posthog-js 1.211.1 → 1.211.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"surveys-preview.js","sources":["../src/posthog-surveys-types.ts","../node_modules/.pnpm/preact@10.19.3/node_modules/preact/dist/preact.module.js","../node_modules/.pnpm/preact@10.19.3/node_modules/preact/hooks/dist/hooks.module.js","../src/utils/globals.ts","../src/types.ts","../src/utils/type-utils.ts","../src/utils/logger.ts","../src/extensions/surveys/surveys-utils.tsx","../src/extensions/surveys/icons.tsx","../src/extensions/surveys/components/PostHogLogo.tsx","../src/extensions/surveys/components/BottomSection.tsx","../src/extensions/surveys/components/QuestionHeader.tsx","../src/extensions/surveys/components/ConfirmationMessage.tsx","../src/extensions/surveys/hooks/useContrastingTextColor.ts","../src/extensions/surveys/components/QuestionTypes.tsx","../src/extensions/surveys.tsx","../src/extensions/surveys-widget.ts","../src/constants.ts","../src/utils/request-utils.ts","../src/utils/index.ts","../src/utils/simple-event-emitter.ts","../src/extensions/surveys/action-matcher.ts","../src/utils/survey-event-receiver.ts","../src/posthog-surveys.ts"],"sourcesContent":["/**\n * Having Survey types in types.ts was confusing tsc\n * and generating an invalid module.d.ts\n * See https://github.com/PostHog/posthog-js/issues/698\n */\n\nexport interface SurveyAppearance {\n // keep in sync with frontend/src/types.ts -> SurveyAppearance\n backgroundColor?: string\n submitButtonColor?: string\n // text color is deprecated, use auto contrast text color instead\n textColor?: string\n // deprecate submit button text eventually\n submitButtonText?: string\n submitButtonTextColor?: string\n descriptionTextColor?: string\n ratingButtonColor?: string\n ratingButtonActiveColor?: string\n ratingButtonHoverColor?: string\n whiteLabel?: boolean\n autoDisappear?: boolean\n displayThankYouMessage?: boolean\n thankYouMessageHeader?: string\n thankYouMessageDescription?: string\n thankYouMessageDescriptionContentType?: SurveyQuestionDescriptionContentType\n thankYouMessageCloseButtonText?: string\n borderColor?: string\n position?: 'left' | 'right' | 'center'\n placeholder?: string\n shuffleQuestions?: boolean\n surveyPopupDelaySeconds?: number\n // widget options\n widgetType?: 'button' | 'tab' | 'selector'\n widgetSelector?: string\n widgetLabel?: string\n widgetColor?: string\n fontFamily?: string\n // questionable: Not in frontend/src/types.ts -> SurveyAppearance, but used in site app\n maxWidth?: string\n zIndex?: string\n}\n\nexport enum SurveyType {\n Popover = 'popover',\n API = 'api',\n Widget = 'widget',\n}\n\nexport type SurveyQuestion = BasicSurveyQuestion | LinkSurveyQuestion | RatingSurveyQuestion | MultipleSurveyQuestion\n\nexport type SurveyQuestionDescriptionContentType = 'html' | 'text'\n\ninterface SurveyQuestionBase {\n question: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n optional?: boolean\n buttonText?: string\n originalQuestionIndex: number\n branching?: NextQuestionBranching | EndBranching | ResponseBasedBranching | SpecificQuestionBranching\n}\n\nexport interface BasicSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Open\n}\n\nexport interface LinkSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Link\n link?: string | null\n}\n\nexport interface RatingSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Rating\n display: 'number' | 'emoji'\n scale: 3 | 5 | 7 | 10\n lowerBoundLabel: string\n upperBoundLabel: string\n}\n\nexport interface MultipleSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.SingleChoice | SurveyQuestionType.MultipleChoice\n choices: string[]\n hasOpenChoice?: boolean\n shuffleOptions?: boolean\n}\n\nexport enum SurveyQuestionType {\n Open = 'open',\n MultipleChoice = 'multiple_choice',\n SingleChoice = 'single_choice',\n Rating = 'rating',\n Link = 'link',\n}\n\nexport enum SurveyQuestionBranchingType {\n NextQuestion = 'next_question',\n End = 'end',\n ResponseBased = 'response_based',\n SpecificQuestion = 'specific_question',\n}\n\ninterface NextQuestionBranching {\n type: SurveyQuestionBranchingType.NextQuestion\n}\n\ninterface EndBranching {\n type: SurveyQuestionBranchingType.End\n}\n\ninterface ResponseBasedBranching {\n type: SurveyQuestionBranchingType.ResponseBased\n responseValues: Record<string, any>\n}\n\ninterface SpecificQuestionBranching {\n type: SurveyQuestionBranchingType.SpecificQuestion\n index: number\n}\n\nexport interface SurveyResponse {\n surveys: Survey[]\n}\n\nexport type SurveyCallback = (surveys: Survey[]) => void\n\nexport type SurveyUrlMatchType = 'regex' | 'not_regex' | 'exact' | 'is_not' | 'icontains' | 'not_icontains'\n\nexport interface SurveyElement {\n text?: string\n $el_text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\nexport interface SurveyRenderReason {\n visible: boolean\n disabledReason?: string\n}\n\nexport interface Survey {\n // Sync this with the backend's SurveyAPISerializer!\n id: string\n name: string\n description: string\n type: SurveyType\n feature_flag_keys:\n | {\n key: string\n value?: string\n }[]\n | null\n linked_flag_key: string | null\n targeting_flag_key: string | null\n internal_targeting_flag_key: string | null\n questions: SurveyQuestion[]\n appearance: SurveyAppearance | null\n conditions: {\n url?: string\n selector?: string\n seenSurveyWaitPeriodInDays?: number\n urlMatchType?: SurveyUrlMatchType\n events: {\n repeatedActivation?: boolean\n values: {\n name: string\n }[]\n } | null\n actions: {\n values: SurveyActionType[]\n } | null\n } | null\n start_date: string | null\n end_date: string | null\n current_iteration: number | null\n current_iteration_start_date: string | null\n}\n\nexport interface SurveyActionType {\n id: number\n name: string | null\n steps?: ActionStepType[]\n}\n\n/** Sync with plugin-server/src/types.ts */\nexport type ActionStepStringMatching = 'contains' | 'exact' | 'regex'\n\nexport interface ActionStepType {\n event?: string | null\n selector?: string | null\n /** @deprecated Only `selector` should be used now. */\n tag_name?: string\n text?: string | null\n /** @default StringMatching.Exact */\n text_matching?: ActionStepStringMatching | null\n href?: string | null\n /** @default ActionStepStringMatching.Exact */\n href_matching?: ActionStepStringMatching | null\n url?: string | null\n /** @default StringMatching.Contains */\n url_matching?: ActionStepStringMatching | null\n}\n","var n,l,u,t,i,o,r,f,e,c={},s=[],a=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,h=Array.isArray;function v(n,l){for(var u in l)n[u]=l[u];return n}function p(n){var l=n.parentNode;l&&l.removeChild(n)}function y(l,u,t){var i,o,r,f={};for(r in u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return d(l,f,i,o,null)}function d(n,t,i,o,r){var f={type:n,props:t,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,constructor:void 0,__v:null==r?++u:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(f),f}function _(){return{current:null}}function g(n){return n.children}function b(n,l){this.props=n,this.context=l}function m(n,l){if(null==l)return n.__?m(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?m(n):null}function k(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k(n)}}function w(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!x.__r++||o!==l.debounceRendering)&&((o=l.debounceRendering)||r)(x)}function x(){var n,u,t,o,r,e,c,s,a;for(i.sort(f);n=i.shift();)n.__d&&(u=i.length,o=void 0,e=(r=(t=n).__v).__e,s=[],a=[],(c=t.__P)&&((o=v({},r)).__v=r.__v+1,l.vnode&&l.vnode(o),L(c,o,r,t.__n,void 0!==c.ownerSVGElement,32&r.__u?[e]:null,s,null==e?m(r):e,!!(32&r.__u),a),o.__.__k[o.__i]=o,M(s,o,a),o.__e!=e&&k(o)),i.length>u&&i.sort(f));x.__r=0}function C(n,l,u,t,i,o,r,f,e,a,h){var v,p,y,d,_,g=t&&t.__k||s,b=l.length;for(u.__d=e,P(u,l,g),e=u.__d,v=0;v<b;v++)null!=(y=u.__k[v])&&\"boolean\"!=typeof y&&\"function\"!=typeof y&&(p=-1===y.__i?c:g[y.__i]||c,y.__i=v,L(n,y,p,i,o,r,f,e,a,h),d=y.__e,y.ref&&p.ref!=y.ref&&(p.ref&&z(p.ref,null,y),h.push(y.ref,y.__c||d,y)),null==_&&null!=d&&(_=d),65536&y.__u||p.__k===y.__k?e=S(y,e,n):\"function\"==typeof y.type&&void 0!==y.__d?e=y.__d:d&&(e=d.nextSibling),y.__d=void 0,y.__u&=-196609);u.__d=e,u.__e=_}function P(n,l,u){var t,i,o,r,f,e=l.length,c=u.length,s=c,a=0;for(n.__k=[],t=0;t<e;t++)null!=(i=n.__k[t]=null==(i=l[t])||\"boolean\"==typeof i||\"function\"==typeof i?null:\"string\"==typeof i||\"number\"==typeof i||\"bigint\"==typeof i||i.constructor==String?d(null,i,null,null,i):h(i)?d(g,{children:i},null,null,null):void 0===i.constructor&&i.__b>0?d(i.type,i.props,i.key,i.ref?i.ref:null,i.__v):i)?(i.__=n,i.__b=n.__b+1,f=H(i,u,r=t+a,s),i.__i=f,o=null,-1!==f&&(s--,(o=u[f])&&(o.__u|=131072)),null==o||null===o.__v?(-1==f&&a--,\"function\"!=typeof i.type&&(i.__u|=65536)):f!==r&&(f===r+1?a++:f>r?s>e-r?a+=f-r:a--:a=f<r&&f==r-1?f-r:0,f!==t+a&&(i.__u|=65536))):(o=u[t])&&null==o.key&&o.__e&&(o.__e==n.__d&&(n.__d=m(o)),N(o,o,!1),u[t]=null,s--);if(s)for(t=0;t<c;t++)null!=(o=u[t])&&0==(131072&o.__u)&&(o.__e==n.__d&&(n.__d=m(o)),N(o,o))}function S(n,l,u){var t,i;if(\"function\"==typeof n.type){for(t=n.__k,i=0;t&&i<t.length;i++)t[i]&&(t[i].__=n,l=S(t[i],l,u));return l}return n.__e!=l&&(u.insertBefore(n.__e,l||null),l=n.__e),l&&l.nextSibling}function $(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(h(n)?n.some(function(n){$(n,l)}):l.push(n)),l}function H(n,l,u,t){var i=n.key,o=n.type,r=u-1,f=u+1,e=l[u];if(null===e||e&&i==e.key&&o===e.type)return u;if(t>(null!=e&&0==(131072&e.__u)?1:0))for(;r>=0||f<l.length;){if(r>=0){if((e=l[r])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return r;r--}if(f<l.length){if((e=l[f])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return f;f++}}return-1}function I(n,l,u){\"-\"===l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||a.test(l)?u:u+\"px\"}function T(n,l,u,t,i){var o;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof t&&(n.style.cssText=t=\"\"),t)for(l in t)u&&l in u||I(n.style,l,\"\");if(u)for(l in u)t&&u[l]===t[l]||I(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])o=l!==(l=l.replace(/(PointerCapture)$|Capture$/,\"$1\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?t?u.u=t.u:(u.u=Date.now(),n.addEventListener(l,o?D:A,o)):n.removeEventListener(l,o?D:A,o);else{if(i)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!==l&&\"height\"!==l&&\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&\"rowSpan\"!==l&&\"colSpan\"!==l&&\"role\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&\"-\"!==l[4]?n.removeAttribute(l):n.setAttribute(l,u))}}function A(n){var u=this.l[n.type+!1];if(n.t){if(n.t<=u.u)return}else n.t=Date.now();return u(l.event?l.event(n):n)}function D(n){return this.l[n.type+!0](l.event?l.event(n):n)}function L(n,u,t,i,o,r,f,e,c,s){var a,p,y,d,_,m,k,w,x,P,S,$,H,I,T,A=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),r=[e=u.__e=t.__e]),(a=l.__b)&&a(u);n:if(\"function\"==typeof A)try{if(w=u.props,x=(a=A.contextType)&&i[a.__c],P=a?x?x.props.value:a.__:i,t.__c?k=(p=u.__c=t.__c).__=p.__E:(\"prototype\"in A&&A.prototype.render?u.__c=p=new A(w,P):(u.__c=p=new b(w,P),p.constructor=A,p.render=O),x&&x.sub(p),p.props=w,p.state||(p.state={}),p.context=P,p.__n=i,y=p.__d=!0,p.__h=[],p._sb=[]),null==p.__s&&(p.__s=p.state),null!=A.getDerivedStateFromProps&&(p.__s==p.state&&(p.__s=v({},p.__s)),v(p.__s,A.getDerivedStateFromProps(w,p.__s))),d=p.props,_=p.state,p.__v=u,y)null==A.getDerivedStateFromProps&&null!=p.componentWillMount&&p.componentWillMount(),null!=p.componentDidMount&&p.__h.push(p.componentDidMount);else{if(null==A.getDerivedStateFromProps&&w!==d&&null!=p.componentWillReceiveProps&&p.componentWillReceiveProps(w,P),!p.__e&&(null!=p.shouldComponentUpdate&&!1===p.shouldComponentUpdate(w,p.__s,P)||u.__v===t.__v)){for(u.__v!==t.__v&&(p.props=w,p.state=p.__s,p.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.forEach(function(n){n&&(n.__=u)}),S=0;S<p._sb.length;S++)p.__h.push(p._sb[S]);p._sb=[],p.__h.length&&f.push(p);break n}null!=p.componentWillUpdate&&p.componentWillUpdate(w,p.__s,P),null!=p.componentDidUpdate&&p.__h.push(function(){p.componentDidUpdate(d,_,m)})}if(p.context=P,p.props=w,p.__P=n,p.__e=!1,$=l.__r,H=0,\"prototype\"in A&&A.prototype.render){for(p.state=p.__s,p.__d=!1,$&&$(u),a=p.render(p.props,p.state,p.context),I=0;I<p._sb.length;I++)p.__h.push(p._sb[I]);p._sb=[]}else do{p.__d=!1,$&&$(u),a=p.render(p.props,p.state,p.context),p.state=p.__s}while(p.__d&&++H<25);p.state=p.__s,null!=p.getChildContext&&(i=v(v({},i),p.getChildContext())),y||null==p.getSnapshotBeforeUpdate||(m=p.getSnapshotBeforeUpdate(d,_)),C(n,h(T=null!=a&&a.type===g&&null==a.key?a.props.children:a)?T:[T],u,t,i,o,r,f,e,c,s),p.base=u.__e,u.__u&=-161,p.__h.length&&f.push(p),k&&(p.__E=p.__=null)}catch(n){u.__v=null,c||null!=r?(u.__e=e,u.__u|=c?160:32,r[r.indexOf(e)]=null):(u.__e=t.__e,u.__k=t.__k),l.__e(n,u,t)}else null==r&&u.__v===t.__v?(u.__k=t.__k,u.__e=t.__e):u.__e=j(t.__e,u,t,i,o,r,f,c,s);(a=l.diffed)&&a(u)}function M(n,u,t){u.__d=void 0;for(var i=0;i<t.length;i++)z(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function j(l,u,t,i,o,r,f,e,s){var a,v,y,d,_,g,b,k=t.props,w=u.props,x=u.type;if(\"svg\"===x&&(o=!0),null!=r)for(a=0;a<r.length;a++)if((_=r[a])&&\"setAttribute\"in _==!!x&&(x?_.localName===x:3===_.nodeType)){l=_,r[a]=null;break}if(null==l){if(null===x)return document.createTextNode(w);l=o?document.createElementNS(\"http://www.w3.org/2000/svg\",x):document.createElement(x,w.is&&w),r=null,e=!1}if(null===x)k===w||e&&l.data===w||(l.data=w);else{if(r=r&&n.call(l.childNodes),k=t.props||c,!e&&null!=r)for(k={},a=0;a<l.attributes.length;a++)k[(_=l.attributes[a]).name]=_.value;for(a in k)_=k[a],\"children\"==a||(\"dangerouslySetInnerHTML\"==a?y=_:\"key\"===a||a in w||T(l,a,null,_,o));for(a in w)_=w[a],\"children\"==a?d=_:\"dangerouslySetInnerHTML\"==a?v=_:\"value\"==a?g=_:\"checked\"==a?b=_:\"key\"===a||e&&\"function\"!=typeof _||k[a]===_||T(l,a,_,k[a],o);if(v)e||y&&(v.__html===y.__html||v.__html===l.innerHTML)||(l.innerHTML=v.__html),u.__k=[];else if(y&&(l.innerHTML=\"\"),C(l,h(d)?d:[d],u,t,i,o&&\"foreignObject\"!==x,r,f,r?r[0]:t.__k&&m(t,0),e,s),null!=r)for(a=r.length;a--;)null!=r[a]&&p(r[a]);e||(a=\"value\",void 0!==g&&(g!==l[a]||\"progress\"===x&&!g||\"option\"===x&&g!==k[a])&&T(l,a,g,k[a],!1),a=\"checked\",void 0!==b&&b!==l[a]&&T(l,a,b,k[a],!1))}return l}function z(n,u,t){try{\"function\"==typeof n?n(u):n.current=u}catch(n){l.__e(n,t)}}function N(n,u,t){var i,o;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!==n.__e||z(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null,n.__c=void 0}if(i=n.__k)for(o=0;o<i.length;o++)i[o]&&N(i[o],u,t||\"function\"!=typeof n.type);t||null==n.__e||p(n.__e),n.__=n.__e=n.__d=void 0}function O(n,l,u){return this.constructor(n,u)}function q(u,t,i){var o,r,f,e;l.__&&l.__(u,t),r=(o=\"function\"==typeof i)?null:i&&i.__k||t.__k,f=[],e=[],L(t,u=(!o&&i||t).__k=y(g,null,[u]),r||c,c,void 0!==t.ownerSVGElement,!o&&i?[i]:r?null:t.firstChild?n.call(t.childNodes):null,f,!o&&i?i:r?r.__e:t.firstChild,o,e),M(f,u,e)}function B(n,l){q(n,l,B)}function E(l,u,t){var i,o,r,f,e=v({},l.props);for(r in l.type&&l.type.defaultProps&&(f=l.type.defaultProps),u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:e[r]=void 0===u[r]&&void 0!==f?f[r]:u[r];return arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),d(l.type,e,i||l.key,o||l.ref,null)}function F(n,l){var u={__c:l=\"__cC\"+e++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,t;return this.getChildContext||(u=[],(t={})[l]=this,this.getChildContext=function(){return t},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(function(n){n.__e=!0,w(n)})},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=s.slice,l={__e:function(n,l,u,t){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&null==n.constructor},b.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=v({},this.state),\"function\"==typeof n&&(n=n(v({},u),this.props)),n&&v(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),w(this))},b.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),w(this))},b.prototype.render=g,i=[],r=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,f=function(n,l){return n.__v.__b-l.__v.__b},x.__r=0,e=0;export{b as Component,g as Fragment,E as cloneElement,F as createContext,y as createElement,_ as createRef,y as h,B as hydrate,t as isValidElement,l as options,q as render,$ as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","import{options as n}from\"preact\";var t,r,u,i,o=0,f=[],c=[],e=n.__b,a=n.__r,v=n.diffed,l=n.__c,m=n.unmount;function d(t,u){n.__h&&n.__h(r,t,o||u),o=0;var i=r.__H||(r.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({__V:c}),i.__[t]}function h(n){return o=1,s(B,n)}function s(n,u,i){var o=d(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):B(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=!1;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),!(!i&&o.__c.props===n)&&(!c||c.call(this,n,t,r))};r.u=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function p(u,i){var o=d(t++,3);!n.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__H.__h.push(o))}function y(u,i){var o=d(t++,4);!n.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__h.push(o))}function _(n){return o=5,F(function(){return{current:n}},[])}function A(n,t,r){o=6,y(function(){return\"function\"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function F(n,r){var u=d(t++,7);return z(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function T(n,t){return o=8,F(function(){return n},t)}function q(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function x(t,r){n.useDebugValue&&n.useDebugValue(r?r(t):t)}function P(n){var u=d(t++,10),i=h();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function V(){var n=d(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function b(){for(var t;t=f.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(k),t.__H.__h.forEach(w),t.__H.__h=[]}catch(r){t.__H.__h=[],n.__e(r,t.__v)}}n.__b=function(n){r=null,e&&e(n)},n.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=c,n.__N=n.i=void 0})):(i.__h.forEach(k),i.__h.forEach(w),i.__h=[],t=0)),u=r},n.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==f.push(o)&&i===n.requestAnimationFrame||((i=n.requestAnimationFrame)||j)(b)),o.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==c&&(n.__=n.__V),n.i=void 0,n.__V=c})),u=r=null},n.__c=function(t,r){r.some(function(t){try{t.__h.forEach(k),t.__h=t.__h.filter(function(n){return!n.__||w(n)})}catch(u){r.some(function(n){n.__h&&(n.__h=[])}),r=[],n.__e(u,t.__v)}}),l&&l(t,r)},n.unmount=function(t){m&&m(t);var r,u=t.__c;u&&u.__H&&(u.__H.__.forEach(function(n){try{k(n)}catch(n){r=n}}),u.__H=void 0,r&&n.__e(r,u.__v))};var g=\"function\"==typeof requestAnimationFrame;function j(n){var t,r=function(){clearTimeout(u),g&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);g&&(t=requestAnimationFrame(r))}function k(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function w(n){var t=r;n.__c=n.__(),r=t}function z(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function B(n,t){return\"function\"==typeof t?t(n):t}export{T as useCallback,q as useContext,x as useDebugValue,p as useEffect,P as useErrorBoundary,V as useId,A as useImperativeHandle,y as useLayoutEffect,F as useMemo,s as useReducer,_ as useRef,h as useState};\n//# sourceMappingURL=hooks.module.js.map\n","import { ErrorProperties } from '../extensions/exception-autocapture/error-conversion'\nimport type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ErrorEventArgs,\n ErrorMetadata,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n} from '../types'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis &\n Record<string, any> & {\n __PosthogExtensions__?: PostHogExtensions\n\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n }\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n parseErrorAsProperties?: (\n [event, source, lineno, colno, error]: ErrorEventArgs,\n metadata?: ErrorMetadata\n ) => ErrorProperties\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: Properties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: Properties) => void) => () => void\n }\n rrweb?: { record: any; version: string }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n canActivateRepeatedly?: (survey: any) => boolean\n generateSurveys?: (posthog: PostHog) => any | undefined\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n tracingHeadersPatchFns?: {\n _patchFetch: (sessionManager?: SessionIdManager) => () => void\n _patchXHR: (sessionManager?: SessionIdManager) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\nexport const ArrayProto = Array.prototype\nexport const nativeForEach = ArrayProto.forEach\nexport const nativeIndexOf = ArrayProto.indexOf\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import { PostHog } from './posthog-core'\nimport type { SegmentAnalytics } from './extensions/segment-integration'\nimport { recordOptions } from './extensions/replay/sessionrecording-utils'\n\nexport type Property = any\nexport type Properties = Record<string, Property>\n\nexport const COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'\n\nexport const knownUnsafeEditableEvent = [\n '$snapshot',\n '$pageview',\n '$pageleave',\n '$set',\n 'survey dismissed',\n 'survey sent',\n 'survey shown',\n '$identify',\n '$groupidentify',\n '$create_alias',\n '$$client_ingestion_warning',\n '$web_experiment_applied',\n '$feature_enrollment_update',\n '$feature_flag_called',\n] as const\n\n/**\n * These events can be processed by the `beforeCapture` function\n * but can cause unexpected confusion in data.\n *\n * Some features of PostHog rely on receiving 100% of these events\n */\nexport type KnownUnsafeEditableEvent = (typeof knownUnsafeEditableEvent)[number]\n\n/**\n * These are known events PostHog events that can be processed by the `beforeCapture` function\n * That means PostHog functionality does not rely on receiving 100% of these for calculations\n * So, it is safe to sample them to reduce the volume of events sent to PostHog\n */\nexport type KnownEventName =\n | '$heatmaps_data'\n | '$opt_in'\n | '$exception'\n | '$$heatmap'\n | '$web_vitals'\n | '$dead_click'\n | '$autocapture'\n | typeof COPY_AUTOCAPTURE_EVENT\n | '$rageclick'\n\nexport type EventName =\n | KnownUnsafeEditableEvent\n | KnownEventName\n // magic value so that the type of EventName is a set of known strings or any other string\n // which means you get autocomplete for known strings\n // but no type complaints when you add an arbitrary string\n | (string & {})\n\nexport interface CaptureResult {\n uuid: string\n event: EventName\n properties: Properties\n $set?: Properties\n $set_once?: Properties\n timestamp?: Date\n}\n\nexport type AutocaptureCompatibleElement = 'a' | 'button' | 'form' | 'input' | 'select' | 'textarea' | 'label'\nexport type DomAutocaptureEvents = 'click' | 'change' | 'submit'\n\n/**\n * If an array is passed for an allowlist, autocapture events will only be sent for elements matching\n * at least one of the elements in the array. Multiple allowlists can be used\n */\nexport interface AutocaptureConfig {\n /**\n * List of URLs to allow autocapture on, can be strings to match\n * or regexes e.g. ['https://example.com', 'test.com/.*']\n * this is useful when you want to autocapture on specific pages only\n *\n * if you set both url_allowlist and url_ignorelist,\n * we check the allowlist first and then the ignorelist.\n * the ignorelist can override the allowlist\n */\n url_allowlist?: (string | RegExp)[]\n\n /**\n * List of URLs to not allow autocapture on, can be strings to match\n * or regexes e.g. ['https://example.com', 'test.com/.*']\n * this is useful when you want to autocapture on most pages but not some specific ones\n *\n * if you set both url_allowlist and url_ignorelist,\n * we check the allowlist first and then the ignorelist.\n * the ignorelist can override the allowlist\n */\n url_ignorelist?: (string | RegExp)[]\n\n /**\n * List of DOM events to allow autocapture on e.g. ['click', 'change', 'submit']\n */\n dom_event_allowlist?: DomAutocaptureEvents[]\n\n /**\n * List of DOM elements to allow autocapture on\n * e.g. ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']\n * we consider the tree of elements from the root to the target element of the click event\n * so for the tree div > div > button > svg\n * if the allowlist has button then we allow the capture when the button or the svg is the click target\n * but not if either of the divs are detected as the click target\n */\n element_allowlist?: AutocaptureCompatibleElement[]\n\n /**\n * List of CSS selectors to allow autocapture on\n * e.g. ['[ph-capture]']\n * we consider the tree of elements from the root to the target element of the click event\n * so for the tree div > div > button > svg\n * and allow list config `['[id]']`\n * we will capture the click if the click-target or its parents has any id\n */\n css_selector_allowlist?: string[]\n\n /**\n * Exclude certain element attributes from autocapture\n * E.g. ['aria-label'] or [data-attr-pii]\n */\n element_attribute_ignorelist?: string[]\n\n capture_copied_text?: boolean\n}\n\nexport interface BootstrapConfig {\n distinctID?: string\n isIdentifiedID?: boolean\n featureFlags?: Record<string, boolean | string>\n featureFlagPayloads?: Record<string, JsonType>\n /**\n * Optionally provide a sessionID, this is so that you can provide an existing sessionID here to continue a user's session across a domain or device. It MUST be:\n * - unique to this user\n * - a valid UUID v7\n * - the timestamp part must be <= the timestamp of the first event in the session\n * - the timestamp of the last event in the session must be < the timestamp part + 24 hours\n * **/\n sessionID?: string\n}\n\nexport type SupportedWebVitalsMetrics = 'LCP' | 'CLS' | 'FCP' | 'INP'\n\nexport interface PerformanceCaptureConfig {\n /** works with session replay to use the browser's native performance observer to capture performance metrics */\n network_timing?: boolean\n /** use chrome's web vitals library to wrap fetch and capture web vitals */\n web_vitals?: boolean\n /**\n * We observe very large values reported by the Chrome web vitals library\n * These outliers are likely not real, useful values, and we exclude them\n * You can set this to 0 in order to include all values, NB this is not recommended\n * if not set this defaults to 15 minutes\n */\n __web_vitals_max_value?: number\n /**\n * By default all 4 metrics are captured\n * You can set this config to restrict which metrics are captured\n * e.g. ['CLS', 'FCP'] to only capture those two metrics\n * NB setting this does not override whether the capture is enabled\n */\n web_vitals_allowed_metrics?: SupportedWebVitalsMetrics[]\n /**\n * we delay flushing web vitals metrics to reduce the number of events we send\n * this is the maximum time we will wait before sending the metrics\n * if not set it defaults to 5 seconds\n */\n web_vitals_delayed_flush_ms?: number\n}\n\nexport interface DeadClickCandidate {\n node: Element\n originalEvent: MouseEvent\n timestamp: number\n // time between click and the most recent scroll\n scrollDelayMs?: number\n // time between click and the most recent mutation\n mutationDelayMs?: number\n // time between click and the most recent selection changed event\n selectionChangedDelayMs?: number\n // if neither scroll nor mutation seen before threshold passed\n absoluteDelayMs?: number\n}\n\nexport type DeadClicksAutoCaptureConfig = {\n // by default if a click is followed by a sroll within 100ms it is not a dead click\n scroll_threshold_ms?: number\n // by default if a click is followed by a selection change within 100ms it is not a dead click\n selection_change_threshold_ms?: number\n // by default if a click is followed by a mutation within 2500ms it is not a dead click\n mutation_threshold_ms?: number\n /**\n * Allows setting behavior for when a dead click is captured.\n * For e.g. to support capture to heatmaps\n *\n * If not provided the default behavior is to auto-capture dead click events\n *\n * Only intended to be provided by the SDK\n */\n __onCapture?: ((click: DeadClickCandidate, properties: Properties) => void) | undefined\n} & Pick<AutocaptureConfig, 'element_attribute_ignorelist'>\n\nexport interface HeatmapConfig {\n /*\n * how often to send batched data in $$heatmap_data events\n * if set to 0 or not set, sends using the default interval of 1 second\n * */\n flush_interval_milliseconds: number\n}\n\nexport type BeforeSendFn = (cr: CaptureResult | null) => CaptureResult | null\n\nexport interface PostHogConfig {\n api_host: string\n /** @deprecated - This property is no longer supported */\n api_method?: string\n api_transport?: 'XHR' | 'fetch'\n ui_host: string | null\n token: string\n autocapture: boolean | AutocaptureConfig\n rageclick: boolean\n cross_subdomain_cookie: boolean\n persistence: 'localStorage' | 'cookie' | 'memory' | 'localStorage+cookie' | 'sessionStorage'\n persistence_name: string\n /** @deprecated - Use 'persistence_name' instead */\n cookie_name?: string\n loaded: (posthog_instance: PostHog) => void\n\n /** @deprecated - Use `save_campaign_params` instead */\n store_google?: boolean\n save_campaign_params: boolean\n\n custom_campaign_params: string[]\n // a list of strings to be tested against navigator.userAgent to determine if the source is a bot\n // this is **added to** the default list of bots that we check\n // defaults to the empty array\n custom_blocked_useragents: string[]\n save_referrer: boolean\n capture_pageview: boolean\n capture_pageleave: boolean | 'if_capture_pageview'\n\n /** @deprecated Use `debug` instead */\n verbose?: boolean\n debug: boolean\n\n cookie_expiration: number\n upgrade: boolean\n disable_session_recording: boolean\n disable_persistence: boolean\n /** @deprecated - use `disable_persistence` instead */\n disable_cookie?: boolean\n disable_surveys: boolean\n disable_web_experiments: boolean\n /** If set, posthog-js will never load external scripts such as those needed for Session Replay or Surveys. */\n disable_external_dependency_loading?: boolean\n prepare_external_dependency_script?: (script: HTMLScriptElement) => HTMLScriptElement | null\n enable_recording_console_log?: boolean\n secure_cookie: boolean\n ip: boolean\n /** Starts the SDK in an opted out state requiring opt_in_capturing() to be called before events will b captured */\n opt_out_capturing_by_default: boolean\n opt_out_capturing_persistence_type: 'localStorage' | 'cookie'\n /** If set to true this will disable persistence if the user is opted out of capturing. @default false */\n opt_out_persistence_by_default?: boolean\n /** Opt out of user agent filtering such as googlebot or other bots. Defaults to `false` */\n opt_out_useragent_filter: boolean\n\n opt_out_capturing_cookie_prefix: string | null\n opt_in_site_apps: boolean\n respect_dnt: boolean\n /** @deprecated - use `property_denylist` instead */\n property_blacklist?: string[]\n property_denylist: string[]\n request_headers: { [header_name: string]: string }\n on_request_error?: (error: RequestResponse) => void\n /** @deprecated - use `request_headers` instead */\n xhr_headers?: { [header_name: string]: string }\n /** @deprecated - use `on_request_error` instead */\n on_xhr_error?: (failedRequest: XMLHttpRequest) => void\n request_batching: boolean\n properties_string_max_length: number\n session_recording: SessionRecordingOptions\n session_idle_timeout_seconds: number\n mask_all_element_attributes: boolean\n mask_all_text: boolean\n mask_personal_data_properties: boolean\n custom_personal_data_properties: string[]\n advanced_disable_decide: boolean\n advanced_disable_feature_flags: boolean\n advanced_disable_feature_flags_on_first_load: boolean\n advanced_disable_toolbar_metrics: boolean\n feature_flag_request_timeout_ms: number\n get_device_id: (uuid: string) => string\n name: string\n\n /**\n * This function is called when collecting properties for an event.\n * It allows you to edit data before it is sent\n * @deprecated - use `before_send` instead\n */\n sanitize_properties: ((properties: Properties, event_name: string) => Properties) | null\n /**\n * this is a read-only function that can be used to react to event capture\n * @deprecated - use `before_send` instead - NB before_send is not read only\n */\n _onCapture: (eventName: string, eventData: CaptureResult) => void\n /**\n * This function or array of functions - if provided - are called immediately before sending data to the server.\n * It allows you to edit data before it is sent, or choose not to send it all.\n * if provided as an array the functions are called in the order they are provided\n * any one function returning null means the event will not be sent\n */\n before_send?: BeforeSendFn | BeforeSendFn[]\n capture_performance?: boolean | PerformanceCaptureConfig\n // Should only be used for testing. Could negatively impact performance.\n disable_compression: boolean\n bootstrap: BootstrapConfig\n segment?: SegmentAnalytics\n /* @deprecated - use `capture_heatmaps` instead */\n enable_heatmaps?: boolean\n capture_heatmaps?: boolean | HeatmapConfig\n capture_dead_clicks?: boolean | DeadClicksAutoCaptureConfig\n disable_scroll_properties?: boolean\n // Let the pageview scroll stats use a custom css selector for the root element, e.g. `main`\n scroll_root_selector?: string | string[]\n\n /** You can control whether events from PostHog-js have person processing enabled with the `person_profiles` config setting. There are three options:\n * - `person_profiles: 'always'` _(default)_ - we will process persons data for all events\n * - `person_profiles: 'never'` - we won't process persons for any event. This means that anonymous users will not be merged once they sign up or login, so you lose the ability to create funnels that track users from anonymous to identified. All events (including `$identify`) will be sent with `$process_person_profile: False`.\n * - `person_profiles: 'identified_only'` - we will only process persons when you call `posthog.identify`, `posthog.alias`, `posthog.setPersonProperties`, `posthog.group`, `posthog.setPersonPropertiesForFlags` or `posthog.setGroupPropertiesForFlags` Anonymous users won't get person profiles.\n */\n person_profiles?: 'always' | 'never' | 'identified_only'\n /** @deprecated - use `person_profiles` instead */\n process_person?: 'always' | 'never' | 'identified_only'\n\n /** Client side rate limiting */\n rate_limiting?: {\n /** The average number of events per second that should be permitted (defaults to 10) */\n events_per_second?: number\n /** How many events can be captured in a burst. This defaults to 10 times the events_per_second count */\n events_burst_limit?: number\n }\n\n /** Used when sending data via `fetch`, use with care, this is intentionally meant to be used with NextJS `fetch`\n * Incorrect usage may cause out-of-date data for feature flags, actions tracking, etc.\n * See https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options\n */\n fetch_options?: {\n cache?: RequestInit['cache']\n next_options?: NextOptions\n }\n\n /**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * whether to wrap fetch and add tracing headers to the request\n * */\n __add_tracing_headers?: boolean\n\n /**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * enables the new RemoteConfig approach to loading config instead of decide\n * */\n __preview_remote_config?: boolean\n\n /**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * whether to send a sentinel value for distinct id, device id, and session id, which will be replaced server-side by a cookieless hash\n * */\n __preview_experimental_cookieless_mode?: boolean\n\n // ------- RETIRED CONFIGS -------\n\n /** @deprecated - NOT USED ANYMORE, kept here for backwards compatibility reasons */\n inapp_protocol?: string\n\n /** @deprecated - NOT USED ANYMORE, kept here for backwards compatibility reasons */\n inapp_link_new_window?: boolean\n}\n\nexport interface OptInOutCapturingOptions {\n capture: (event: string, properties: Properties, options: CaptureOptions) => void\n capture_event_name: string\n capture_properties: Properties\n enable_persistence: boolean\n clear_persistence: boolean\n persistence_type: 'cookie' | 'localStorage' | 'localStorage+cookie'\n cookie_prefix: string\n cookie_expiration: number\n cross_subdomain_cookie: boolean\n secure_cookie: boolean\n}\n\nexport interface SessionRecordingOptions {\n blockClass?: string | RegExp\n blockSelector?: string | null\n ignoreClass?: string\n maskTextClass?: string | RegExp\n maskTextSelector?: string | null\n maskTextFn?: ((text: string, element: HTMLElement | null) => string) | null\n maskAllInputs?: boolean\n maskInputOptions?: recordOptions['maskInputOptions']\n maskInputFn?: ((text: string, element?: HTMLElement) => string) | null\n slimDOMOptions?: recordOptions['slimDOMOptions']\n collectFonts?: boolean\n inlineStylesheet?: boolean\n recordCrossOriginIframes?: boolean\n /**\n * Allows local config to override remote canvas recording settings from the decide response\n */\n captureCanvas?: SessionRecordingCanvasOptions\n /** @deprecated - use maskCapturedNetworkRequestFn instead */\n maskNetworkRequestFn?: ((data: NetworkRequest) => NetworkRequest | null | undefined) | null\n /** Modify the network request before it is captured. Returning null or undefined stops it being captured */\n maskCapturedNetworkRequestFn?: ((data: CapturedNetworkRequest) => CapturedNetworkRequest | null | undefined) | null\n // our settings here only support a subset of those proposed for rrweb's network capture plugin\n recordHeaders?: boolean\n recordBody?: boolean\n // ADVANCED: while a user is active we take a full snapshot of the browser every interval. For very few sites playback performance might be better with different interval. Set to 0 to disable\n full_snapshot_interval_millis?: number\n /*\n ADVANCED: whether to partially compress rrweb events before sending them to the server,\n defaults to true, can be set to false to disable partial compression\n NB requests are still compressed when sent to the server regardless of this setting\n */\n compress_events?: boolean\n /*\n ADVANCED: alters the threshold before a recording considers a user has become idle.\n Normally only altered alongside changes to session_idle_timeout_ms.\n Default is 5 minutes.\n */\n session_idle_threshold_ms?: number\n /*\n ADVANCED: alters the refill rate for the token bucket mutation throttling\n Normally only altered alongside posthog support guidance.\n Accepts values between 0 and 100\n Default is 10.\n */\n __mutationRateLimiterRefillRate?: number\n /*\n ADVANCED: alters the bucket size for the token bucket mutation throttling\n Normally only altered alongside posthog support guidance.\n Accepts values between 0 and 100\n Default is 100.\n */\n __mutationRateLimiterBucketSize?: number\n}\n\nexport type SessionIdChangedCallback = (\n sessionId: string,\n windowId: string | null | undefined,\n changeReason?: { noSessionId: boolean; activityTimeout: boolean; sessionPastMaximumLength: boolean }\n) => void\n\nexport enum Compression {\n GZipJS = 'gzip-js',\n Base64 = 'base64',\n}\n\n// Request types - these should be kept minimal to what request.ts needs\n\n// Minimal class to allow interop between different request methods (xhr / fetch)\nexport interface RequestResponse {\n statusCode: number\n text?: string\n json?: any\n}\n\nexport type RequestCallback = (response: RequestResponse) => void\n\n// See https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options\ntype NextOptions = { revalidate: false | 0 | number; tags: string[] }\n\nexport interface RequestOptions {\n url: string\n // Data can be a single object or an array of objects when batched\n data?: Record<string, any> | Record<string, any>[]\n headers?: Record<string, any>\n transport?: 'XHR' | 'fetch' | 'sendBeacon'\n method?: 'POST' | 'GET'\n urlQueryArgs?: { compression: Compression }\n callback?: RequestCallback\n timeout?: number\n noRetries?: boolean\n compression?: Compression | 'best-available'\n fetchOptions?: {\n cache?: RequestInit['cache']\n next?: NextOptions\n }\n}\n\n// Queued request types - the same as a request but with additional queueing information\n\nexport interface QueuedRequestOptions extends RequestOptions {\n batchKey?: string /** key of queue, e.g. 'sessionRecording' vs 'event' */\n}\n\n// Used explicitly for retriable requests\nexport interface RetriableRequestOptions extends QueuedRequestOptions {\n retriesPerformedSoFar?: number\n}\n\nexport interface CaptureOptions {\n $set?: Properties /** used with $identify */\n $set_once?: Properties /** used with $identify */\n _url?: string /** Used to override the desired endpoint for the captured event */\n _batchKey?: string /** key of queue, e.g. 'sessionRecording' vs 'event' */\n _noTruncate?: boolean /** if set, overrides and disables config.properties_string_max_length */\n send_instantly?: boolean /** if set skips the batched queue */\n skip_client_rate_limiting?: boolean /** if set skips the client side rate limiting */\n transport?: RequestOptions['transport'] /** if set, overrides the desired transport method */\n timestamp?: Date\n}\n\nexport type FlagVariant = { flag: string; variant: string }\n\nexport type SessionRecordingCanvasOptions = {\n recordCanvas?: boolean | null\n canvasFps?: number | null\n // the API returns a decimal between 0 and 1 as a string\n canvasQuality?: string | null\n}\n\nexport interface RemoteConfig {\n supportedCompression: Compression[]\n autocapture_opt_out?: boolean\n /**\n * originally capturePerformance was replay only and so boolean true\n * is equivalent to { network_timing: true }\n * now capture performance can be separately enabled within replay\n * and as a standalone web vitals tracker\n * people can have them enabled separately\n * they work standalone but enhance each other\n * TODO: deprecate this so we make a new config that doesn't need this explanation\n */\n capturePerformance?: boolean | PerformanceCaptureConfig\n analytics?: {\n endpoint?: string\n }\n elementsChainAsString?: boolean\n // this is currently in development and may have breaking changes without a major version bump\n autocaptureExceptions?: boolean | { endpoint?: string }\n sessionRecording?: SessionRecordingCanvasOptions & {\n endpoint?: string\n consoleLogRecordingEnabled?: boolean\n // the API returns a decimal between 0 and 1 as a string\n sampleRate?: string | null\n minimumDurationMilliseconds?: number\n linkedFlag?: string | FlagVariant | null\n networkPayloadCapture?: Pick<NetworkRecordOptions, 'recordBody' | 'recordHeaders'>\n urlTriggers?: SessionRecordingUrlTrigger[]\n scriptConfig?: { script?: string | undefined }\n urlBlocklist?: SessionRecordingUrlTrigger[]\n eventTriggers?: string[]\n }\n surveys?: boolean\n toolbarParams: ToolbarParams\n editorParams?: ToolbarParams /** @deprecated, renamed to toolbarParams, still present on older API responses */\n toolbarVersion: 'toolbar' /** @deprecated, moved to toolbarParams */\n isAuthenticated: boolean\n siteApps: { id: string; url: string }[]\n heatmaps?: boolean\n defaultIdentifiedOnly?: boolean\n captureDeadClicks?: boolean\n hasFeatureFlags?: boolean // Indicates if the team has any flags enabled (if not we don't need to load them)\n}\n\nexport interface DecideResponse extends RemoteConfig {\n featureFlags: Record<string, string | boolean>\n featureFlagPayloads: Record<string, JsonType>\n errorsWhileComputingFlags: boolean\n}\n\nexport type SiteAppGlobals = {\n event: {\n uuid: string\n event: EventName\n properties: Properties\n timestamp?: Date\n elements_chain?: string\n distinct_id?: string\n }\n person: {\n properties: Properties\n }\n groups: Record<string, { id: string; type: string; properties: Properties }>\n}\n\nexport type SiteAppLoader = {\n id: string\n init: (config: { posthog: PostHog; callback: (success: boolean) => void }) => {\n processEvent?: (globals: SiteAppGlobals) => void\n }\n}\n\nexport type SiteApp = {\n id: string\n loaded: boolean\n errored: boolean\n processEvent?: (globals: SiteAppGlobals) => void\n}\n\nexport type FeatureFlagsCallback = (\n flags: string[],\n variants: Record<string, string | boolean>,\n context?: {\n errorsLoading?: boolean\n }\n) => void\n\nexport interface PersistentStore {\n is_supported: () => boolean\n error: (error: any) => void\n parse: (name: string) => any\n get: (name: string) => any\n set: (\n name: string,\n value: any,\n expire_days?: number | null,\n cross_subdomain?: boolean,\n secure?: boolean,\n debug?: boolean\n ) => void\n remove: (name: string, cross_subdomain?: boolean) => void\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Breaker = {}\nexport type EventHandler = (event: Event) => boolean | void\n\nexport type ToolbarUserIntent = 'add-action' | 'edit-action'\nexport type ToolbarSource = 'url' | 'localstorage'\nexport type ToolbarVersion = 'toolbar'\n\n/* sync with posthog */\nexport interface ToolbarParams {\n token?: string /** public posthog-js token */\n temporaryToken?: string /** private temporary user token */\n actionId?: number\n userIntent?: ToolbarUserIntent\n source?: ToolbarSource\n toolbarVersion?: ToolbarVersion\n instrument?: boolean\n distinctId?: string\n userEmail?: string\n dataAttributes?: string[]\n featureFlags?: Record<string, string | boolean>\n}\n\nexport type SnippetArrayItem = [method: string, ...args: any[]]\n\nexport type JsonRecord = { [key: string]: JsonType }\nexport type JsonType = string | number | boolean | null | JsonRecord | Array<JsonType>\n\n/** A feature that isn't publicly available yet.*/\nexport interface EarlyAccessFeature {\n // Sync this with the backend's EarlyAccessFeatureSerializer!\n name: string\n description: string\n stage: 'concept' | 'alpha' | 'beta'\n documentationUrl: string | null\n flagKey: string | null\n}\n\nexport type EarlyAccessFeatureCallback = (earlyAccessFeatures: EarlyAccessFeature[]) => void\n\nexport interface EarlyAccessFeatureResponse {\n earlyAccessFeatures: EarlyAccessFeature[]\n}\n\nexport type Headers = Record<string, string>\n\n/* for rrweb/network@1\n ** when that is released as part of rrweb this can be removed\n ** don't rely on this type, it may change without notice\n */\nexport type InitiatorType =\n | 'audio'\n | 'beacon'\n | 'body'\n | 'css'\n | 'early-hint'\n | 'embed'\n | 'fetch'\n | 'frame'\n | 'iframe'\n | 'icon'\n | 'image'\n | 'img'\n | 'input'\n | 'link'\n | 'navigation'\n | 'object'\n | 'ping'\n | 'script'\n | 'track'\n | 'video'\n | 'xmlhttprequest'\n\nexport type NetworkRecordOptions = {\n initiatorTypes?: InitiatorType[]\n maskRequestFn?: (data: CapturedNetworkRequest) => CapturedNetworkRequest | undefined\n recordHeaders?: boolean | { request: boolean; response: boolean }\n recordBody?: boolean | string[] | { request: boolean | string[]; response: boolean | string[] }\n recordInitialRequests?: boolean\n /**\n * whether to record PerformanceEntry events for network requests\n */\n recordPerformance?: boolean\n /**\n * the PerformanceObserver will only observe these entry types\n */\n performanceEntryTypeToObserve: string[]\n /**\n * the maximum size of the request/response body to record\n * NB this will be at most 1MB even if set larger\n */\n payloadSizeLimitBytes: number\n /**\n * some domains we should never record the payload\n * for example other companies session replay ingestion payloads aren't super useful but are gigantic\n * if this isn't provided we use a default list\n * if this is provided - we add the provided list to the default list\n * i.e. we never record the payloads on the default deny list\n */\n payloadHostDenyList?: string[]\n}\n\n/** @deprecated - use CapturedNetworkRequest instead */\nexport type NetworkRequest = {\n url: string\n}\n\n// In rrweb this is called NetworkRequest, but we already exposed that as having only URL\n// we also want to vary from the rrweb NetworkRequest because we want to include\n// all PerformanceEntry properties too.\n// that has 4 required properties\n// readonly duration: DOMHighResTimeStamp;\n// readonly entryType: string;\n// readonly name: string;\n// readonly startTime: DOMHighResTimeStamp;\n// NB: properties below here are ALPHA, don't rely on them, they may change without notice\n\n// we mirror PerformanceEntry since we read into this type from a PerformanceObserver,\n// but we don't want to inherit its readonly-iness\ntype Writable<T> = { -readonly [P in keyof T]: T[P] }\n\nexport type CapturedNetworkRequest = Writable<Omit<PerformanceEntry, 'toJSON'>> & {\n // properties below here are ALPHA, don't rely on them, they may change without notice\n method?: string\n initiatorType?: InitiatorType\n status?: number\n timeOrigin?: number\n timestamp?: number\n startTime?: number\n endTime?: number\n requestHeaders?: Headers\n requestBody?: string | null\n responseHeaders?: Headers\n responseBody?: string | null\n // was this captured before fetch/xhr could have been wrapped\n isInitial?: boolean\n}\n\nexport type ErrorEventArgs = [\n event: string | Event,\n source?: string | undefined,\n lineno?: number | undefined,\n colno?: number | undefined,\n error?: Error | undefined,\n]\n\nexport type ErrorMetadata = {\n handled?: boolean\n synthetic?: boolean\n syntheticException?: Error\n overrideExceptionType?: string\n overrideExceptionMessage?: string\n defaultExceptionType?: string\n defaultExceptionMessage?: string\n}\n\n// levels originally copied from Sentry to work with the sentry integration\n// and to avoid relying on a frequently changing @sentry/types dependency\n// but provided as an array of literal types, so we can constrain the level below\nexport const severityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'] as const\nexport declare type SeverityLevel = (typeof severityLevels)[number]\n\nexport interface ErrorProperties {\n $exception_type: string\n $exception_message: string\n $exception_level: SeverityLevel\n $exception_source?: string\n $exception_lineno?: number\n $exception_colno?: number\n $exception_DOMException_code?: string\n $exception_is_synthetic?: boolean\n $exception_stack_trace_raw?: string\n $exception_handled?: boolean\n $exception_personURL?: string\n}\n\nexport interface ErrorConversions {\n errorToProperties: (args: ErrorEventArgs) => ErrorProperties\n unhandledRejectionToProperties: (args: [ev: PromiseRejectionEvent]) => ErrorProperties\n}\n\nexport interface SessionRecordingUrlTrigger {\n url: string\n matching: 'regex'\n}\n","import { window } from './globals'\nimport { knownUnsafeEditableEvent, KnownUnsafeEditableEvent } from '../types'\nimport { includes } from './string-utils'\n\n// eslint-disable-next-line posthog-js/no-direct-array-check\nconst nativeIsArray = Array.isArray\nconst ObjProto = Object.prototype\nexport const hasOwnProperty = ObjProto.hasOwnProperty\nconst toString = ObjProto.toString\n\nexport const isArray =\n nativeIsArray ||\n function (obj: any): obj is any[] {\n return toString.call(obj) === '[object Array]'\n }\n\n// from a comment on http://dbj.org/dbj/?p=286\n// fails on only one very rare and deliberate custom object:\n// let bomb = { toString : undefined, valueOf: function(o) { return \"function BOMBA!\"; }};\nexport const isFunction = (x: unknown): x is (...args: any[]) => any => {\n // eslint-disable-next-line posthog-js/no-direct-function-check\n return typeof x === 'function'\n}\n\nexport const isNativeFunction = (x: unknown): x is (...args: any[]) => any =>\n isFunction(x) && x.toString().indexOf('[native code]') !== -1\n\n// When angular patches functions they pass the above `isNativeFunction` check (at least the MutationObserver)\nexport const isAngularZonePresent = (): boolean => {\n return !!(window as any).Zone\n}\n\n// Underscore Addons\nexport const isObject = (x: unknown): x is Record<string, any> => {\n // eslint-disable-next-line posthog-js/no-direct-object-check\n return x === Object(x) && !isArray(x)\n}\nexport const isEmptyObject = (x: unknown) => {\n if (isObject(x)) {\n for (const key in x) {\n if (hasOwnProperty.call(x, key)) {\n return false\n }\n }\n return true\n }\n return false\n}\nexport const isUndefined = (x: unknown): x is undefined => x === void 0\n\nexport const isString = (x: unknown): x is string => {\n // eslint-disable-next-line posthog-js/no-direct-string-check\n return toString.call(x) == '[object String]'\n}\n\nexport const isEmptyString = (x: unknown): boolean => isString(x) && x.trim().length === 0\n\nexport const isNull = (x: unknown): x is null => {\n // eslint-disable-next-line posthog-js/no-direct-null-check\n return x === null\n}\n\n/*\n sometimes you want to check if something is null or undefined\n that's what this is for\n */\nexport const isNullish = (x: unknown): x is null | undefined => isUndefined(x) || isNull(x)\n\nexport const isNumber = (x: unknown): x is number => {\n // eslint-disable-next-line posthog-js/no-direct-number-check\n return toString.call(x) == '[object Number]'\n}\nexport const isBoolean = (x: unknown): x is boolean => {\n // eslint-disable-next-line posthog-js/no-direct-boolean-check\n return toString.call(x) === '[object Boolean]'\n}\n\nexport const isDocument = (x: unknown): x is Document => {\n // eslint-disable-next-line posthog-js/no-direct-document-check\n return x instanceof Document\n}\n\nexport const isFormData = (x: unknown): x is FormData => {\n // eslint-disable-next-line posthog-js/no-direct-form-data-check\n return x instanceof FormData\n}\n\nexport const isFile = (x: unknown): x is File => {\n // eslint-disable-next-line posthog-js/no-direct-file-check\n return x instanceof File\n}\n\nexport const isKnownUnsafeEditableEvent = (x: unknown): x is KnownUnsafeEditableEvent => {\n return includes(knownUnsafeEditableEvent as unknown as string[], x)\n}\n","import Config from '../config'\nimport { isUndefined } from './type-utils'\nimport { assignableWindow, window } from './globals'\n\nexport type Logger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => void\n info: (...args: any[]) => void\n warn: (...args: any[]) => void\n error: (...args: any[]) => void\n critical: (...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string) => Logger\n}\n\nconst _createLogger = (prefix: string): Logger => {\n const logger: Logger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string) => _createLogger(`${prefix} ${additionalPrefix}`),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","import { VNode, cloneElement, createContext } from 'preact'\nimport { PostHog } from '../../posthog-core'\nimport { MultipleSurveyQuestion, Survey, SurveyAppearance, SurveyQuestion } from '../../posthog-surveys-types'\nimport { document as _document, window as _window } from '../../utils/globals'\nimport { createLogger } from '../../utils/logger'\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\nconst SurveySeenPrefix = 'seenSurvey_'\n\nconst logger = createLogger('[Surveys]')\n\nexport const style = (appearance: SurveyAppearance | null) => {\n const positions = {\n left: 'left: 30px;',\n right: 'right: 30px;',\n center: `\n left: 50%;\n transform: translateX(-50%);\n `,\n }\n return `\n .survey-form, .thank-you-message {\n position: fixed;\n margin: 0px;\n bottom: 0px;\n color: black;\n font-weight: normal;\n font-family: ${appearance?.fontFamily || '-apple-system'}, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n text-align: left;\n max-width: ${parseInt(appearance?.maxWidth || '300')}px;\n width: 100%;\n z-index: ${parseInt(appearance?.zIndex || '99999')};\n border: 1.5px solid ${appearance?.borderColor || '#c9c6c6'};\n border-bottom: 0px;\n ${positions[appearance?.position || 'right'] || 'right: 30px;'}\n flex-direction: column;\n background: ${appearance?.backgroundColor || '#eeeded'};\n border-top-left-radius: 10px;\n border-top-right-radius: 10px;\n box-shadow: -6px 0 16px -8px rgb(0 0 0 / 8%), -9px 0 28px 0 rgb(0 0 0 / 5%), -12px 0 48px 16px rgb(0 0 0 / 3%);\n }\n\n .survey-box, .thank-you-message-container {\n padding: 20px 25px 10px;\n display: flex;\n flex-direction: column;\n border-radius: 10px;\n }\n\n .thank-you-message {\n text-align: center;\n }\n\n .form-submit[disabled] {\n opacity: 0.6;\n filter: grayscale(50%);\n cursor: not-allowed;\n }\n .survey-form textarea {\n color: #2d2d2d;\n font-size: 14px;\n font-family: ${appearance?.fontFamily || '-apple-system'}, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n background: white;\n color: black;\n outline: none;\n padding-left: 10px;\n padding-right: 10px;\n padding-top: 10px;\n border-radius: 6px;\n border-color: ${appearance?.borderColor || '#c9c6c6'};\n margin-top: 14px;\n width: 100%;\n box-sizing: border-box;\n }\n .survey-box:has(.survey-question:empty):not(:has(.survey-question-description)) textarea {\n margin-top: 0;\n }\n .form-submit {\n box-sizing: border-box;\n margin: 0;\n font-family: inherit;\n overflow: visible;\n text-transform: none;\n position: relative;\n display: inline-block;\n font-weight: 700;\n white-space: nowrap;\n text-align: center;\n border: 1.5px solid transparent;\n cursor: pointer;\n user-select: none;\n touch-action: manipulation;\n padding: 12px;\n font-size: 14px;\n border-radius: 6px;\n outline: 0;\n background: ${appearance?.submitButtonColor || 'black'} !important;\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);\n box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);\n width: 100%;\n }\n .form-cancel {\n display: flex;\n float: right;\n border: none;\n background: none;\n cursor: pointer;\n }\n .cancel-btn-wrapper {\n position: absolute;\n width: 35px;\n height: 35px;\n border-radius: 100%;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n background: white;\n border: 1.5px solid ${appearance?.borderColor || '#c9c6c6'};\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .bolded { font-weight: 600; }\n .buttons {\n display: flex;\n justify-content: center;\n }\n .footer-branding {\n font-size: 11px;\n margin-top: 10px;\n text-align: center;\n display: flex;\n justify-content: center;\n gap: 4px;\n align-items: center;\n font-weight: 500;\n background: ${appearance?.backgroundColor || '#eeeded'};\n text-decoration: none;\n backgroundColor: ${appearance?.backgroundColor || '#eeeded'};\n color: ${getContrastingTextColor(appearance?.backgroundColor || '#eeeded')};\n }\n .survey-question {\n font-weight: 500;\n font-size: 14px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .question-textarea-wrapper {\n display: flex;\n flex-direction: column;\n }\n .survey-question-description {\n font-size: 13px;\n padding-top: 5px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .ratings-number {\n font-size: 16px;\n font-weight: 600;\n padding: 8px 0px;\n border: none;\n }\n .ratings-number:hover {\n cursor: pointer;\n }\n .rating-options {\n margin-top: 14px;\n }\n .rating-options-number {\n display: grid;\n border-radius: 6px;\n overflow: hidden;\n border: 1.5px solid ${appearance?.borderColor || '#c9c6c6'};\n }\n .rating-options-number > .ratings-number {\n border-right: 1px solid ${appearance?.borderColor || '#c9c6c6'};\n }\n .rating-options-number > .ratings-number:last-of-type {\n border-right: 0px;\n }\n .rating-options-number .rating-active {\n background: ${appearance?.ratingButtonActiveColor || 'black'};\n }\n .rating-options-emoji {\n display: flex;\n justify-content: space-between;\n }\n .ratings-emoji {\n font-size: 16px;\n background-color: transparent;\n border: none;\n padding: 0px;\n }\n .ratings-emoji:hover {\n cursor: pointer;\n }\n .ratings-emoji.rating-active svg {\n fill: ${appearance?.ratingButtonActiveColor || 'black'};\n }\n .emoji-svg {\n fill: '#939393';\n }\n .rating-text {\n display: flex;\n flex-direction: row;\n font-size: 11px;\n justify-content: space-between;\n margin-top: 6px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n opacity: .60;\n }\n .multiple-choice-options {\n margin-top: 13px;\n font-size: 14px;\n }\n .survey-box:has(.survey-question:empty):not(:has(.survey-question-description)) .multiple-choice-options {\n margin-top: 0;\n }\n .multiple-choice-options .choice-option {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 13px;\n cursor: pointer;\n margin-bottom: 5px;\n position: relative;\n }\n .multiple-choice-options > .choice-option:last-of-type {\n margin-bottom: 0px;\n }\n .multiple-choice-options input {\n cursor: pointer;\n position: absolute;\n opacity: 0;\n }\n .choice-check {\n position: absolute;\n right: 10px;\n background: white;\n }\n .choice-check svg {\n display: none;\n }\n .multiple-choice-options .choice-option:hover .choice-check svg {\n display: inline-block;\n opacity: .25;\n }\n .multiple-choice-options input:checked + label + .choice-check svg {\n display: inline-block;\n opacity: 100% !important;\n }\n .multiple-choice-options input:checked + label {\n font-weight: bold;\n border: 1.5px solid rgba(0,0,0);\n }\n .multiple-choice-options input:checked + label input {\n font-weight: bold;\n }\n .multiple-choice-options label {\n width: 100%;\n cursor: pointer;\n padding: 10px;\n border: 1.5px solid rgba(0,0,0,.25);\n border-radius: 4px;\n background: white;\n }\n .multiple-choice-options .choice-option-open label {\n padding-right: 30px;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n max-width: 100%;\n }\n .multiple-choice-options .choice-option-open label span {\n width: 100%;\n }\n .multiple-choice-options .choice-option-open input:disabled + label {\n opacity: 0.6;\n }\n .multiple-choice-options .choice-option-open label input {\n position: relative;\n opacity: 1;\n flex-grow: 1;\n border: 0;\n outline: 0;\n }\n .thank-you-message-body {\n margin-top: 6px;\n font-size: 14px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .thank-you-message-header {\n margin: 10px 0px 0px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .thank-you-message-container .form-submit {\n margin-top: 20px;\n margin-bottom: 10px;\n }\n .thank-you-message-countdown {\n margin-left: 6px;\n }\n .bottom-section {\n margin-top: 14px;\n }\n `\n}\n\nfunction nameToHex(name: string) {\n return {\n aliceblue: '#f0f8ff',\n antiquewhite: '#faebd7',\n aqua: '#00ffff',\n aquamarine: '#7fffd4',\n azure: '#f0ffff',\n beige: '#f5f5dc',\n bisque: '#ffe4c4',\n black: '#000000',\n blanchedalmond: '#ffebcd',\n blue: '#0000ff',\n blueviolet: '#8a2be2',\n brown: '#a52a2a',\n burlywood: '#deb887',\n cadetblue: '#5f9ea0',\n chartreuse: '#7fff00',\n chocolate: '#d2691e',\n coral: '#ff7f50',\n cornflowerblue: '#6495ed',\n cornsilk: '#fff8dc',\n crimson: '#dc143c',\n cyan: '#00ffff',\n darkblue: '#00008b',\n darkcyan: '#008b8b',\n darkgoldenrod: '#b8860b',\n darkgray: '#a9a9a9',\n darkgreen: '#006400',\n darkkhaki: '#bdb76b',\n darkmagenta: '#8b008b',\n darkolivegreen: '#556b2f',\n darkorange: '#ff8c00',\n darkorchid: '#9932cc',\n darkred: '#8b0000',\n darksalmon: '#e9967a',\n darkseagreen: '#8fbc8f',\n darkslateblue: '#483d8b',\n darkslategray: '#2f4f4f',\n darkturquoise: '#00ced1',\n darkviolet: '#9400d3',\n deeppink: '#ff1493',\n deepskyblue: '#00bfff',\n dimgray: '#696969',\n dodgerblue: '#1e90ff',\n firebrick: '#b22222',\n floralwhite: '#fffaf0',\n forestgreen: '#228b22',\n fuchsia: '#ff00ff',\n gainsboro: '#dcdcdc',\n ghostwhite: '#f8f8ff',\n gold: '#ffd700',\n goldenrod: '#daa520',\n gray: '#808080',\n green: '#008000',\n greenyellow: '#adff2f',\n honeydew: '#f0fff0',\n hotpink: '#ff69b4',\n 'indianred ': '#cd5c5c',\n indigo: '#4b0082',\n ivory: '#fffff0',\n khaki: '#f0e68c',\n lavender: '#e6e6fa',\n lavenderblush: '#fff0f5',\n lawngreen: '#7cfc00',\n lemonchiffon: '#fffacd',\n lightblue: '#add8e6',\n lightcoral: '#f08080',\n lightcyan: '#e0ffff',\n lightgoldenrodyellow: '#fafad2',\n lightgrey: '#d3d3d3',\n lightgreen: '#90ee90',\n lightpink: '#ffb6c1',\n lightsalmon: '#ffa07a',\n lightseagreen: '#20b2aa',\n lightskyblue: '#87cefa',\n lightslategray: '#778899',\n lightsteelblue: '#b0c4de',\n lightyellow: '#ffffe0',\n lime: '#00ff00',\n limegreen: '#32cd32',\n linen: '#faf0e6',\n magenta: '#ff00ff',\n maroon: '#800000',\n mediumaquamarine: '#66cdaa',\n mediumblue: '#0000cd',\n mediumorchid: '#ba55d3',\n mediumpurple: '#9370d8',\n mediumseagreen: '#3cb371',\n mediumslateblue: '#7b68ee',\n mediumspringgreen: '#00fa9a',\n mediumturquoise: '#48d1cc',\n mediumvioletred: '#c71585',\n midnightblue: '#191970',\n mintcream: '#f5fffa',\n mistyrose: '#ffe4e1',\n moccasin: '#ffe4b5',\n navajowhite: '#ffdead',\n navy: '#000080',\n oldlace: '#fdf5e6',\n olive: '#808000',\n olivedrab: '#6b8e23',\n orange: '#ffa500',\n orangered: '#ff4500',\n orchid: '#da70d6',\n palegoldenrod: '#eee8aa',\n palegreen: '#98fb98',\n paleturquoise: '#afeeee',\n palevioletred: '#d87093',\n papayawhip: '#ffefd5',\n peachpuff: '#ffdab9',\n peru: '#cd853f',\n pink: '#ffc0cb',\n plum: '#dda0dd',\n powderblue: '#b0e0e6',\n purple: '#800080',\n red: '#ff0000',\n rosybrown: '#bc8f8f',\n royalblue: '#4169e1',\n saddlebrown: '#8b4513',\n salmon: '#fa8072',\n sandybrown: '#f4a460',\n seagreen: '#2e8b57',\n seashell: '#fff5ee',\n sienna: '#a0522d',\n silver: '#c0c0c0',\n skyblue: '#87ceeb',\n slateblue: '#6a5acd',\n slategray: '#708090',\n snow: '#fffafa',\n springgreen: '#00ff7f',\n steelblue: '#4682b4',\n tan: '#d2b48c',\n teal: '#008080',\n thistle: '#d8bfd8',\n tomato: '#ff6347',\n turquoise: '#40e0d0',\n violet: '#ee82ee',\n wheat: '#f5deb3',\n white: '#ffffff',\n whitesmoke: '#f5f5f5',\n yellow: '#ffff00',\n yellowgreen: '#9acd32',\n }[name.toLowerCase()]\n}\n\nfunction hex2rgb(c: string) {\n if (c[0] === '#') {\n const hexColor = c.replace(/^#/, '')\n const r = parseInt(hexColor.slice(0, 2), 16)\n const g = parseInt(hexColor.slice(2, 4), 16)\n const b = parseInt(hexColor.slice(4, 6), 16)\n return 'rgb(' + r + ',' + g + ',' + b + ')'\n }\n return 'rgb(255, 255, 255)'\n}\n\nexport function getContrastingTextColor(color: string = defaultBackgroundColor) {\n let rgb\n if (color[0] === '#') {\n rgb = hex2rgb(color)\n }\n if (color.startsWith('rgb')) {\n rgb = color\n }\n // otherwise it's a color name\n const nameColorToHex = nameToHex(color)\n if (nameColorToHex) {\n rgb = hex2rgb(nameColorToHex)\n }\n if (!rgb) {\n return 'black'\n }\n const colorMatch = rgb.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)$/)\n if (colorMatch) {\n const r = parseInt(colorMatch[1])\n const g = parseInt(colorMatch[2])\n const b = parseInt(colorMatch[3])\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? 'black' : 'white'\n }\n return 'black'\n}\nexport function getTextColor(el: HTMLElement) {\n const backgroundColor = window.getComputedStyle(el).backgroundColor\n if (backgroundColor === 'rgba(0, 0, 0, 0)') {\n return 'black'\n }\n const colorMatch = backgroundColor.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)$/)\n if (!colorMatch) return 'black'\n\n const r = parseInt(colorMatch[1])\n const g = parseInt(colorMatch[2])\n const b = parseInt(colorMatch[3])\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? 'black' : 'white'\n}\n\nexport const defaultSurveyAppearance: SurveyAppearance = {\n backgroundColor: '#eeeded',\n submitButtonColor: 'black',\n submitButtonTextColor: 'white',\n ratingButtonColor: 'white',\n ratingButtonActiveColor: 'black',\n borderColor: '#c9c6c6',\n placeholder: 'Start typing...',\n whiteLabel: false,\n displayThankYouMessage: true,\n thankYouMessageHeader: 'Thank you for your feedback!',\n position: 'right',\n}\n\nexport const defaultBackgroundColor = '#eeeded'\n\nexport const createShadow = (styleSheet: string, surveyId: string, element?: Element) => {\n const div = document.createElement('div')\n div.className = `PostHogSurvey${surveyId}`\n const shadow = div.attachShadow({ mode: 'open' })\n if (styleSheet) {\n const styleElement = Object.assign(document.createElement('style'), {\n innerText: styleSheet,\n })\n shadow.appendChild(styleElement)\n }\n ;(element ? element : document.body).appendChild(div)\n return shadow\n}\n\nexport const sendSurveyEvent = (\n responses: Record<string, string | number | string[] | null> = {},\n survey: Survey,\n posthog?: PostHog\n) => {\n if (!posthog) {\n logger.error('[survey sent] event not captured, PostHog instance not found.')\n return\n }\n localStorage.setItem(getSurveySeenKey(survey), 'true')\n\n posthog.capture('survey sent', {\n $survey_name: survey.name,\n $survey_id: survey.id,\n $survey_iteration: survey.current_iteration,\n $survey_iteration_start_date: survey.current_iteration_start_date,\n $survey_questions: survey.questions.map((question) => question.question),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n ...responses,\n $set: {\n [getSurveyInteractionProperty(survey, 'responded')]: true,\n },\n })\n window.dispatchEvent(new Event('PHSurveySent'))\n}\n\nexport const dismissedSurveyEvent = (survey: Survey, posthog?: PostHog, readOnly?: boolean) => {\n // TODO: state management and unit tests for this would be nice\n if (!posthog) {\n logger.error('[survey dismissed] event not captured, PostHog instance not found.')\n return\n }\n if (readOnly) {\n return\n }\n posthog.capture('survey dismissed', {\n $survey_name: survey.name,\n $survey_id: survey.id,\n $survey_iteration: survey.current_iteration,\n $survey_iteration_start_date: survey.current_iteration_start_date,\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n $set: {\n [getSurveyInteractionProperty(survey, 'dismissed')]: true,\n },\n })\n localStorage.setItem(getSurveySeenKey(survey), 'true')\n window.dispatchEvent(new Event('PHSurveyClosed'))\n}\n\n// Use the Fisher-yates algorithm to shuffle this array\n// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\nexport const shuffle = (array: any[]) => {\n return array\n .map((a) => ({ sort: Math.floor(Math.random() * 10), value: a }))\n .sort((a, b) => a.sort - b.sort)\n .map((a) => a.value)\n}\n\nconst reverseIfUnshuffled = (unshuffled: any[], shuffled: any[]): any[] => {\n if (unshuffled.length === shuffled.length && unshuffled.every((val, index) => val === shuffled[index])) {\n return shuffled.reverse()\n }\n\n return shuffled\n}\n\nexport const getDisplayOrderChoices = (question: MultipleSurveyQuestion): string[] => {\n if (!question.shuffleOptions) {\n return question.choices\n }\n\n const displayOrderChoices = question.choices\n let openEndedChoice = ''\n if (question.hasOpenChoice) {\n // if the question has an open-ended choice, its always the last element in the choices array.\n openEndedChoice = displayOrderChoices.pop()!\n }\n\n const shuffledOptions = reverseIfUnshuffled(displayOrderChoices, shuffle(displayOrderChoices))\n\n if (question.hasOpenChoice) {\n question.choices.push(openEndedChoice)\n shuffledOptions.push(openEndedChoice)\n }\n\n return shuffledOptions\n}\n\nexport const getDisplayOrderQuestions = (survey: Survey): SurveyQuestion[] => {\n // retain the original questionIndex so we can correlate values in the webapp\n survey.questions.forEach((question, idx) => {\n question.originalQuestionIndex = idx\n })\n\n if (!survey.appearance || !survey.appearance.shuffleQuestions) {\n return survey.questions\n }\n\n return reverseIfUnshuffled(survey.questions, shuffle(survey.questions))\n}\n\nexport const hasEvents = (survey: Survey): boolean => {\n return survey.conditions?.events?.values?.length != undefined && survey.conditions?.events?.values?.length > 0\n}\n\nexport const canActivateRepeatedly = (survey: Survey): boolean => {\n return !!(survey.conditions?.events?.repeatedActivation && hasEvents(survey))\n}\n\n/**\n * getSurveySeen checks local storage for the surveySeen Key a\n * and overrides this value if the survey can be repeatedly activated by its events.\n * @param survey\n */\nexport const getSurveySeen = (survey: Survey): boolean => {\n const surveySeen = localStorage.getItem(getSurveySeenKey(survey))\n if (surveySeen) {\n // if a survey has already been seen,\n // we will override it with the event repeated activation value.\n return !canActivateRepeatedly(survey)\n }\n\n return false\n}\n\nexport const getSurveySeenKey = (survey: Survey): string => {\n let surveySeenKey = `${SurveySeenPrefix}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n surveySeenKey = `${SurveySeenPrefix}${survey.id}_${survey.current_iteration}`\n }\n\n return surveySeenKey\n}\n\nexport const getSurveySeenStorageKeys = (): string[] => {\n const surveyKeys = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(SurveySeenPrefix)) {\n surveyKeys.push(key)\n }\n }\n\n return surveyKeys\n}\n\nconst getSurveyInteractionProperty = (survey: Survey, action: string): string => {\n let surveyProperty = `$survey_${action}/${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n surveyProperty = `$survey_${action}/${survey.id}/${survey.current_iteration}`\n }\n\n return surveyProperty\n}\n\ninterface SurveyContextProps {\n isPreviewMode: boolean\n previewPageIndex: number | undefined\n handleCloseSurveyPopup: () => void\n isPopup: boolean\n onPreviewSubmit: (res: string | string[] | number | null) => void\n}\n\nexport const SurveyContext = createContext<SurveyContextProps>({\n isPreviewMode: false,\n previewPageIndex: 0,\n handleCloseSurveyPopup: () => {},\n isPopup: true,\n onPreviewSubmit: () => {},\n})\n\ninterface RenderProps {\n component: VNode<{ className: string }>\n children: string\n renderAsHtml?: boolean\n style?: React.CSSProperties\n}\n\nexport const renderChildrenAsTextOrHtml = ({ component, children, renderAsHtml, style }: RenderProps) => {\n return renderAsHtml\n ? cloneElement(component, {\n dangerouslySetInnerHTML: { __html: children },\n style,\n })\n : cloneElement(component, {\n children,\n style,\n })\n}\n","export const satisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146 272q66 0 121.5-35.5T682-393h-52q-23 40-63 61.5T480.5-310q-46.5 0-87-21T331-393h-53q26 61 81 96.5T480-261Zm0 181q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const neutralEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm20 194h253v-49H354v49ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const dissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146.174 116Q413-417 358.5-379.5T278-280h53q22-42 62.173-65t87.5-23Q528-368 567.5-344.5T630-280h52q-25-63-79.826-100-54.826-37-122-37ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const veryDissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M480-417q-67 0-121.5 37.5T278-280h404q-25-63-80-100t-122-37Zm-183-72 50-45 45 45 31-36-45-45 45-45-31-36-45 45-50-45-31 36 45 45-45 45 31 36Zm272 0 44-45 51 45 31-36-45-45 45-45-31-36-51 45-44-45-31 36 44 45-44 45 31 36ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142 0 241-99t99-241q0-142-99-241t-241-99q-142 0-241 99t-99 241q0 142 99 241t241 99Z\" />\n </svg>\n)\nexport const verySatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M479.504-261Q537-261 585.5-287q48.5-26 78.5-72.4 6-11.6-.75-22.6-6.75-11-20.25-11H316.918Q303-393 296.5-382t-.5 22.6q30 46.4 78.5 72.4 48.5 26 105.004 26ZM347-578l27 27q7.636 8 17.818 8Q402-543 410-551q8-8 8-18t-8-18l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.636-8 17.818Q276-559 284-551q8 8 18 8t18-8l27-27Zm267 0 27 27q7.714 8 18 8t18-8q8-7.636 8-17.818Q685-579 677-587l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.714-8 18t8 18q7.636 8 17.818 8Q579-543 587-551l27-27ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const cancelSVG = (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M0.164752 0.164752C0.384422 -0.0549175 0.740578 -0.0549175 0.960248 0.164752L6 5.20451L11.0398 0.164752C11.2594 -0.0549175 11.6156 -0.0549175 11.8352 0.164752C12.0549 0.384422 12.0549 0.740578 11.8352 0.960248L6.79549 6L11.8352 11.0398C12.0549 11.2594 12.0549 11.6156 11.8352 11.8352C11.6156 12.0549 11.2594 12.0549 11.0398 11.8352L6 6.79549L0.960248 11.8352C0.740578 12.0549 0.384422 12.0549 0.164752 11.8352C-0.0549175 11.6156 -0.0549175 11.2594 0.164752 11.0398L5.20451 6L0.164752 0.960248C-0.0549175 0.740578 -0.0549175 0.384422 0.164752 0.164752Z\"\n fill=\"black\"\n />\n </svg>\n)\nexport const IconPosthogLogo = (\n <svg width=\"77\" height=\"14\" viewBox=\"0 0 77 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_2415_6911)\">\n <mask\n id=\"mask0_2415_6911\"\n style={{ maskType: 'luminance' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width=\"77\"\n height=\"14\"\n >\n <path d=\"M0.5 0H76.5V14H0.5V0Z\" fill=\"white\" />\n </mask>\n <g mask=\"url(#mask0_2415_6911)\">\n <path\n d=\"M5.77226 8.02931C5.59388 8.37329 5.08474 8.37329 4.90634 8.02931L4.4797 7.20672C4.41155 7.07535 4.41155 6.9207 4.4797 6.78933L4.90634 5.96669C5.08474 5.62276 5.59388 5.62276 5.77226 5.96669L6.19893 6.78933C6.26709 6.9207 6.26709 7.07535 6.19893 7.20672L5.77226 8.02931ZM5.77226 12.6946C5.59388 13.0386 5.08474 13.0386 4.90634 12.6946L4.4797 11.872C4.41155 11.7406 4.41155 11.586 4.4797 11.4546L4.90634 10.632C5.08474 10.288 5.59388 10.288 5.77226 10.632L6.19893 11.4546C6.26709 11.586 6.26709 11.7406 6.19893 11.872L5.77226 12.6946Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M0.5 10.9238C0.5 10.508 1.02142 10.2998 1.32637 10.5938L3.54508 12.7327C3.85003 13.0267 3.63405 13.5294 3.20279 13.5294H0.984076C0.716728 13.5294 0.5 13.3205 0.5 13.0627V10.9238ZM0.5 8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.19753 13.3927C5.28831 13.4802 5.41144 13.5294 5.53982 13.5294H8.0421C8.47337 13.5294 8.68936 13.0267 8.3844 12.7327L1.32637 5.92856C1.02142 5.63456 0.5 5.84278 0.5 6.25854V8.67083ZM0.5 4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L10.0368 13.3927C10.1276 13.4802 10.2508 13.5294 10.3791 13.5294H12.8814C13.3127 13.5294 13.5287 13.0267 13.2237 12.7327L1.32637 1.26329C1.02142 0.969312 0.5 1.17752 0.5 1.59327V4.00556ZM5.33931 4.00556C5.33931 4.12932 5.39033 4.24802 5.4811 4.33554L14.1916 12.7327C14.4965 13.0267 15.0179 12.8185 15.0179 12.4028V9.99047C15.0179 9.86671 14.9669 9.74799 14.8762 9.66049L6.16568 1.26329C5.86071 0.969307 5.33931 1.17752 5.33931 1.59327V4.00556ZM11.005 1.26329C10.7 0.969307 10.1786 1.17752 10.1786 1.59327V4.00556C10.1786 4.12932 10.2296 4.24802 10.3204 4.33554L14.1916 8.06748C14.4965 8.36148 15.0179 8.15325 15.0179 7.7375V5.3252C15.0179 5.20144 14.9669 5.08272 14.8762 4.99522L11.005 1.26329Z\"\n fill=\"#F9BD2B\"\n />\n <path\n d=\"M21.0852 10.981L16.5288 6.58843C16.2238 6.29443 15.7024 6.50266 15.7024 6.91841V13.0627C15.7024 13.3205 15.9191 13.5294 16.1865 13.5294H23.2446C23.5119 13.5294 23.7287 13.3205 23.7287 13.0627V12.5032C23.7287 12.2455 23.511 12.0396 23.2459 12.0063C22.4323 11.9042 21.6713 11.546 21.0852 10.981ZM18.0252 12.0365C17.5978 12.0365 17.251 11.7021 17.251 11.2901C17.251 10.878 17.5978 10.5436 18.0252 10.5436C18.4527 10.5436 18.7996 10.878 18.7996 11.2901C18.7996 11.7021 18.4527 12.0365 18.0252 12.0365Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M0.5 13.0627C0.5 13.3205 0.716728 13.5294 0.984076 13.5294H3.20279C3.63405 13.5294 3.85003 13.0267 3.54508 12.7327L1.32637 10.5938C1.02142 10.2998 0.5 10.508 0.5 10.9238V13.0627ZM5.33931 5.13191L1.32637 1.26329C1.02142 0.969306 0.5 1.17752 0.5 1.59327V4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L5.33931 8.86412V5.13191ZM1.32637 5.92855C1.02142 5.63455 0.5 5.84278 0.5 6.25853V8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.33931 13.5294V9.79717L1.32637 5.92855Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M10.1787 5.3252C10.1787 5.20144 10.1277 5.08272 10.0369 4.99522L6.16572 1.26329C5.8608 0.969306 5.33936 1.17752 5.33936 1.59327V4.00556C5.33936 4.12932 5.39037 4.24802 5.48114 4.33554L10.1787 8.86412V5.3252ZM5.33936 13.5294H8.04214C8.47341 13.5294 8.6894 13.0267 8.38443 12.7327L5.33936 9.79717V13.5294ZM5.33936 5.13191V8.67083C5.33936 8.79459 5.39037 8.91331 5.48114 9.00081L10.1787 13.5294V9.99047C10.1787 9.86671 10.1277 9.74803 10.0369 9.66049L5.33936 5.13191Z\"\n fill=\"#F54E00\"\n />\n <path\n d=\"M29.375 11.6667H31.3636V8.48772H33.0249C34.8499 8.48772 36.0204 7.4443 36.0204 5.83052C36.0204 4.21681 34.8499 3.17334 33.0249 3.17334H29.375V11.6667ZM31.3636 6.84972V4.81136H32.8236C33.5787 4.81136 34.0318 5.19958 34.0318 5.83052C34.0318 6.4615 33.5787 6.84972 32.8236 6.84972H31.3636ZM39.618 11.7637C41.5563 11.7637 42.9659 10.429 42.9659 8.60905C42.9659 6.78905 41.5563 5.45438 39.618 5.45438C37.6546 5.45438 36.2701 6.78905 36.2701 8.60905C36.2701 10.429 37.6546 11.7637 39.618 11.7637ZM38.1077 8.60905C38.1077 7.63838 38.7118 6.97105 39.618 6.97105C40.5116 6.97105 41.1157 7.63838 41.1157 8.60905C41.1157 9.57972 40.5116 10.2471 39.618 10.2471C38.7118 10.2471 38.1077 9.57972 38.1077 8.60905ZM46.1482 11.7637C47.6333 11.7637 48.6402 10.8658 48.6402 9.81025C48.6402 7.33505 45.2294 8.13585 45.2294 7.16518C45.2294 6.8983 45.5189 6.72843 45.9342 6.72843C46.3622 6.72843 46.8782 6.98318 47.0418 7.54132L48.527 6.94678C48.2375 6.06105 47.1677 5.45438 45.8713 5.45438C44.4743 5.45438 43.6058 6.25518 43.6058 7.21372C43.6058 9.53118 46.9663 8.88812 46.9663 9.84665C46.9663 10.1864 46.6391 10.417 46.1482 10.417C45.4434 10.417 44.9525 9.94376 44.8015 9.3735L43.3164 9.93158C43.6436 10.8537 44.6001 11.7637 46.1482 11.7637ZM53.4241 11.606L53.2982 10.0651C53.0843 10.1743 52.8074 10.2106 52.5808 10.2106C52.1278 10.2106 51.8257 9.89523 51.8257 9.34918V7.03172H53.3612V5.55145H51.8257V3.78001H49.9755V5.55145H48.9687V7.03172H49.9755V9.57972C49.9755 11.06 51.0202 11.7637 52.3921 11.7637C52.7696 11.7637 53.122 11.7031 53.4241 11.606ZM59.8749 3.17334V6.47358H56.376V3.17334H54.3874V11.6667H56.376V8.11158H59.8749V11.6667H61.8761V3.17334H59.8749ZM66.2899 11.7637C68.2281 11.7637 69.6378 10.429 69.6378 8.60905C69.6378 6.78905 68.2281 5.45438 66.2899 5.45438C64.3265 5.45438 62.942 6.78905 62.942 8.60905C62.942 10.429 64.3265 11.7637 66.2899 11.7637ZM64.7796 8.60905C64.7796 7.63838 65.3837 6.97105 66.2899 6.97105C67.1835 6.97105 67.7876 7.63838 67.7876 8.60905C67.7876 9.57972 67.1835 10.2471 66.2899 10.2471C65.3837 10.2471 64.7796 9.57972 64.7796 8.60905ZM73.2088 11.4725C73.901 11.4725 74.5177 11.242 74.845 10.8416V11.424C74.845 12.1034 74.2786 12.5767 73.4102 12.5767C72.7935 12.5767 72.2523 12.2854 72.1642 11.788L70.4776 12.0428C70.7042 13.1955 71.925 13.972 73.4102 13.972C75.361 13.972 76.6574 12.8679 76.6574 11.2298V5.55145H74.8324V6.07318C74.4926 5.69705 73.9136 5.45438 73.171 5.45438C71.409 5.45438 70.3014 6.61918 70.3014 8.46345C70.3014 10.3077 71.409 11.4725 73.2088 11.4725ZM72.1012 8.46345C72.1012 7.55345 72.655 6.97105 73.5109 6.97105C74.3793 6.97105 74.9331 7.55345 74.9331 8.46345C74.9331 9.37345 74.3793 9.95585 73.5109 9.95585C72.655 9.95585 72.1012 9.37345 72.1012 8.46345Z\"\n fill=\"currentColor\"\n />\n </g>\n </g>\n <defs>\n <clipPath id=\"clip0_2415_6911\">\n <rect width=\"76\" height=\"14\" fill=\"white\" transform=\"translate(0.5)\" />\n </clipPath>\n </defs>\n </svg>\n)\nexport const checkSVG = (\n <svg width=\"16\" height=\"12\" viewBox=\"0 0 16 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.30769 10.6923L4.77736 11.2226C4.91801 11.3633 5.10878 11.4423 5.30769 11.4423C5.5066 11.4423 5.69737 11.3633 5.83802 11.2226L5.30769 10.6923ZM15.5303 1.53033C15.8232 1.23744 15.8232 0.762563 15.5303 0.46967C15.2374 0.176777 14.7626 0.176777 14.4697 0.46967L15.5303 1.53033ZM1.53033 5.85429C1.23744 5.56139 0.762563 5.56139 0.46967 5.85429C0.176777 6.14718 0.176777 6.62205 0.46967 6.91495L1.53033 5.85429ZM5.83802 11.2226L15.5303 1.53033L14.4697 0.46967L4.77736 10.162L5.83802 11.2226ZM0.46967 6.91495L4.77736 11.2226L5.83802 10.162L1.53033 5.85429L0.46967 6.91495Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n","import { IconPosthogLogo } from '../icons'\n// import { getContrastingTextColor } from '../surveys-utils'\n\nexport function PostHogLogo() {\n // const textColor = getContrastingTextColor(backgroundColor)\n\n return (\n <a\n href=\"https://posthog.com\"\n target=\"_blank\"\n rel=\"noopener\"\n // style={{ backgroundColor: backgroundColor, color: textColor }}\n className=\"footer-branding\"\n >\n Survey by {IconPosthogLogo}\n </a>\n )\n}\n","import { window } from '../../../utils/globals'\n\nimport { SurveyAppearance } from '../../../posthog-surveys-types'\n\nimport { useContext } from 'preact/hooks'\nimport { SurveyContext, defaultSurveyAppearance, getContrastingTextColor } from '../surveys-utils'\nimport { PostHogLogo } from './PostHogLogo'\n\nexport function BottomSection({\n text,\n submitDisabled,\n appearance,\n onSubmit,\n link,\n onPreviewSubmit,\n}: {\n text: string\n submitDisabled: boolean\n appearance: SurveyAppearance\n onSubmit: () => void\n link?: string | null\n onPreviewSubmit?: () => void\n}) {\n const { isPreviewMode, isPopup } = useContext(SurveyContext)\n const textColor =\n appearance.submitButtonTextColor ||\n getContrastingTextColor(appearance.submitButtonColor || defaultSurveyAppearance.submitButtonColor)\n return (\n <div className=\"bottom-section\">\n <div className=\"buttons\">\n <button\n className=\"form-submit\"\n disabled={submitDisabled && !isPreviewMode}\n type=\"button\"\n style={isPopup ? { color: textColor } : {}}\n onClick={() => {\n if (isPreviewMode) {\n onPreviewSubmit?.()\n return\n }\n if (link) {\n window?.open(link)\n }\n onSubmit()\n }}\n >\n {text}\n </button>\n </div>\n {!appearance.whiteLabel && <PostHogLogo />}\n </div>\n )\n}\n","import { SurveyContext, defaultSurveyAppearance, renderChildrenAsTextOrHtml } from '../surveys-utils'\nimport { cancelSVG } from '../icons'\nimport { useContext } from 'preact/hooks'\nimport { SurveyQuestionDescriptionContentType } from '../../../posthog-surveys-types'\nimport { h } from 'preact'\n\nexport function QuestionHeader({\n question,\n description,\n descriptionContentType,\n backgroundColor,\n forceDisableHtml,\n}: {\n question: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n forceDisableHtml: boolean\n backgroundColor?: string\n}) {\n const { isPopup } = useContext(SurveyContext)\n return (\n <div style={isPopup ? { backgroundColor: backgroundColor || defaultSurveyAppearance.backgroundColor } : {}}>\n <div className=\"survey-question\">{question}</div>\n {description &&\n renderChildrenAsTextOrHtml({\n component: h('div', { className: 'survey-question-description' }),\n children: description,\n renderAsHtml: !forceDisableHtml && descriptionContentType !== 'text',\n })}\n </div>\n )\n}\n\nexport function Cancel({ onClick }: { onClick: () => void }) {\n const { isPreviewMode } = useContext(SurveyContext)\n\n return (\n <div className=\"cancel-btn-wrapper\" onClick={onClick} disabled={isPreviewMode}>\n <button className=\"form-cancel\" onClick={onClick} disabled={isPreviewMode}>\n {cancelSVG}\n </button>\n </div>\n )\n}\n","import { BottomSection } from './BottomSection'\nimport { Cancel } from './QuestionHeader'\nimport { SurveyAppearance, SurveyQuestionDescriptionContentType } from '../../../posthog-surveys-types'\nimport { defaultSurveyAppearance, getContrastingTextColor, renderChildrenAsTextOrHtml } from '../surveys-utils'\nimport { h } from 'preact'\n\nimport { useContext } from 'preact/hooks'\nimport { SurveyContext } from '../../surveys/surveys-utils'\n\nexport function ConfirmationMessage({\n header,\n description,\n contentType,\n forceDisableHtml,\n appearance,\n onClose,\n styleOverrides,\n}: {\n header: string\n description: string\n forceDisableHtml: boolean\n contentType?: SurveyQuestionDescriptionContentType\n appearance: SurveyAppearance\n onClose: () => void\n styleOverrides?: React.CSSProperties\n}) {\n const textColor = getContrastingTextColor(appearance.backgroundColor || defaultSurveyAppearance.backgroundColor)\n\n const { isPopup } = useContext(SurveyContext)\n\n return (\n <>\n <div className=\"thank-you-message\" style={{ ...styleOverrides }}>\n <div className=\"thank-you-message-container\">\n {isPopup && <Cancel onClick={() => onClose()} />}\n <h3 className=\"thank-you-message-header\" style={{ color: textColor }}>\n {header}\n </h3>\n {description &&\n renderChildrenAsTextOrHtml({\n component: h('div', { className: 'thank-you-message-body' }),\n children: description,\n renderAsHtml: !forceDisableHtml && contentType !== 'text',\n style: { color: textColor },\n })}\n {isPopup && (\n <BottomSection\n text={appearance.thankYouMessageCloseButtonText || 'Close'}\n submitDisabled={false}\n appearance={appearance}\n onSubmit={() => onClose()}\n />\n )}\n </div>\n </div>\n </>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\nimport { SurveyAppearance } from '../../../posthog-surveys-types'\nimport * as Preact from 'preact'\nimport { getTextColor } from '../surveys-utils'\n\nexport function useContrastingTextColor(options: {\n appearance: SurveyAppearance\n defaultTextColor?: string\n forceUpdate?: boolean\n}): {\n ref: Preact.RefObject<HTMLElement>\n textColor: string\n} {\n const ref = useRef<HTMLElement>(null)\n const [textColor, setTextColor] = useState(options.defaultTextColor ?? 'black')\n\n // TODO: useContext to get the background colors instead of querying the DOM\n useEffect(() => {\n if (ref.current) {\n const color = getTextColor(ref.current)\n setTextColor(color)\n }\n }, [options.appearance, options.forceUpdate])\n\n return {\n ref,\n textColor,\n }\n}\n","import { RefObject } from 'preact'\nimport { useMemo, useRef, useState } from 'preact/hooks'\nimport {\n BasicSurveyQuestion,\n LinkSurveyQuestion,\n MultipleSurveyQuestion,\n RatingSurveyQuestion,\n SurveyAppearance,\n SurveyQuestionType,\n} from '../../../posthog-surveys-types'\nimport { isArray, isNull } from '../../../utils/type-utils'\nimport { useContrastingTextColor } from '../hooks/useContrastingTextColor'\nimport {\n checkSVG,\n dissatisfiedEmoji,\n neutralEmoji,\n satisfiedEmoji,\n veryDissatisfiedEmoji,\n verySatisfiedEmoji,\n} from '../icons'\nimport { getDisplayOrderChoices } from '../surveys-utils'\nimport { BottomSection } from './BottomSection'\nimport { QuestionHeader } from './QuestionHeader'\n\ninterface CommonProps {\n forceDisableHtml: boolean\n appearance: SurveyAppearance\n onSubmit: (res: string | string[] | number | null) => void\n onPreviewSubmit: (res: string | string[] | number | null) => void\n}\n\nexport function OpenTextQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: BasicSurveyQuestion\n}) {\n const textRef = useRef(null)\n const [text, setText] = useState('')\n\n return (\n <div ref={textRef}>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n backgroundColor={appearance.backgroundColor}\n forceDisableHtml={forceDisableHtml}\n />\n <textarea rows={4} placeholder={appearance?.placeholder} onInput={(e) => setText(e.currentTarget.value)} />\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={!text && !question.optional}\n appearance={appearance}\n onSubmit={() => onSubmit(text)}\n onPreviewSubmit={() => onPreviewSubmit(text)}\n />\n </div>\n )\n}\n\nexport function LinkQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: LinkSurveyQuestion\n}) {\n return (\n <>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n forceDisableHtml={forceDisableHtml}\n />\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={false}\n link={question.link}\n appearance={appearance}\n onSubmit={() => onSubmit('link clicked')}\n onPreviewSubmit={() => onPreviewSubmit('link clicked')}\n />\n </>\n )\n}\n\nexport function RatingQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: RatingSurveyQuestion\n displayQuestionIndex: number\n}) {\n const scale = question.scale\n const starting = question.scale === 10 ? 0 : 1\n const [rating, setRating] = useState<number | null>(null)\n\n return (\n <>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n forceDisableHtml={forceDisableHtml}\n backgroundColor={appearance.backgroundColor}\n />\n <div className=\"rating-section\">\n <div className=\"rating-options\">\n {question.display === 'emoji' && (\n <div className=\"rating-options-emoji\">\n {(question.scale === 3 ? threeScaleEmojis : fiveScaleEmojis).map((emoji, idx) => {\n const active = idx + 1 === rating\n return (\n <button\n className={`ratings-emoji question-${displayQuestionIndex}-rating-${idx} ${\n active ? 'rating-active' : null\n }`}\n value={idx + 1}\n key={idx}\n type=\"button\"\n onClick={() => {\n setRating(idx + 1)\n }}\n style={{\n fill: active\n ? appearance.ratingButtonActiveColor\n : appearance.ratingButtonColor,\n borderColor: appearance.borderColor,\n }}\n >\n {emoji}\n </button>\n )\n })}\n </div>\n )}\n {question.display === 'number' && (\n <div\n className=\"rating-options-number\"\n style={{ gridTemplateColumns: `repeat(${scale - starting + 1}, minmax(0, 1fr))` }}\n >\n {getScaleNumbers(question.scale).map((number, idx) => {\n const active = rating === number\n return (\n <RatingButton\n key={idx}\n displayQuestionIndex={displayQuestionIndex}\n active={active}\n appearance={appearance}\n num={number}\n setActiveNumber={(num) => {\n setRating(num)\n }}\n />\n )\n })}\n </div>\n )}\n </div>\n <div className=\"rating-text\">\n <div>{question.lowerBoundLabel}</div>\n <div>{question.upperBoundLabel}</div>\n </div>\n </div>\n <BottomSection\n text={question.buttonText || appearance?.submitButtonText || 'Submit'}\n submitDisabled={isNull(rating) && !question.optional}\n appearance={appearance}\n onSubmit={() => onSubmit(rating)}\n onPreviewSubmit={() => onPreviewSubmit(rating)}\n />\n </>\n )\n}\n\nexport function RatingButton({\n num,\n active,\n displayQuestionIndex,\n appearance,\n setActiveNumber,\n}: {\n num: number\n active: boolean\n displayQuestionIndex: number\n appearance: SurveyAppearance\n setActiveNumber: (num: number) => void\n}) {\n const { textColor, ref } = useContrastingTextColor({ appearance, defaultTextColor: 'black', forceUpdate: active })\n return (\n <button\n ref={ref as RefObject<HTMLButtonElement>}\n className={`ratings-number question-${displayQuestionIndex}-rating-${num} ${\n active ? 'rating-active' : null\n }`}\n type=\"button\"\n onClick={() => {\n setActiveNumber(num)\n }}\n style={{\n color: textColor,\n backgroundColor: active ? appearance.ratingButtonActiveColor : appearance.ratingButtonColor,\n borderColor: appearance.borderColor,\n }}\n >\n {num}\n </button>\n )\n}\n\nexport function MultipleChoiceQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: MultipleSurveyQuestion\n displayQuestionIndex: number\n}) {\n const textRef = useRef(null)\n const choices = useMemo(() => getDisplayOrderChoices(question), [question])\n const [selectedChoices, setSelectedChoices] = useState<string | string[] | null>(\n question.type === SurveyQuestionType.MultipleChoice ? [] : null\n )\n const [openChoiceSelected, setOpenChoiceSelected] = useState(false)\n const [openEndedInput, setOpenEndedInput] = useState('')\n\n const inputType = question.type === SurveyQuestionType.SingleChoice ? 'radio' : 'checkbox'\n return (\n <div ref={textRef}>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n forceDisableHtml={forceDisableHtml}\n backgroundColor={appearance.backgroundColor}\n />\n <div className=\"multiple-choice-options\">\n {/* Remove the last element from the choices, if hasOpenChoice is set */}\n {/* shuffle all other options here if question.shuffleOptions is set */}\n {/* Always ensure that the open ended choice is the last option */}\n {choices.map((choice: string, idx: number) => {\n let choiceClass = 'choice-option'\n const val = choice\n const option = choice\n if (!!question.hasOpenChoice && idx === question.choices.length - 1) {\n choiceClass += ' choice-option-open'\n }\n return (\n <div className={choiceClass}>\n <input\n type={inputType}\n id={`surveyQuestion${displayQuestionIndex}Choice${idx}`}\n name={`question${displayQuestionIndex}`}\n value={val}\n disabled={!val}\n onInput={() => {\n if (question.hasOpenChoice && idx === question.choices.length - 1) {\n return setOpenChoiceSelected(!openChoiceSelected)\n }\n if (question.type === SurveyQuestionType.SingleChoice) {\n return setSelectedChoices(val)\n }\n if (\n question.type === SurveyQuestionType.MultipleChoice &&\n isArray(selectedChoices)\n ) {\n if (selectedChoices.includes(val)) {\n // filter out values because clicking on a selected choice should deselect it\n return setSelectedChoices(\n selectedChoices.filter((choice) => choice !== val)\n )\n }\n return setSelectedChoices([...selectedChoices, val])\n }\n }}\n />\n <label\n htmlFor={`surveyQuestion${displayQuestionIndex}Choice${idx}`}\n style={{ color: 'black' }}\n >\n {question.hasOpenChoice && idx === question.choices.length - 1 ? (\n <>\n <span>{option}:</span>\n <input\n type=\"text\"\n id={`surveyQuestion${displayQuestionIndex}Choice${idx}Open`}\n name={`question${displayQuestionIndex}`}\n onInput={(e) => {\n const userValue = e.currentTarget.value\n if (question.type === SurveyQuestionType.SingleChoice) {\n return setSelectedChoices(userValue)\n }\n if (\n question.type === SurveyQuestionType.MultipleChoice &&\n isArray(selectedChoices)\n ) {\n return setOpenEndedInput(userValue)\n }\n }}\n />\n </>\n ) : (\n option\n )}\n </label>\n <span className=\"choice-check\" style={{ color: 'black' }}>\n {checkSVG}\n </span>\n </div>\n )\n })}\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={\n (isNull(selectedChoices) ||\n (isArray(selectedChoices) && !openChoiceSelected && selectedChoices.length === 0) ||\n (isArray(selectedChoices) &&\n openChoiceSelected &&\n !openEndedInput &&\n selectedChoices.length === 0 &&\n !question.optional)) &&\n !question.optional\n }\n appearance={appearance}\n onSubmit={() => {\n if (openChoiceSelected && question.type === SurveyQuestionType.MultipleChoice) {\n if (isArray(selectedChoices)) {\n onSubmit([...selectedChoices, openEndedInput])\n }\n } else {\n onSubmit(selectedChoices)\n }\n }}\n onPreviewSubmit={() => {\n if (openChoiceSelected && question.type === SurveyQuestionType.MultipleChoice) {\n if (isArray(selectedChoices)) {\n onPreviewSubmit([...selectedChoices, openEndedInput])\n }\n } else {\n onPreviewSubmit(selectedChoices)\n }\n }}\n />\n </div>\n )\n}\n\nconst threeScaleEmojis = [dissatisfiedEmoji, neutralEmoji, satisfiedEmoji]\nconst fiveScaleEmojis = [veryDissatisfiedEmoji, dissatisfiedEmoji, neutralEmoji, satisfiedEmoji, verySatisfiedEmoji]\nconst fiveScaleNumbers = [1, 2, 3, 4, 5]\nconst sevenScaleNumbers = [1, 2, 3, 4, 5, 6, 7]\nconst tenScaleNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nfunction getScaleNumbers(scale: number): number[] {\n switch (scale) {\n case 5:\n return fiveScaleNumbers\n case 7:\n return sevenScaleNumbers\n case 10:\n return tenScaleNumbers\n default:\n return fiveScaleNumbers\n }\n}\n","import { PostHog } from '../posthog-core'\nimport {\n Survey,\n SurveyAppearance,\n SurveyQuestion,\n SurveyQuestionBranchingType,\n SurveyQuestionType,\n SurveyRenderReason,\n SurveyType,\n} from '../posthog-surveys-types'\n\nimport * as Preact from 'preact'\nimport { useContext, useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport { document as _document, window as _window } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\nimport { isNull, isNumber } from '../utils/type-utils'\nimport { createWidgetShadow, createWidgetStyle } from './surveys-widget'\nimport { ConfirmationMessage } from './surveys/components/ConfirmationMessage'\nimport { Cancel } from './surveys/components/QuestionHeader'\nimport {\n LinkQuestion,\n MultipleChoiceQuestion,\n OpenTextQuestion,\n RatingQuestion,\n} from './surveys/components/QuestionTypes'\nimport {\n createShadow,\n defaultSurveyAppearance,\n dismissedSurveyEvent,\n getContrastingTextColor,\n getDisplayOrderQuestions,\n getSurveySeen,\n sendSurveyEvent,\n style,\n SurveyContext,\n} from './surveys/surveys-utils'\nconst logger = createLogger('[Surveys]')\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\n\nexport class SurveyManager {\n private posthog: PostHog\n private surveyInFocus: string | null\n\n constructor(posthog: PostHog) {\n this.posthog = posthog\n // This is used to track the survey that is currently in focus. We only show one survey at a time.\n this.surveyInFocus = null\n }\n\n private canShowNextEventBasedSurvey = (): boolean => {\n // with event based surveys, we need to show the next survey without reloading the page.\n // A simple check for div elements with the class name pattern of PostHogSurvey_xyz doesn't work here\n // because preact leaves behind the div element for any surveys responded/dismissed with a <style> node.\n // To alleviate this, we check the last div in the dom and see if it has any elements other than a Style node.\n // if the last PostHogSurvey_xyz div has only one style node, we can show the next survey in the queue\n // without reloading the page.\n const surveyPopups = document.querySelectorAll(`div[class^=PostHogSurvey]`)\n if (surveyPopups.length > 0) {\n return surveyPopups[surveyPopups.length - 1].shadowRoot?.childElementCount === 1\n }\n return true\n }\n\n private handlePopoverSurvey = (survey: Survey): void => {\n const surveyWaitPeriodInDays = survey.conditions?.seenSurveyWaitPeriodInDays\n const lastSeenSurveyDate = localStorage.getItem(`lastSeenSurveyDate`)\n if (surveyWaitPeriodInDays && lastSeenSurveyDate) {\n const today = new Date()\n const diff = Math.abs(today.getTime() - new Date(lastSeenSurveyDate).getTime())\n const diffDaysFromToday = Math.ceil(diff / (1000 * 3600 * 24))\n if (diffDaysFromToday < surveyWaitPeriodInDays) {\n return\n }\n }\n\n const surveySeen = getSurveySeen(survey)\n if (!surveySeen) {\n this.addSurveyToFocus(survey.id)\n const shadow = createShadow(style(survey?.appearance), survey.id)\n Preact.render(\n <SurveyPopup\n key={'popover-survey'}\n posthog={this.posthog}\n survey={survey}\n removeSurveyFromFocus={this.removeSurveyFromFocus}\n isPopup={true}\n />,\n shadow\n )\n }\n }\n\n private handleWidget = (survey: Survey): void => {\n const shadow = createWidgetShadow(survey)\n const surveyStyleSheet = style(survey.appearance)\n shadow.appendChild(Object.assign(document.createElement('style'), { innerText: surveyStyleSheet }))\n Preact.render(\n <FeedbackWidget\n key={'feedback-survey'}\n posthog={this.posthog}\n survey={survey}\n removeSurveyFromFocus={this.removeSurveyFromFocus}\n />,\n shadow\n )\n }\n\n private handleWidgetSelector = (survey: Survey): void => {\n const selectorOnPage =\n survey.appearance?.widgetSelector && document.querySelector(survey.appearance.widgetSelector)\n if (selectorOnPage) {\n if (document.querySelectorAll(`.PostHogWidget${survey.id}`).length === 0) {\n this.handleWidget(survey)\n } else if (document.querySelectorAll(`.PostHogWidget${survey.id}`).length === 1) {\n // we have to check if user selector already has a survey listener attached to it because we always have to check if it's on the page or not\n if (!selectorOnPage.getAttribute('PHWidgetSurveyClickListener')) {\n const surveyPopup = document\n .querySelector(`.PostHogWidget${survey.id}`)\n ?.shadowRoot?.querySelector(`.survey-form`) as HTMLFormElement\n selectorOnPage.addEventListener('click', () => {\n if (surveyPopup) {\n surveyPopup.style.display = surveyPopup.style.display === 'none' ? 'block' : 'none'\n surveyPopup.addEventListener('PHSurveyClosed', () => {\n this.removeSurveyFromFocus(survey.id)\n surveyPopup.style.display = 'none'\n })\n }\n })\n selectorOnPage.setAttribute('PHWidgetSurveyClickListener', 'true')\n }\n }\n }\n }\n\n /**\n * Sorts surveys by their appearance delay in ascending order. If a survey does not have an appearance delay,\n * it is considered to have a delay of 0.\n * @param surveys\n * @returns The surveys sorted by their appearance delay\n */\n private sortSurveysByAppearanceDelay(surveys: Survey[]): Survey[] {\n return surveys.sort(\n (a, b) => (a.appearance?.surveyPopupDelaySeconds || 0) - (b.appearance?.surveyPopupDelaySeconds || 0)\n )\n }\n\n /**\n * Checks the feature flags associated with this Survey to see if the survey can be rendered.\n * @param survey\n * @param instance\n */\n public canRenderSurvey = (survey: Survey): SurveyRenderReason => {\n const renderReason: SurveyRenderReason = {\n visible: false,\n }\n\n if (survey.end_date) {\n renderReason.disabledReason = `survey was completed on ${survey.end_date}`\n return renderReason\n }\n\n if (survey.type != SurveyType.Popover) {\n renderReason.disabledReason = `Only Popover survey types can be rendered`\n return renderReason\n }\n\n const linkedFlagCheck = survey.linked_flag_key\n ? this.posthog.featureFlags.isFeatureEnabled(survey.linked_flag_key)\n : true\n\n if (!linkedFlagCheck) {\n renderReason.disabledReason = `linked feature flag ${survey.linked_flag_key} is false`\n return renderReason\n }\n\n const targetingFlagCheck = survey.targeting_flag_key\n ? this.posthog.featureFlags.isFeatureEnabled(survey.targeting_flag_key)\n : true\n\n if (!targetingFlagCheck) {\n renderReason.disabledReason = `targeting feature flag ${survey.targeting_flag_key} is false`\n return renderReason\n }\n\n const internalTargetingFlagCheck = survey.internal_targeting_flag_key\n ? this.posthog.featureFlags.isFeatureEnabled(survey.internal_targeting_flag_key)\n : true\n\n if (!internalTargetingFlagCheck) {\n renderReason.disabledReason = `internal targeting feature flag ${survey.internal_targeting_flag_key} is false`\n return renderReason\n }\n\n renderReason.visible = true\n return renderReason\n }\n\n public renderSurvey = (survey: Survey, selector: Element): void => {\n Preact.render(\n <SurveyPopup\n key={'popover-survey'}\n posthog={this.posthog}\n survey={survey}\n removeSurveyFromFocus={this.removeSurveyFromFocus}\n isPopup={false}\n />,\n selector\n )\n }\n\n public callSurveysAndEvaluateDisplayLogic = (forceReload: boolean = false): void => {\n this.posthog?.getActiveMatchingSurveys((surveys) => {\n const nonAPISurveys = surveys.filter((survey) => survey.type !== 'api')\n\n // Create a queue of surveys sorted by their appearance delay. We will evaluate the display logic\n // for each survey in the queue in order, and only display one survey at a time.\n const nonAPISurveyQueue = this.sortSurveysByAppearanceDelay(nonAPISurveys)\n\n nonAPISurveyQueue.forEach((survey) => {\n // We only evaluate the display logic for one survey at a time\n if (!isNull(this.surveyInFocus)) {\n return\n }\n if (survey.type === SurveyType.Widget) {\n if (\n survey.appearance?.widgetType === 'tab' &&\n document.querySelectorAll(`.PostHogWidget${survey.id}`).length === 0\n ) {\n this.handleWidget(survey)\n }\n if (survey.appearance?.widgetType === 'selector' && survey.appearance?.widgetSelector) {\n this.handleWidgetSelector(survey)\n }\n }\n\n if (survey.type === SurveyType.Popover && this.canShowNextEventBasedSurvey()) {\n this.handlePopoverSurvey(survey)\n }\n })\n }, forceReload)\n }\n\n private addSurveyToFocus = (id: string): void => {\n if (!isNull(this.surveyInFocus)) {\n logger.error(`Survey ${[...this.surveyInFocus]} already in focus. Cannot add survey ${id}.`)\n }\n this.surveyInFocus = id\n }\n\n private removeSurveyFromFocus = (id: string): void => {\n if (this.surveyInFocus !== id) {\n logger.error(`Survey ${id} is not in focus. Cannot remove survey ${id}.`)\n }\n this.surveyInFocus = null\n }\n\n // Expose internal state and methods for testing\n public getTestAPI() {\n return {\n addSurveyToFocus: this.addSurveyToFocus,\n removeSurveyFromFocus: this.removeSurveyFromFocus,\n surveyInFocus: this.surveyInFocus,\n canShowNextEventBasedSurvey: this.canShowNextEventBasedSurvey,\n handleWidget: this.handleWidget,\n handlePopoverSurvey: this.handlePopoverSurvey,\n handleWidgetSelector: this.handleWidgetSelector,\n sortSurveysByAppearanceDelay: this.sortSurveysByAppearanceDelay,\n }\n }\n}\n\nexport const renderSurveysPreview = ({\n survey,\n parentElement,\n previewPageIndex,\n forceDisableHtml,\n onPreviewSubmit,\n}: {\n survey: Survey\n parentElement: HTMLElement\n previewPageIndex: number\n forceDisableHtml?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n}) => {\n const surveyStyleSheet = style(survey.appearance)\n const styleElement = Object.assign(document.createElement('style'), { innerText: surveyStyleSheet })\n\n // Remove previously attached <style>\n Array.from(parentElement.children).forEach((child) => {\n if (child instanceof HTMLStyleElement) {\n parentElement.removeChild(child)\n }\n })\n\n parentElement.appendChild(styleElement)\n const textColor = getContrastingTextColor(\n survey.appearance?.backgroundColor || defaultSurveyAppearance.backgroundColor || 'white'\n )\n\n Preact.render(\n <SurveyPopup\n key=\"surveys-render-preview\"\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={{\n position: 'relative',\n right: 0,\n borderBottom: `1px solid ${survey.appearance?.borderColor}`,\n borderRadius: 10,\n color: textColor,\n }}\n onPreviewSubmit={onPreviewSubmit}\n previewPageIndex={previewPageIndex}\n removeSurveyFromFocus={() => {}}\n isPopup={true}\n />,\n parentElement\n )\n}\n\nexport const renderFeedbackWidgetPreview = ({\n survey,\n root,\n forceDisableHtml,\n}: {\n survey: Survey\n root: HTMLElement\n forceDisableHtml?: boolean\n}) => {\n const widgetStyleSheet = createWidgetStyle(survey.appearance?.widgetColor)\n const styleElement = Object.assign(document.createElement('style'), { innerText: widgetStyleSheet })\n root.appendChild(styleElement)\n Preact.render(\n <FeedbackWidget\n key={'feedback-render-preview'}\n forceDisableHtml={forceDisableHtml}\n survey={survey}\n readOnly={true}\n removeSurveyFromFocus={() => {}}\n />,\n root\n )\n}\n\n// This is the main exported function\nexport function generateSurveys(posthog: PostHog) {\n // NOTE: Important to ensure we never try and run surveys without a window environment\n if (!document || !window) {\n return\n }\n\n const surveyManager = new SurveyManager(posthog)\n surveyManager.callSurveysAndEvaluateDisplayLogic(true)\n\n // recalculate surveys every second to check if URL or selectors have changed\n setInterval(() => {\n surveyManager.callSurveysAndEvaluateDisplayLogic(false)\n }, 1000)\n return surveyManager\n}\n\nexport function usePopupVisibility(\n survey: Survey,\n posthog: PostHog | undefined,\n millisecondDelay: number,\n isPreviewMode: boolean,\n removeSurveyFromFocus: (id: string) => void\n) {\n const [isPopupVisible, setIsPopupVisible] = useState(isPreviewMode || millisecondDelay === 0)\n const [isSurveySent, setIsSurveySent] = useState(false)\n\n useEffect(() => {\n if (!posthog) {\n logger.error('usePopupVisibility hook called without a PostHog instance.')\n return\n }\n if (isPreviewMode) {\n return\n }\n\n const handleSurveyClosed = () => {\n removeSurveyFromFocus(survey.id)\n setIsPopupVisible(false)\n }\n\n const handleSurveySent = () => {\n if (!survey.appearance?.displayThankYouMessage) {\n removeSurveyFromFocus(survey.id)\n setIsPopupVisible(false)\n } else {\n setIsSurveySent(true)\n removeSurveyFromFocus(survey.id)\n if (survey.appearance?.autoDisappear) {\n setTimeout(() => {\n setIsPopupVisible(false)\n }, 5000)\n }\n }\n }\n\n const showSurvey = () => {\n setIsPopupVisible(true)\n window.dispatchEvent(new Event('PHSurveyShown'))\n posthog.capture('survey shown', {\n $survey_name: survey.name,\n $survey_id: survey.id,\n $survey_iteration: survey.current_iteration,\n $survey_iteration_start_date: survey.current_iteration_start_date,\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n })\n localStorage.setItem('lastSeenSurveyDate', new Date().toISOString())\n }\n\n const handleShowSurveyWithDelay = () => {\n const timeoutId = setTimeout(() => {\n showSurvey()\n }, millisecondDelay)\n\n return () => {\n clearTimeout(timeoutId)\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed)\n window.removeEventListener('PHSurveySent', handleSurveySent)\n }\n }\n\n const handleShowSurveyImmediately = () => {\n showSurvey()\n return () => {\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed)\n window.removeEventListener('PHSurveySent', handleSurveySent)\n }\n }\n\n window.addEventListener('PHSurveyClosed', handleSurveyClosed)\n window.addEventListener('PHSurveySent', handleSurveySent)\n\n if (millisecondDelay > 0) {\n return handleShowSurveyWithDelay()\n } else {\n return handleShowSurveyImmediately()\n }\n }, [])\n\n return { isPopupVisible, isSurveySent, setIsPopupVisible }\n}\n\ninterface SurveyPopupProps {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n style?: React.CSSProperties\n previewPageIndex?: number | undefined\n removeSurveyFromFocus: (id: string) => void\n isPopup?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n}\n\nexport function SurveyPopup({\n survey,\n forceDisableHtml,\n posthog,\n style,\n previewPageIndex,\n removeSurveyFromFocus,\n isPopup,\n onPreviewSubmit = () => {},\n}: SurveyPopupProps) {\n const isPreviewMode = Number.isInteger(previewPageIndex)\n // NB: The client-side code passes the millisecondDelay in seconds, but setTimeout expects milliseconds, so we multiply by 1000\n const surveyPopupDelayMilliseconds = survey.appearance?.surveyPopupDelaySeconds\n ? survey.appearance.surveyPopupDelaySeconds * 1000\n : 0\n const { isPopupVisible, isSurveySent, setIsPopupVisible } = usePopupVisibility(\n survey,\n posthog,\n surveyPopupDelayMilliseconds,\n isPreviewMode,\n removeSurveyFromFocus\n )\n const shouldShowConfirmation = isSurveySent || previewPageIndex === survey.questions.length\n const confirmationBoxLeftStyle = style?.left && isNumber(style?.left) ? { left: style.left - 40 } : {}\n\n if (isPreviewMode) {\n style = style || {}\n style.left = 'unset'\n style.right = 'unset'\n style.transform = 'unset'\n }\n\n return isPopupVisible ? (\n <SurveyContext.Provider\n value={{\n isPreviewMode,\n previewPageIndex: previewPageIndex,\n handleCloseSurveyPopup: () => dismissedSurveyEvent(survey, posthog, isPreviewMode),\n isPopup: isPopup || false,\n onPreviewSubmit,\n }}\n >\n {!shouldShowConfirmation ? (\n <Questions\n survey={survey}\n forceDisableHtml={!!forceDisableHtml}\n posthog={posthog}\n styleOverrides={style}\n />\n ) : (\n <ConfirmationMessage\n header={survey.appearance?.thankYouMessageHeader || 'Thank you!'}\n description={survey.appearance?.thankYouMessageDescription || ''}\n forceDisableHtml={!!forceDisableHtml}\n contentType={survey.appearance?.thankYouMessageDescriptionContentType}\n appearance={survey.appearance || defaultSurveyAppearance}\n styleOverrides={{ ...style, ...confirmationBoxLeftStyle }}\n onClose={() => setIsPopupVisible(false)}\n />\n )}\n </SurveyContext.Provider>\n ) : (\n <></>\n )\n}\n\nexport function Questions({\n survey,\n forceDisableHtml,\n posthog,\n styleOverrides,\n}: {\n survey: Survey\n forceDisableHtml: boolean\n posthog?: PostHog\n styleOverrides?: React.CSSProperties\n}) {\n const textColor = getContrastingTextColor(\n survey.appearance?.backgroundColor || defaultSurveyAppearance.backgroundColor\n )\n const [questionsResponses, setQuestionsResponses] = useState({})\n const { isPreviewMode, previewPageIndex, handleCloseSurveyPopup, isPopup, onPreviewSubmit } =\n useContext(SurveyContext)\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(previewPageIndex || 0)\n const surveyQuestions = useMemo(() => getDisplayOrderQuestions(survey), [survey])\n\n // Sync preview state\n useEffect(() => {\n setCurrentQuestionIndex(previewPageIndex ?? 0)\n }, [previewPageIndex])\n\n const onNextButtonClick = ({\n res,\n originalQuestionIndex,\n displayQuestionIndex,\n }: {\n res: string | string[] | number | null\n originalQuestionIndex: number\n displayQuestionIndex: number\n }) => {\n if (!posthog) {\n logger.error('onNextButtonClick called without a PostHog instance.')\n return\n }\n\n const responseKey =\n originalQuestionIndex === 0 ? `$survey_response` : `$survey_response_${originalQuestionIndex}`\n\n setQuestionsResponses({ ...questionsResponses, [responseKey]: res })\n\n // Old SDK, no branching\n if (!posthog.getNextSurveyStep) {\n const isLastDisplayedQuestion = displayQuestionIndex === survey.questions.length - 1\n if (isLastDisplayedQuestion) {\n sendSurveyEvent({ ...questionsResponses, [responseKey]: res }, survey, posthog)\n } else {\n setCurrentQuestionIndex(displayQuestionIndex + 1)\n }\n return\n }\n\n const nextStep = posthog.getNextSurveyStep(survey, displayQuestionIndex, res)\n if (nextStep === SurveyQuestionBranchingType.End) {\n sendSurveyEvent({ ...questionsResponses, [responseKey]: res }, survey, posthog)\n } else {\n setCurrentQuestionIndex(nextStep)\n }\n }\n\n return (\n <form\n className=\"survey-form\"\n style={\n isPopup\n ? {\n color: textColor,\n borderColor: survey.appearance?.borderColor,\n ...styleOverrides,\n }\n : {}\n }\n >\n {surveyQuestions.map((question, displayQuestionIndex) => {\n const { originalQuestionIndex } = question\n\n const isVisible = isPreviewMode\n ? currentQuestionIndex === originalQuestionIndex\n : currentQuestionIndex === displayQuestionIndex\n return (\n isVisible && (\n <div\n className=\"survey-box\"\n style={\n isPopup\n ? {\n backgroundColor:\n survey.appearance?.backgroundColor ||\n defaultSurveyAppearance.backgroundColor,\n }\n : {}\n }\n >\n {isPopup && <Cancel onClick={() => handleCloseSurveyPopup()} />}\n {getQuestionComponent({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance: survey.appearance || defaultSurveyAppearance,\n onSubmit: (res) =>\n onNextButtonClick({\n res,\n originalQuestionIndex,\n displayQuestionIndex,\n }),\n onPreviewSubmit,\n })}\n </div>\n )\n )\n })}\n </form>\n )\n}\n\nexport function FeedbackWidget({\n survey,\n forceDisableHtml,\n posthog,\n readOnly,\n removeSurveyFromFocus,\n}: {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n readOnly?: boolean\n removeSurveyFromFocus: (id: string) => void\n}): JSX.Element {\n const [showSurvey, setShowSurvey] = useState(false)\n const [styleOverrides, setStyle] = useState({})\n const widgetRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n if (!posthog) {\n logger.error('FeedbackWidget called without a PostHog instance.')\n return\n }\n if (readOnly) {\n return\n }\n\n if (survey.appearance?.widgetType === 'tab') {\n if (widgetRef.current) {\n const widgetPos = widgetRef.current.getBoundingClientRect()\n const style = {\n top: '50%',\n left: parseInt(`${widgetPos.right - 360}`),\n bottom: 'auto',\n borderRadius: 10,\n borderBottom: `1.5px solid ${survey.appearance?.borderColor || '#c9c6c6'}`,\n }\n setStyle(style)\n }\n }\n if (survey.appearance?.widgetType === 'selector') {\n const widget = document.querySelector(survey.appearance.widgetSelector || '')\n widget?.addEventListener('click', () => {\n setShowSurvey(!showSurvey)\n })\n widget?.setAttribute('PHWidgetSurveyClickListener', 'true')\n }\n }, [])\n\n return (\n <>\n {survey.appearance?.widgetType === 'tab' && (\n <div\n className=\"ph-survey-widget-tab\"\n ref={widgetRef}\n onClick={() => !readOnly && setShowSurvey(!showSurvey)}\n style={{ color: getContrastingTextColor(survey.appearance.widgetColor) }}\n >\n <div className=\"ph-survey-widget-tab-icon\"></div>\n {survey.appearance?.widgetLabel || ''}\n </div>\n )}\n {showSurvey && (\n <SurveyPopup\n key={'feedback-widget-survey'}\n posthog={posthog}\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={styleOverrides}\n removeSurveyFromFocus={removeSurveyFromFocus}\n isPopup={true}\n />\n )}\n </>\n )\n}\n\ninterface GetQuestionComponentProps {\n question: SurveyQuestion\n forceDisableHtml: boolean\n displayQuestionIndex: number\n appearance: SurveyAppearance\n onSubmit: (res: string | string[] | number | null) => void\n onPreviewSubmit: (res: string | string[] | number | null) => void\n}\n\nconst getQuestionComponent = ({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: GetQuestionComponentProps): JSX.Element => {\n const questionComponents = {\n [SurveyQuestionType.Open]: OpenTextQuestion,\n [SurveyQuestionType.Link]: LinkQuestion,\n [SurveyQuestionType.Rating]: RatingQuestion,\n [SurveyQuestionType.SingleChoice]: MultipleChoiceQuestion,\n [SurveyQuestionType.MultipleChoice]: MultipleChoiceQuestion,\n }\n\n const commonProps = {\n question,\n forceDisableHtml,\n appearance,\n onPreviewSubmit: (res: string | string[] | number | null) => {\n onPreviewSubmit(res)\n },\n onSubmit: (res: string | string[] | number | null) => {\n onSubmit(res)\n },\n }\n\n const additionalProps: Record<SurveyQuestionType, any> = {\n [SurveyQuestionType.Open]: {},\n [SurveyQuestionType.Link]: {},\n [SurveyQuestionType.Rating]: { displayQuestionIndex },\n [SurveyQuestionType.SingleChoice]: { displayQuestionIndex },\n [SurveyQuestionType.MultipleChoice]: { displayQuestionIndex },\n }\n\n const Component = questionComponents[question.type]\n const componentProps = { ...commonProps, ...additionalProps[question.type] }\n\n return <Component {...componentProps} />\n}\n","import { Survey } from '../posthog-surveys-types'\nimport { document as _document } from '../utils/globals'\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst document = _document as Document\n\nexport function createWidgetShadow(survey: Survey) {\n const div = document.createElement('div')\n div.className = `PostHogWidget${survey.id}`\n const shadow = div.attachShadow({ mode: 'open' })\n const widgetStyleSheet = createWidgetStyle(survey.appearance?.widgetColor)\n shadow.append(Object.assign(document.createElement('style'), { innerText: widgetStyleSheet }))\n document.body.appendChild(div)\n return shadow\n}\n\nexport function createWidgetStyle(widgetColor?: string) {\n return `\n .ph-survey-widget-tab {\n position: fixed;\n top: 50%;\n right: 0;\n background: ${widgetColor || '#e0a045'};\n color: white;\n transform: rotate(-90deg) translate(0, -100%);\n transform-origin: right top;\n min-width: 40px;\n padding: 8px 12px;\n font-weight: 500;\n border-radius: 3px 3px 0 0;\n text-align: center;\n cursor: pointer;\n z-index: 9999999;\n }\n .ph-survey-widget-tab:hover {\n padding-bottom: 13px;\n }\n .ph-survey-widget-button {\n position: fixed;\n }\n `\n}\n","/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_URL_TRIGGER_STATUS = '$session_recording_url_trigger_status'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_STATUS = '$session_recording_event_trigger_status'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\n// These are properties that are reserved and will not be automatically included in events\nexport const PERSISTENCE_RESERVED_PROPERTIES = [\n PEOPLE_DISTINCT_ID_KEY,\n ALIAS_ID_KEY,\n CAMPAIGN_IDS_KEY,\n EVENT_TIMERS_KEY,\n SESSION_RECORDING_ENABLED_SERVER_SIDE,\n HEATMAPS_ENABLED_SERVER_SIDE,\n SESSION_ID,\n ENABLED_FEATURE_FLAGS,\n USER_STATE,\n PERSISTENCE_EARLY_ACCESS_FEATURES,\n STORED_GROUP_PROPERTIES_KEY,\n STORED_PERSON_PROPERTIES_KEY,\n SURVEYS,\n FLAG_CALL_REPORTED,\n CLIENT_SESSION_PROPS,\n CAPTURE_RATE_LIMIT,\n INITIAL_CAMPAIGN_PARAMS,\n INITIAL_REFERRER_INFO,\n ENABLE_PERSON_PROCESSING,\n]\n","import { each, isValidRegex } from './'\n\nimport { isArray, isFile, isUndefined } from './type-utils'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const isUrlMatchingRegex = function (url: string, pattern: string): boolean {\n if (!isValidRegex(pattern)) return false\n return new RegExp(pattern).test(url)\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n const queryParams: string = withoutHash.split('?')[1] || ''\n\n const queryParts = queryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","import { Breaker, EventHandler, Properties } from '../types'\nimport { hasOwnProperty, isArray, isFormData, isFunction, isNull, isNullish, isString } from './type-utils'\nimport { logger } from './logger'\nimport { nativeForEach, nativeIndexOf, window } from './globals'\n\nconst breaker: Breaker = {}\n\nexport function eachArray<E = any>(\n obj: E[] | null | undefined,\n iterator: (value: E, key: number) => void | Breaker,\n thisArg?: any\n): void {\n if (isArray(obj)) {\n if (nativeForEach && obj.forEach === nativeForEach) {\n obj.forEach(iterator, thisArg)\n } else if ('length' in obj && obj.length === +obj.length) {\n for (let i = 0, l = obj.length; i < l; i++) {\n if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {\n return\n }\n }\n }\n }\n}\n\n/**\n * @param {*=} obj\n * @param {function(...*)=} iterator\n * @param {Object=} thisArg\n */\nexport function each(obj: any, iterator: (value: any, key: any) => void | Breaker, thisArg?: any): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n return eachArray(obj, iterator, thisArg)\n }\n if (isFormData(obj)) {\n for (const pair of obj.entries()) {\n if (iterator.call(thisArg, pair[1], pair[0]) === breaker) {\n return\n }\n }\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n if (iterator.call(thisArg, obj[key], key) === breaker) {\n return\n }\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n eachArray(args, function (source) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n })\n return obj\n}\n\nexport const extendArray = function <T>(obj: T[], ...args: T[][]): T[] {\n eachArray(args, function (source) {\n eachArray(source, function (item) {\n obj.push(item)\n })\n })\n return obj\n}\n\nexport const include = function (\n obj: null | string | Array<any> | Record<string, any>,\n target: any\n): boolean | Breaker {\n let found = false\n if (isNull(obj)) {\n return found\n }\n if (nativeIndexOf && obj.indexOf === nativeIndexOf) {\n return obj.indexOf(target) != -1\n }\n each(obj, function (value) {\n if (found || (found = value === target)) {\n return breaker\n }\n return\n })\n return found\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const isValidRegex = function (str: string): boolean {\n try {\n new RegExp(str)\n } catch {\n return false\n }\n return true\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if (isString(v) && v.length > 0) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number | null\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value) && !isNull(maxStringLength)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\nexport const registerEvent = (function () {\n // written by Dean Edwards, 2005\n // with input from Tino Zijdel - crisp@xs4all.nl\n // with input from Carl Sverre - mail@carlsverre.com\n // with input from PostHog\n // http://dean.edwards.name/weblog/2005/10/add-event/\n // https://gist.github.com/1930440\n\n /**\n * @param {Object} element\n * @param {string} type\n * @param {function(...*)} handler\n * @param {boolean=} oldSchool\n * @param {boolean=} useCapture\n */\n const register_event = function (\n element: Element | Window | Document | Node,\n type: string,\n handler: EventHandler,\n oldSchool?: boolean,\n useCapture?: boolean\n ) {\n if (!element) {\n logger.error('No valid element provided to register_event')\n return\n }\n\n if (element.addEventListener && !oldSchool) {\n element.addEventListener(type, handler, !!useCapture)\n } else {\n const ontype = 'on' + type\n const old_handler = (element as any)[ontype] // can be undefined\n ;(element as any)[ontype] = makeHandler(element, handler, old_handler)\n }\n }\n\n function makeHandler(\n element: Element | Window | Document | Node,\n new_handler: EventHandler,\n old_handlers: EventHandler\n ) {\n return function (event: Event): boolean | void {\n event = event || fixEvent(window?.event)\n\n // this basically happens in firefox whenever another script\n // overwrites the onload callback and doesn't pass the event\n // object to previously defined callbacks. All the browsers\n // that don't define window.event implement addEventListener\n // so the dom_loaded handler will still be fired as usual.\n if (!event) {\n return undefined\n }\n\n let ret = true\n let old_result: any\n\n if (isFunction(old_handlers)) {\n old_result = old_handlers(event)\n }\n const new_result = new_handler.call(element, event)\n\n if (false === old_result || false === new_result) {\n ret = false\n }\n\n return ret\n }\n }\n\n function fixEvent(event: Event | undefined): Event | undefined {\n if (event) {\n event.preventDefault = fixEvent.preventDefault\n event.stopPropagation = fixEvent.stopPropagation\n }\n return event\n }\n fixEvent.preventDefault = function () {\n ;(this as any as Event).returnValue = false\n }\n fixEvent.stopPropagation = function () {\n ;(this as any as Event).cancelBubble = true\n }\n\n return register_event\n})()\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n","export class SimpleEventEmitter {\n private events: { [key: string]: ((...args: any[]) => void)[] } = {}\n\n constructor() {\n this.events = {}\n }\n\n on(event: string, listener: (...args: any[]) => void): () => void {\n if (!this.events[event]) {\n this.events[event] = []\n }\n this.events[event].push(listener)\n\n return () => {\n this.events[event] = this.events[event].filter((x) => x !== listener)\n }\n }\n\n emit(event: string, payload: any): void {\n for (const listener of this.events[event] || []) {\n listener(payload)\n }\n for (const listener of this.events['*'] || []) {\n listener(event, payload)\n }\n }\n}\n","import { PostHog } from '../../posthog-core'\nimport { ActionStepStringMatching, ActionStepType, SurveyActionType, SurveyElement } from '../../posthog-surveys-types'\nimport { SimpleEventEmitter } from '../../utils/simple-event-emitter'\nimport { CaptureResult } from '../../types'\nimport { isUndefined } from '../../utils/type-utils'\nimport { window } from '../../utils/globals'\nimport { isUrlMatchingRegex } from '../../utils/request-utils'\n\nexport class ActionMatcher {\n private readonly actionRegistry?: Set<SurveyActionType>\n private readonly instance?: PostHog\n private readonly actionEvents: Set<string>\n private _debugEventEmitter = new SimpleEventEmitter()\n\n constructor(instance?: PostHog) {\n this.instance = instance\n this.actionEvents = new Set<string>()\n this.actionRegistry = new Set<SurveyActionType>()\n }\n\n init() {\n if (!isUndefined(this.instance?._addCaptureHook)) {\n const matchEventToAction = (eventName: string, eventPayload: any) => {\n this.on(eventName, eventPayload)\n }\n this.instance?._addCaptureHook(matchEventToAction)\n }\n }\n\n register(actions: SurveyActionType[]): void {\n if (isUndefined(this.instance?._addCaptureHook)) {\n return\n }\n\n actions.forEach((action) => {\n this.actionRegistry?.add(action)\n action.steps?.forEach((step) => {\n this.actionEvents?.add(step?.event || '')\n })\n })\n\n if (this.instance?.autocapture) {\n const selectorsToWatch: Set<string> = new Set<string>()\n actions.forEach((action) => {\n action.steps?.forEach((step) => {\n if (step?.selector) {\n selectorsToWatch.add(step?.selector)\n }\n })\n })\n this.instance?.autocapture.setElementSelectors(selectorsToWatch)\n }\n }\n\n on(eventName: string, eventPayload?: CaptureResult) {\n if (eventPayload == null || eventName.length == 0) {\n return\n }\n\n if (!this.actionEvents.has(eventName) && !this.actionEvents.has(<string>eventPayload?.event)) {\n return\n }\n\n if (this.actionRegistry && this.actionRegistry?.size > 0) {\n this.actionRegistry.forEach((action) => {\n if (this.checkAction(eventPayload, action)) {\n this._debugEventEmitter.emit('actionCaptured', action.name)\n }\n })\n }\n }\n\n _addActionHook(callback: (actionName: string, eventPayload?: any) => void): void {\n this.onAction('actionCaptured', (data) => callback(data))\n }\n\n private checkAction(event?: CaptureResult, action?: SurveyActionType): boolean {\n if (action?.steps == null) {\n return false\n }\n\n for (const step of action.steps) {\n if (this.checkStep(event, step)) {\n return true\n }\n }\n\n return false\n }\n\n onAction(event: 'actionCaptured', cb: (...args: any[]) => void): () => void {\n return this._debugEventEmitter.on(event, cb)\n }\n\n private checkStep = (event?: CaptureResult, step?: ActionStepType): boolean => {\n return this.checkStepEvent(event, step) && this.checkStepUrl(event, step) && this.checkStepElement(event, step)\n }\n\n private checkStepEvent = (event?: CaptureResult, step?: ActionStepType): boolean => {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.event && event?.event !== step?.event) {\n return false // EVENT NAME IS A MISMATCH\n }\n return true\n }\n\n private checkStepUrl(event?: CaptureResult, step?: ActionStepType): boolean {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.url) {\n const eventUrl = event?.properties?.$current_url\n if (!eventUrl || typeof eventUrl !== 'string') {\n return false // URL IS UNKNOWN\n }\n if (!ActionMatcher.matchString(eventUrl, step?.url, step?.url_matching || 'contains')) {\n return false // URL IS A MISMATCH\n }\n }\n return true\n }\n\n private static matchString(url: string, pattern: string, matching: ActionStepStringMatching): boolean {\n switch (matching) {\n case 'regex':\n return !!window && isUrlMatchingRegex(url, pattern)\n case 'exact':\n return pattern === url\n case 'contains':\n // Simulating SQL LIKE behavior (_ = any single character, % = any zero or more characters)\n // eslint-disable-next-line no-case-declarations\n const adjustedRegExpStringPattern = ActionMatcher.escapeStringRegexp(pattern)\n .replace(/_/g, '.')\n .replace(/%/g, '.*')\n return isUrlMatchingRegex(url, adjustedRegExpStringPattern)\n\n default:\n return false\n }\n }\n\n private static escapeStringRegexp(pattern: string): string {\n // Escape characters with special meaning either inside or outside character sets.\n // Use a simple backslash escape when it’s always valid, and a `\\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar.\n return pattern.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d')\n }\n\n private checkStepElement(event?: CaptureResult, step?: ActionStepType): boolean {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.href || step?.tag_name || step?.text) {\n const elements = this.getElementsList(event)\n if (\n !elements.some((element) => {\n if (\n step?.href &&\n !ActionMatcher.matchString(element.href || '', step?.href, step?.href_matching || 'exact')\n ) {\n return false // ELEMENT HREF IS A MISMATCH\n }\n if (step?.tag_name && element.tag_name !== step?.tag_name) {\n return false // ELEMENT TAG NAME IS A MISMATCH\n }\n if (\n step?.text &&\n !(\n ActionMatcher.matchString(element.text || '', step?.text, step?.text_matching || 'exact') ||\n ActionMatcher.matchString(\n element.$el_text || '',\n step?.text,\n step?.text_matching || 'exact'\n )\n )\n ) {\n return false // ELEMENT TEXT IS A MISMATCH\n }\n return true\n })\n ) {\n // AT LEAST ONE ELEMENT MUST BE A SUBMATCH\n return false\n }\n }\n\n if (step?.selector) {\n const elementSelectors = event?.properties?.$element_selectors as unknown as string[]\n if (!elementSelectors) {\n return false // SELECTOR IS A MISMATCH\n }\n if (!elementSelectors.includes(step?.selector)) {\n return false // SELECTOR IS A MISMATCH\n }\n }\n\n return true\n }\n\n private getElementsList(event?: CaptureResult): SurveyElement[] {\n if (event?.properties.$elements == null) {\n return []\n }\n\n return event?.properties.$elements as unknown as SurveyElement[]\n }\n}\n","import { Survey } from '../posthog-surveys-types'\nimport { SURVEYS_ACTIVATED } from '../constants'\n\nimport { CaptureResult } from '../types'\nimport { ActionMatcher } from '../extensions/surveys/action-matcher'\nimport { PostHog } from '../posthog-core'\nimport { isUndefined } from './type-utils'\n\nexport class SurveyEventReceiver {\n // eventToSurveys is a mapping of event name to all the surveys that are activated by it\n private readonly eventToSurveys: Map<string, string[]>\n // actionToSurveys is a mapping of action name to all the surveys that are activated by it\n private readonly actionToSurveys: Map<string, string[]>\n // actionMatcher can look at CaptureResult payloads and match an event to its corresponding action.\n private actionMatcher?: ActionMatcher | null\n private readonly instance?: PostHog\n private static SURVEY_SHOWN_EVENT_NAME = 'survey shown'\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.eventToSurveys = new Map<string, string[]>()\n this.actionToSurveys = new Map<string, string[]>()\n }\n\n register(surveys: Survey[]): void {\n if (isUndefined(this.instance?._addCaptureHook)) {\n return\n }\n\n this.setupEventBasedSurveys(surveys)\n this.setupActionBasedSurveys(surveys)\n }\n\n private setupActionBasedSurveys(surveys: Survey[]) {\n const actionBasedSurveys = surveys.filter(\n (survey: Survey) => survey.conditions?.actions && survey.conditions?.actions?.values?.length > 0\n )\n\n if (actionBasedSurveys.length === 0) {\n return\n }\n\n if (this.actionMatcher == null) {\n this.actionMatcher = new ActionMatcher(this.instance)\n this.actionMatcher.init()\n // match any actions to its corresponding survey.\n const matchActionToSurvey = (actionName: string) => {\n this.onAction(actionName)\n }\n\n this.actionMatcher._addActionHook(matchActionToSurvey)\n }\n\n actionBasedSurveys.forEach((survey) => {\n if (\n survey.conditions &&\n survey.conditions?.actions &&\n survey.conditions?.actions?.values &&\n survey.conditions?.actions?.values?.length > 0\n ) {\n // register the known set of actions with\n // the action-matcher so it can match\n // events to actions\n this.actionMatcher?.register(survey.conditions.actions.values)\n\n // maintain a mapping of (Action1) => [Survey1, Survey2, Survey3]\n // where Surveys 1-3 are all activated by Action1\n survey.conditions?.actions?.values?.forEach((action) => {\n if (action && action.name) {\n const knownSurveys: string[] | undefined = this.actionToSurveys.get(action.name)\n if (knownSurveys) {\n knownSurveys.push(survey.id)\n }\n this.actionToSurveys.set(action.name, knownSurveys || [survey.id])\n }\n })\n }\n })\n }\n\n private setupEventBasedSurveys(surveys: Survey[]) {\n const eventBasedSurveys = surveys.filter(\n (survey: Survey) => survey.conditions?.events && survey.conditions?.events?.values?.length > 0\n )\n\n if (eventBasedSurveys.length === 0) {\n return\n }\n\n // match any events to its corresponding survey.\n const matchEventToSurvey = (eventName: string, eventPayload?: CaptureResult) => {\n this.onEvent(eventName, eventPayload)\n }\n this.instance?._addCaptureHook(matchEventToSurvey)\n\n surveys.forEach((survey) => {\n // maintain a mapping of (Event1) => [Survey1, Survey2, Survey3]\n // where Surveys 1-3 are all activated by Event1\n survey.conditions?.events?.values?.forEach((event) => {\n if (event && event.name) {\n const knownSurveys: string[] | undefined = this.eventToSurveys.get(event.name)\n if (knownSurveys) {\n knownSurveys.push(survey.id)\n }\n this.eventToSurveys.set(event.name, knownSurveys || [survey.id])\n }\n })\n })\n }\n\n onEvent(event: string, eventPayload?: CaptureResult): void {\n const existingActivatedSurveys: string[] = this.instance?.persistence?.props[SURVEYS_ACTIVATED] || []\n if (\n SurveyEventReceiver.SURVEY_SHOWN_EVENT_NAME == event &&\n eventPayload &&\n existingActivatedSurveys.length > 0\n ) {\n // remove survey that from activatedSurveys here.\n const surveyId = eventPayload?.properties?.$survey_id\n if (surveyId) {\n const index = existingActivatedSurveys.indexOf(surveyId)\n if (index >= 0) {\n existingActivatedSurveys.splice(index, 1)\n this._updateActivatedSurveys(existingActivatedSurveys)\n }\n }\n } else {\n if (this.eventToSurveys.has(event)) {\n this._updateActivatedSurveys(existingActivatedSurveys.concat(this.eventToSurveys.get(event) || []))\n }\n }\n }\n\n onAction(actionName: string): void {\n const existingActivatedSurveys: string[] = this.instance?.persistence?.props[SURVEYS_ACTIVATED] || []\n if (this.actionToSurveys.has(actionName)) {\n this._updateActivatedSurveys(existingActivatedSurveys.concat(this.actionToSurveys.get(actionName) || []))\n }\n }\n\n private _updateActivatedSurveys(activatedSurveys: string[]) {\n // we use a new Set here to remove duplicates.\n this.instance?.persistence?.register({\n [SURVEYS_ACTIVATED]: [...new Set(activatedSurveys)],\n })\n }\n\n getSurveys(): string[] {\n const existingActivatedSurveys = this.instance?.persistence?.props[SURVEYS_ACTIVATED]\n return existingActivatedSurveys ? existingActivatedSurveys : []\n }\n\n getEventToSurveys(): Map<string, string[]> {\n return this.eventToSurveys\n }\n\n _getActionMatcher(): ActionMatcher | null | undefined {\n return this.actionMatcher\n }\n}\n","import { SURVEYS } from './constants'\nimport { getSurveySeenStorageKeys } from './extensions/surveys/surveys-utils'\nimport { PostHog } from './posthog-core'\nimport {\n Survey,\n SurveyCallback,\n SurveyQuestionBranchingType,\n SurveyQuestionType,\n SurveyUrlMatchType,\n} from './posthog-surveys-types'\nimport { RemoteConfig } from './types'\nimport { assignableWindow, document, window } from './utils/globals'\nimport { createLogger } from './utils/logger'\nimport { isUrlMatchingRegex } from './utils/request-utils'\nimport { SurveyEventReceiver } from './utils/survey-event-receiver'\nimport { isNullish } from './utils/type-utils'\n\nconst logger = createLogger('[Surveys]')\n\nexport const surveyUrlValidationMap: Record<SurveyUrlMatchType, (conditionsUrl: string) => boolean> = {\n icontains: (conditionsUrl) =>\n !!window && window.location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) > -1,\n not_icontains: (conditionsUrl) =>\n !!window && window.location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) === -1,\n regex: (conditionsUrl) => !!window && isUrlMatchingRegex(window.location.href, conditionsUrl),\n not_regex: (conditionsUrl) => !!window && !isUrlMatchingRegex(window.location.href, conditionsUrl),\n exact: (conditionsUrl) => window?.location.href === conditionsUrl,\n is_not: (conditionsUrl) => window?.location.href !== conditionsUrl,\n}\n\nfunction getRatingBucketForResponseValue(responseValue: number, scale: number) {\n if (scale === 3) {\n if (responseValue < 1 || responseValue > 3) {\n throw new Error('The response must be in range 1-3')\n }\n\n return responseValue === 1 ? 'negative' : responseValue === 2 ? 'neutral' : 'positive'\n } else if (scale === 5) {\n if (responseValue < 1 || responseValue > 5) {\n throw new Error('The response must be in range 1-5')\n }\n\n return responseValue <= 2 ? 'negative' : responseValue === 3 ? 'neutral' : 'positive'\n } else if (scale === 7) {\n if (responseValue < 1 || responseValue > 7) {\n throw new Error('The response must be in range 1-7')\n }\n\n return responseValue <= 3 ? 'negative' : responseValue === 4 ? 'neutral' : 'positive'\n } else if (scale === 10) {\n if (responseValue < 0 || responseValue > 10) {\n throw new Error('The response must be in range 0-10')\n }\n\n return responseValue <= 6 ? 'detractors' : responseValue <= 8 ? 'passives' : 'promoters'\n }\n\n throw new Error('The scale must be one of: 3, 5, 7, 10')\n}\n\nexport function getNextSurveyStep(\n survey: Survey,\n currentQuestionIndex: number,\n response: string | string[] | number | null\n) {\n const question = survey.questions[currentQuestionIndex]\n const nextQuestionIndex = currentQuestionIndex + 1\n\n if (!question.branching?.type) {\n if (currentQuestionIndex === survey.questions.length - 1) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n\n if (question.branching.type === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n } else if (question.branching.type === SurveyQuestionBranchingType.SpecificQuestion) {\n if (Number.isInteger(question.branching.index)) {\n return question.branching.index\n }\n } else if (question.branching.type === SurveyQuestionBranchingType.ResponseBased) {\n // Single choice\n if (question.type === SurveyQuestionType.SingleChoice) {\n // :KLUDGE: for now, look up the choiceIndex based on the response\n // TODO: once QuestionTypes.MultipleChoiceQuestion is refactored, pass the selected choiceIndex into this method\n const selectedChoiceIndex = question.choices.indexOf(`${response}`)\n\n if (question.branching?.responseValues?.hasOwnProperty(selectedChoiceIndex)) {\n const nextStep = question.branching.responseValues[selectedChoiceIndex]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n } else if (question.type === SurveyQuestionType.Rating) {\n if (typeof response !== 'number' || !Number.isInteger(response)) {\n throw new Error('The response type must be an integer')\n }\n\n const ratingBucket = getRatingBucketForResponseValue(response, question.scale)\n\n if (question.branching?.responseValues?.hasOwnProperty(ratingBucket)) {\n const nextStep = question.branching.responseValues[ratingBucket]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n }\n\n return nextQuestionIndex\n }\n\n logger.warn('Falling back to next question index due to unexpected branching type')\n return nextQuestionIndex\n}\n\nexport class PostHogSurveys {\n private _decideServerResponse?: boolean\n public _surveyEventReceiver: SurveyEventReceiver | null\n private _surveyManager: any\n\n constructor(private readonly instance: PostHog) {\n // we set this to undefined here because we need the persistence storage for this type\n // but that's not initialized until loadIfEnabled is called.\n this._surveyEventReceiver = null\n }\n\n onRemoteConfig(response: RemoteConfig) {\n this._decideServerResponse = !!response['surveys']\n logger.info(`decideServerResponse set to ${this._decideServerResponse}`)\n\n this.loadIfEnabled()\n }\n\n reset(): void {\n localStorage.removeItem('lastSeenSurveyDate')\n const surveyKeys = getSurveySeenStorageKeys()\n surveyKeys.forEach((key) => localStorage.removeItem(key))\n }\n\n loadIfEnabled() {\n if (this._surveyManager) {\n // Surveys already loaded.\n return\n }\n\n const disableSurveys = this.instance.config.disable_surveys\n\n if (disableSurveys) {\n logger.info('Disabled. Not loading surveys.')\n return\n }\n\n const phExtensions = assignableWindow?.__PosthogExtensions__\n\n if (!phExtensions) {\n logger.error('PostHog Extensions not found.')\n return\n }\n\n const generateSurveys = phExtensions.generateSurveys\n\n if (!this._decideServerResponse) {\n logger.warn('Decide not loaded yet. Not loading surveys.')\n return\n }\n\n if (this._surveyEventReceiver == null) {\n this._surveyEventReceiver = new SurveyEventReceiver(this.instance)\n }\n\n if (!generateSurveys) {\n const loadExternalDependency = phExtensions.loadExternalDependency\n\n if (loadExternalDependency) {\n loadExternalDependency(this.instance, 'surveys', (err) => {\n if (err) {\n logger.error('Could not load surveys script', err)\n return\n }\n\n this._surveyManager = phExtensions.generateSurveys?.(this.instance)\n })\n } else {\n logger.error('PostHog loadExternalDependency extension not found. Cannot load remote config.')\n }\n } else {\n this._surveyManager = generateSurveys(this.instance)\n }\n }\n\n getSurveys(callback: SurveyCallback, forceReload = false) {\n // In case we manage to load the surveys script, but config says not to load surveys\n // then we shouldn't return survey data\n if (this.instance.config.disable_surveys) {\n logger.info('Disabled. Not loading surveys.')\n\n return callback([])\n }\n\n if (this._surveyEventReceiver == null) {\n this._surveyEventReceiver = new SurveyEventReceiver(this.instance)\n }\n\n const existingSurveys = this.instance.get_property(SURVEYS)\n\n if (!existingSurveys || forceReload) {\n this.instance._send_request({\n url: this.instance.requestRouter.endpointFor(\n 'api',\n `/api/surveys/?token=${this.instance.config.token}`\n ),\n method: 'GET',\n callback: (response) => {\n const statusCode = response.statusCode\n if (statusCode !== 200 || !response.json) {\n logger.error(`Surveys API could not be loaded, status: ${statusCode}`)\n return callback([])\n }\n const surveys = response.json.surveys || []\n\n const eventOrActionBasedSurveys = surveys.filter(\n (survey: Survey) =>\n (survey.conditions?.events &&\n survey.conditions?.events?.values &&\n survey.conditions?.events?.values?.length > 0) ||\n (survey.conditions?.actions &&\n survey.conditions?.actions?.values &&\n survey.conditions?.actions?.values?.length > 0)\n )\n\n if (eventOrActionBasedSurveys.length > 0) {\n this._surveyEventReceiver?.register(eventOrActionBasedSurveys)\n }\n\n this.instance.persistence?.register({ [SURVEYS]: surveys })\n return callback(surveys)\n },\n })\n } else {\n logger.info('Surveys already loaded, using existing data.')\n return callback(existingSurveys)\n }\n }\n\n getActiveMatchingSurveys(callback: SurveyCallback, forceReload = false) {\n this.getSurveys((surveys) => {\n const activeSurveys = surveys.filter((survey) => {\n return !!(survey.start_date && !survey.end_date)\n })\n\n const conditionMatchedSurveys = activeSurveys.filter((survey) => {\n if (!survey.conditions) {\n return true\n }\n\n // use urlMatchType to validate url condition, fallback to contains for backwards compatibility\n const urlCheck = survey.conditions?.url\n ? surveyUrlValidationMap[survey.conditions?.urlMatchType ?? 'icontains'](survey.conditions.url)\n : true\n const selectorCheck = survey.conditions?.selector\n ? document?.querySelector(survey.conditions.selector)\n : true\n return urlCheck && selectorCheck\n })\n\n // get all the surveys that have been activated so far with user actions.\n const activatedSurveys: string[] | undefined = this._surveyEventReceiver?.getSurveys()\n const targetingMatchedSurveys = conditionMatchedSurveys.filter((survey) => {\n if (\n !survey.linked_flag_key &&\n !survey.targeting_flag_key &&\n !survey.internal_targeting_flag_key &&\n !survey.feature_flag_keys?.length\n ) {\n return true\n }\n const linkedFlagCheck = survey.linked_flag_key\n ? this.instance.featureFlags.isFeatureEnabled(survey.linked_flag_key)\n : true\n const targetingFlagCheck = survey.targeting_flag_key\n ? this.instance.featureFlags.isFeatureEnabled(survey.targeting_flag_key)\n : true\n\n const hasEvents =\n survey.conditions?.events &&\n survey.conditions?.events?.values &&\n survey.conditions?.events?.values.length > 0\n\n const hasActions =\n survey.conditions?.actions &&\n survey.conditions?.actions?.values &&\n survey.conditions?.actions?.values.length > 0\n const eventBasedTargetingFlagCheck =\n hasEvents || hasActions ? activatedSurveys?.includes(survey.id) : true\n\n const overrideInternalTargetingFlagCheck = this._canActivateRepeatedly(survey)\n const internalTargetingFlagCheck =\n survey.internal_targeting_flag_key && !overrideInternalTargetingFlagCheck\n ? this.instance.featureFlags.isFeatureEnabled(survey.internal_targeting_flag_key)\n : true\n const flagsCheck = this.checkFlags(survey)\n return (\n linkedFlagCheck &&\n targetingFlagCheck &&\n internalTargetingFlagCheck &&\n eventBasedTargetingFlagCheck &&\n flagsCheck\n )\n })\n\n return callback(targetingMatchedSurveys)\n }, forceReload)\n }\n\n checkFlags(survey: Survey): boolean {\n if (!survey.feature_flag_keys?.length) {\n return true\n }\n\n return survey.feature_flag_keys.every(({ key, value }) => {\n if (!key || !value) {\n return true\n }\n return this.instance.featureFlags.isFeatureEnabled(value)\n })\n }\n getNextSurveyStep = getNextSurveyStep\n\n // this method is lazily loaded onto the window to avoid loading preact and other dependencies if surveys is not enabled\n private _canActivateRepeatedly(survey: Survey) {\n if (isNullish(assignableWindow.__PosthogExtensions__?.canActivateRepeatedly)) {\n logger.warn('init was not called')\n return false // TODO does it make sense to have a default here?\n }\n return assignableWindow.__PosthogExtensions__.canActivateRepeatedly(survey)\n }\n\n canRenderSurvey(surveyId: string) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n this.getSurveys((surveys) => {\n const survey = surveys.filter((x) => x.id === surveyId)[0]\n this._surveyManager.canRenderSurvey(survey)\n })\n }\n\n renderSurvey(surveyId: string, selector: string) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n this.getSurveys((surveys) => {\n const survey = surveys.filter((x) => x.id === surveyId)[0]\n this._surveyManager.renderSurvey(survey, document?.querySelector(selector))\n })\n }\n}\n"],"names":["SurveyType","SurveyQuestionType","SurveyQuestionBranchingType","EMPTY_OBJ","EMPTY_ARR","IS_NON_DIMENSIONAL","__u","currentIndex","currentComponent","previousComponent","prevRaf","currentHook","afterPaintEffects","EMPTY","oldBeforeDiff","options","__b","oldBeforeRender","__r","oldAfterDiff","diffed","oldCommit","__c","oldBeforeUnmount","unmount","getHookState","index","type","__h","hooks","__H","__","length","push","__V","useState","initialState","useReducer","reducer","init","hookState","_reducer","invokeOrReturn","undefined","n","currentValue","__N","nextValue","action","setState","_hasScuFromHooks","updateHookState","f","p","s","c","stateHooks","filter","x","every","prevScu","call","this","shouldUpdate","forEach","hookItem","props","shouldComponentUpdate","prevCWU","componentWillUpdate","__e","tmp","useEffect","callback","args","state","__s","argsChanged","_pendingArgs","useRef","initialValue","useMemo","current","factory","useContext","context","provider","sub","value","flushAfterPaintEffects","component","shift","__P","invokeCleanup","invokeEffect","e","__v","vnode","t","requestAnimationFrame","afterNextFrame","commitQueue","some","cb","hasErrored","HAS_RAF","raf","done","clearTimeout","timeout","cancelAnimationFrame","setTimeout","hook","comp","cleanup","oldArgs","newArgs","arg","win","window","global","globalThis","navigator","document","location","fetch","XMLHttpRequest","AbortController","userAgent","Compression","assignableWindow","nativeIsArray","Array","isArray","toString","Object","prototype","obj","isUndefined","isNull","isNumber","_createLogger","prefix","logger","_log","level","console","consoleLog","_len","arguments","_key","info","_len2","_key2","warn","_len3","_key3","error","_len4","_key4","critical","_len5","_key5","uninitializedWarning","methodName","concat","createLogger","additionalPrefix","_window","SurveySeenPrefix","hex2rgb","hexColor","replace","parseInt","slice","getContrastingTextColor","rgb","color","defaultBackgroundColor","startsWith","nameColorToHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","honeydew","hotpink","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","toLowerCase","colorMatch","match","r","g","b","Math","sqrt","defaultSurveyAppearance","backgroundColor","submitButtonColor","submitButtonTextColor","ratingButtonColor","ratingButtonActiveColor","borderColor","placeholder","whiteLabel","displayThankYouMessage","thankYouMessageHeader","position","sendSurveyEvent","_posthog$get_session_","responses","survey","posthog","localStorage","setItem","getSurveySeenKey","capture","_objectSpread","$survey_name","name","$survey_id","id","$survey_iteration","current_iteration","$survey_iteration_start_date","current_iteration_start_date","$survey_questions","questions","map","question","sessionRecordingUrl","get_session_replay_url","$set","getSurveyInteractionProperty","dispatchEvent","Event","dismissedSurveyEvent","readOnly","_posthog$get_session_2","shuffle","array","a","sort","floor","random","reverseIfUnshuffled","unshuffled","shuffled","val","reverse","getDisplayOrderQuestions","idx","originalQuestionIndex","appearance","shuffleQuestions","surveySeenKey","surveyProperty","SurveyContext","createContext","isPreviewMode","previewPageIndex","handleCloseSurveyPopup","isPopup","onPreviewSubmit","renderChildrenAsTextOrHtml","_ref","children","renderAsHtml","style","cloneElement","dangerouslySetInnerHTML","__html","satisfiedEmoji","_jsx","className","xmlns","height","viewBox","width","d","neutralEmoji","dissatisfiedEmoji","veryDissatisfiedEmoji","verySatisfiedEmoji","cancelSVG","fill","IconPosthogLogo","_jsxs","maskType","maskUnits","y","mask","transform","checkSVG","PostHogLogo","href","target","rel","BottomSection","text","submitDisabled","onSubmit","link","textColor","disabled","onClick","open","QuestionHeader","description","descriptionContentType","forceDisableHtml","h","Cancel","_ref2","ConfirmationMessage","header","contentType","onClose","styleOverrides","_Fragment","thankYouMessageCloseButtonText","useContrastingTextColor","_options$defaultTextC","ref","setTextColor","defaultTextColor","el","getComputedStyle","getTextColor","forceUpdate","OpenTextQuestion","textRef","setText","rows","onInput","currentTarget","buttonText","optional","LinkQuestion","RatingQuestion","_ref3","displayQuestionIndex","scale","starting","rating","setRating","display","threeScaleEmojis","fiveScaleEmojis","emoji","active","gridTemplateColumns","getScaleNumbers","number","RatingButton","num","setActiveNumber","lowerBoundLabel","upperBoundLabel","submitButtonText","_ref4","MultipleChoiceQuestion","_ref5","choices","shuffleOptions","displayOrderChoices","openEndedChoice","hasOpenChoice","pop","shuffledOptions","getDisplayOrderChoices","selectedChoices","setSelectedChoices","MultipleChoice","openChoiceSelected","setOpenChoiceSelected","openEndedInput","setOpenEndedInput","inputType","SingleChoice","choice","choiceClass","option","includes","htmlFor","userValue","fiveScaleNumbers","sevenScaleNumbers","tenScaleNumbers","_document","renderSurveysPreview","_survey$appearance5","_survey$appearance6","parentElement","surveyStyleSheet","fontFamily","maxWidth","zIndex","left","right","center","styleElement","assign","createElement","innerText","from","child","HTMLStyleElement","removeChild","appendChild","Preact","SurveyPopup","borderBottom","borderRadius","removeSurveyFromFocus","renderFeedbackWidgetPreview","_survey$appearance7","widgetColor","root","widgetStyleSheet","FeedbackWidget","_survey$appearance10","_style","_style2","_survey$appearance11","_survey$appearance12","_survey$appearance13","Number","isInteger","surveyPopupDelayMilliseconds","surveyPopupDelaySeconds","isPopupVisible","isSurveySent","setIsPopupVisible","millisecondDelay","setIsSurveySent","timeoutId","handleSurveyClosed","handleSurveySent","_survey$appearance8","_survey$appearance9","autoDisappear","showSurvey","Date","toISOString","addEventListener","removeEventListener","usePopupVisibility","shouldShowConfirmation","confirmationBoxLeftStyle","Provider","thankYouMessageDescription","thankYouMessageDescriptionContentType","Questions","_survey$appearance14","_survey$appearance15","questionsResponses","setQuestionsResponses","currentQuestionIndex","setCurrentQuestionIndex","surveyQuestions","_survey$appearance16","getQuestionComponent","res","responseKey","getNextSurveyStep","nextStep","End","onNextButtonClick","_ref6","_survey$appearance20","_survey$appearance21","setShowSurvey","setStyle","widgetRef","_survey$appearance17","_survey$appearance19","widgetType","_survey$appearance18","widgetPos","getBoundingClientRect","top","bottom","widget","querySelector","widgetSelector","setAttribute","widgetLabel","_ref7","questionComponents","Open","Link","Rating","commonProps","additionalProps","Component","componentProps","SURVEYS_ACTIVATED","isUrlMatchingRegex","url","pattern","str","RegExp","_unused","isValidRegex","test","SimpleEventEmitter","constructor","_defineProperty","events","on","event","listener","emit","payload","ActionMatcher","instance","step","checkStepEvent","checkStepUrl","checkStepElement","actionEvents","Set","actionRegistry","_this$instance","_addCaptureHook","_this$instance2","matchEventToAction","eventName","eventPayload","register","actions","_this$instance3","_this$instance4","_this$actionRegistry","_action$steps","add","steps","_this$actionEvents","autocapture","_this$instance5","selectorsToWatch","_action$steps2","selector","setElementSelectors","_this$actionRegistry2","has","size","checkAction","_debugEventEmitter","_addActionHook","onAction","data","checkStep","_event$properties","eventUrl","properties","$current_url","matchString","url_matching","matching","adjustedRegExpStringPattern","escapeStringRegexp","tag_name","getElementsList","element","href_matching","text_matching","$el_text","_event$properties2","elementSelectors","$element_selectors","$elements","SurveyEventReceiver","eventToSurveys","Map","actionToSurveys","surveys","setupEventBasedSurveys","setupActionBasedSurveys","actionBasedSurveys","_survey$conditions","_survey$conditions2","_survey$conditions2$a","_survey$conditions2$a2","conditions","values","actionMatcher","actionName","_survey$conditions3","_survey$conditions4","_survey$conditions4$a","_survey$conditions5","_survey$conditions5$a","_survey$conditions5$a2","_this$actionMatcher","_survey$conditions6","_survey$conditions6$a","_survey$conditions6$a2","knownSurveys","get","set","_survey$conditions7","_survey$conditions8","_survey$conditions8$e","_survey$conditions8$e2","matchEventToSurvey","onEvent","_survey$conditions9","_survey$conditions9$e","_survey$conditions9$e2","_this$instance3$persi","existingActivatedSurveys","persistence","SURVEY_SHOWN_EVENT_NAME","_eventPayload$propert","surveyId","indexOf","splice","_updateActivatedSurveys","_this$instance4$persi","activatedSurveys","_this$instance5$persi","getSurveys","_this$instance6","_this$instance6$persi","getEventToSurveys","_getActionMatcher","response","_question$branching","nextQuestionIndex","branching","SpecificQuestion","ResponseBased","_question$branching2","_question$branching2$","selectedChoiceIndex","responseValues","hasOwnProperty","_question$branching3","_question$branching3$","Error","ratingBucket","responseValue","getRatingBucketForResponseValue"],"mappings":"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","x_google_ignoreList":[1,2]}
1
+ {"version":3,"file":"surveys-preview.js","sources":["../src/constants.ts","../node_modules/.pnpm/preact@10.19.3/node_modules/preact/dist/preact.module.js","../src/utils/globals.ts","../src/types.ts","../src/utils/type-utils.ts","../src/utils/logger.ts","../src/extensions/surveys/surveys-utils.tsx","../src/posthog-surveys-types.ts","../src/utils/index.ts","../src/utils/request-utils.ts","../src/utils/simple-event-emitter.ts","../src/extensions/surveys/action-matcher.ts","../src/utils/survey-event-receiver.ts","../src/posthog-surveys.ts","../node_modules/.pnpm/preact@10.19.3/node_modules/preact/hooks/dist/hooks.module.js","../src/extensions/surveys/icons.tsx","../src/extensions/surveys/components/PostHogLogo.tsx","../src/extensions/surveys/components/BottomSection.tsx","../src/extensions/surveys/components/QuestionHeader.tsx","../src/extensions/surveys/components/ConfirmationMessage.tsx","../src/extensions/surveys/hooks/useContrastingTextColor.ts","../src/extensions/surveys/components/QuestionTypes.tsx","../src/extensions/surveys.tsx","../src/extensions/surveys-widget.ts"],"sourcesContent":["/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_URL_TRIGGER_STATUS = '$session_recording_url_trigger_status'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_STATUS = '$session_recording_event_trigger_status'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\n// These are properties that are reserved and will not be automatically included in events\nexport const PERSISTENCE_RESERVED_PROPERTIES = [\n PEOPLE_DISTINCT_ID_KEY,\n ALIAS_ID_KEY,\n CAMPAIGN_IDS_KEY,\n EVENT_TIMERS_KEY,\n SESSION_RECORDING_ENABLED_SERVER_SIDE,\n HEATMAPS_ENABLED_SERVER_SIDE,\n SESSION_ID,\n ENABLED_FEATURE_FLAGS,\n USER_STATE,\n PERSISTENCE_EARLY_ACCESS_FEATURES,\n STORED_GROUP_PROPERTIES_KEY,\n STORED_PERSON_PROPERTIES_KEY,\n SURVEYS,\n FLAG_CALL_REPORTED,\n CLIENT_SESSION_PROPS,\n CAPTURE_RATE_LIMIT,\n INITIAL_CAMPAIGN_PARAMS,\n INITIAL_REFERRER_INFO,\n ENABLE_PERSON_PROCESSING,\n]\n","var n,l,u,t,i,o,r,f,e,c={},s=[],a=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,h=Array.isArray;function v(n,l){for(var u in l)n[u]=l[u];return n}function p(n){var l=n.parentNode;l&&l.removeChild(n)}function y(l,u,t){var i,o,r,f={};for(r in u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return d(l,f,i,o,null)}function d(n,t,i,o,r){var f={type:n,props:t,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,constructor:void 0,__v:null==r?++u:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(f),f}function _(){return{current:null}}function g(n){return n.children}function b(n,l){this.props=n,this.context=l}function m(n,l){if(null==l)return n.__?m(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?m(n):null}function k(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k(n)}}function w(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!x.__r++||o!==l.debounceRendering)&&((o=l.debounceRendering)||r)(x)}function x(){var n,u,t,o,r,e,c,s,a;for(i.sort(f);n=i.shift();)n.__d&&(u=i.length,o=void 0,e=(r=(t=n).__v).__e,s=[],a=[],(c=t.__P)&&((o=v({},r)).__v=r.__v+1,l.vnode&&l.vnode(o),L(c,o,r,t.__n,void 0!==c.ownerSVGElement,32&r.__u?[e]:null,s,null==e?m(r):e,!!(32&r.__u),a),o.__.__k[o.__i]=o,M(s,o,a),o.__e!=e&&k(o)),i.length>u&&i.sort(f));x.__r=0}function C(n,l,u,t,i,o,r,f,e,a,h){var v,p,y,d,_,g=t&&t.__k||s,b=l.length;for(u.__d=e,P(u,l,g),e=u.__d,v=0;v<b;v++)null!=(y=u.__k[v])&&\"boolean\"!=typeof y&&\"function\"!=typeof y&&(p=-1===y.__i?c:g[y.__i]||c,y.__i=v,L(n,y,p,i,o,r,f,e,a,h),d=y.__e,y.ref&&p.ref!=y.ref&&(p.ref&&z(p.ref,null,y),h.push(y.ref,y.__c||d,y)),null==_&&null!=d&&(_=d),65536&y.__u||p.__k===y.__k?e=S(y,e,n):\"function\"==typeof y.type&&void 0!==y.__d?e=y.__d:d&&(e=d.nextSibling),y.__d=void 0,y.__u&=-196609);u.__d=e,u.__e=_}function P(n,l,u){var t,i,o,r,f,e=l.length,c=u.length,s=c,a=0;for(n.__k=[],t=0;t<e;t++)null!=(i=n.__k[t]=null==(i=l[t])||\"boolean\"==typeof i||\"function\"==typeof i?null:\"string\"==typeof i||\"number\"==typeof i||\"bigint\"==typeof i||i.constructor==String?d(null,i,null,null,i):h(i)?d(g,{children:i},null,null,null):void 0===i.constructor&&i.__b>0?d(i.type,i.props,i.key,i.ref?i.ref:null,i.__v):i)?(i.__=n,i.__b=n.__b+1,f=H(i,u,r=t+a,s),i.__i=f,o=null,-1!==f&&(s--,(o=u[f])&&(o.__u|=131072)),null==o||null===o.__v?(-1==f&&a--,\"function\"!=typeof i.type&&(i.__u|=65536)):f!==r&&(f===r+1?a++:f>r?s>e-r?a+=f-r:a--:a=f<r&&f==r-1?f-r:0,f!==t+a&&(i.__u|=65536))):(o=u[t])&&null==o.key&&o.__e&&(o.__e==n.__d&&(n.__d=m(o)),N(o,o,!1),u[t]=null,s--);if(s)for(t=0;t<c;t++)null!=(o=u[t])&&0==(131072&o.__u)&&(o.__e==n.__d&&(n.__d=m(o)),N(o,o))}function S(n,l,u){var t,i;if(\"function\"==typeof n.type){for(t=n.__k,i=0;t&&i<t.length;i++)t[i]&&(t[i].__=n,l=S(t[i],l,u));return l}return n.__e!=l&&(u.insertBefore(n.__e,l||null),l=n.__e),l&&l.nextSibling}function $(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(h(n)?n.some(function(n){$(n,l)}):l.push(n)),l}function H(n,l,u,t){var i=n.key,o=n.type,r=u-1,f=u+1,e=l[u];if(null===e||e&&i==e.key&&o===e.type)return u;if(t>(null!=e&&0==(131072&e.__u)?1:0))for(;r>=0||f<l.length;){if(r>=0){if((e=l[r])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return r;r--}if(f<l.length){if((e=l[f])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return f;f++}}return-1}function I(n,l,u){\"-\"===l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||a.test(l)?u:u+\"px\"}function T(n,l,u,t,i){var o;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof t&&(n.style.cssText=t=\"\"),t)for(l in t)u&&l in u||I(n.style,l,\"\");if(u)for(l in u)t&&u[l]===t[l]||I(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])o=l!==(l=l.replace(/(PointerCapture)$|Capture$/,\"$1\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?t?u.u=t.u:(u.u=Date.now(),n.addEventListener(l,o?D:A,o)):n.removeEventListener(l,o?D:A,o);else{if(i)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!==l&&\"height\"!==l&&\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&\"rowSpan\"!==l&&\"colSpan\"!==l&&\"role\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&\"-\"!==l[4]?n.removeAttribute(l):n.setAttribute(l,u))}}function A(n){var u=this.l[n.type+!1];if(n.t){if(n.t<=u.u)return}else n.t=Date.now();return u(l.event?l.event(n):n)}function D(n){return this.l[n.type+!0](l.event?l.event(n):n)}function L(n,u,t,i,o,r,f,e,c,s){var a,p,y,d,_,m,k,w,x,P,S,$,H,I,T,A=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),r=[e=u.__e=t.__e]),(a=l.__b)&&a(u);n:if(\"function\"==typeof A)try{if(w=u.props,x=(a=A.contextType)&&i[a.__c],P=a?x?x.props.value:a.__:i,t.__c?k=(p=u.__c=t.__c).__=p.__E:(\"prototype\"in A&&A.prototype.render?u.__c=p=new A(w,P):(u.__c=p=new b(w,P),p.constructor=A,p.render=O),x&&x.sub(p),p.props=w,p.state||(p.state={}),p.context=P,p.__n=i,y=p.__d=!0,p.__h=[],p._sb=[]),null==p.__s&&(p.__s=p.state),null!=A.getDerivedStateFromProps&&(p.__s==p.state&&(p.__s=v({},p.__s)),v(p.__s,A.getDerivedStateFromProps(w,p.__s))),d=p.props,_=p.state,p.__v=u,y)null==A.getDerivedStateFromProps&&null!=p.componentWillMount&&p.componentWillMount(),null!=p.componentDidMount&&p.__h.push(p.componentDidMount);else{if(null==A.getDerivedStateFromProps&&w!==d&&null!=p.componentWillReceiveProps&&p.componentWillReceiveProps(w,P),!p.__e&&(null!=p.shouldComponentUpdate&&!1===p.shouldComponentUpdate(w,p.__s,P)||u.__v===t.__v)){for(u.__v!==t.__v&&(p.props=w,p.state=p.__s,p.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.forEach(function(n){n&&(n.__=u)}),S=0;S<p._sb.length;S++)p.__h.push(p._sb[S]);p._sb=[],p.__h.length&&f.push(p);break n}null!=p.componentWillUpdate&&p.componentWillUpdate(w,p.__s,P),null!=p.componentDidUpdate&&p.__h.push(function(){p.componentDidUpdate(d,_,m)})}if(p.context=P,p.props=w,p.__P=n,p.__e=!1,$=l.__r,H=0,\"prototype\"in A&&A.prototype.render){for(p.state=p.__s,p.__d=!1,$&&$(u),a=p.render(p.props,p.state,p.context),I=0;I<p._sb.length;I++)p.__h.push(p._sb[I]);p._sb=[]}else do{p.__d=!1,$&&$(u),a=p.render(p.props,p.state,p.context),p.state=p.__s}while(p.__d&&++H<25);p.state=p.__s,null!=p.getChildContext&&(i=v(v({},i),p.getChildContext())),y||null==p.getSnapshotBeforeUpdate||(m=p.getSnapshotBeforeUpdate(d,_)),C(n,h(T=null!=a&&a.type===g&&null==a.key?a.props.children:a)?T:[T],u,t,i,o,r,f,e,c,s),p.base=u.__e,u.__u&=-161,p.__h.length&&f.push(p),k&&(p.__E=p.__=null)}catch(n){u.__v=null,c||null!=r?(u.__e=e,u.__u|=c?160:32,r[r.indexOf(e)]=null):(u.__e=t.__e,u.__k=t.__k),l.__e(n,u,t)}else null==r&&u.__v===t.__v?(u.__k=t.__k,u.__e=t.__e):u.__e=j(t.__e,u,t,i,o,r,f,c,s);(a=l.diffed)&&a(u)}function M(n,u,t){u.__d=void 0;for(var i=0;i<t.length;i++)z(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function j(l,u,t,i,o,r,f,e,s){var a,v,y,d,_,g,b,k=t.props,w=u.props,x=u.type;if(\"svg\"===x&&(o=!0),null!=r)for(a=0;a<r.length;a++)if((_=r[a])&&\"setAttribute\"in _==!!x&&(x?_.localName===x:3===_.nodeType)){l=_,r[a]=null;break}if(null==l){if(null===x)return document.createTextNode(w);l=o?document.createElementNS(\"http://www.w3.org/2000/svg\",x):document.createElement(x,w.is&&w),r=null,e=!1}if(null===x)k===w||e&&l.data===w||(l.data=w);else{if(r=r&&n.call(l.childNodes),k=t.props||c,!e&&null!=r)for(k={},a=0;a<l.attributes.length;a++)k[(_=l.attributes[a]).name]=_.value;for(a in k)_=k[a],\"children\"==a||(\"dangerouslySetInnerHTML\"==a?y=_:\"key\"===a||a in w||T(l,a,null,_,o));for(a in w)_=w[a],\"children\"==a?d=_:\"dangerouslySetInnerHTML\"==a?v=_:\"value\"==a?g=_:\"checked\"==a?b=_:\"key\"===a||e&&\"function\"!=typeof _||k[a]===_||T(l,a,_,k[a],o);if(v)e||y&&(v.__html===y.__html||v.__html===l.innerHTML)||(l.innerHTML=v.__html),u.__k=[];else if(y&&(l.innerHTML=\"\"),C(l,h(d)?d:[d],u,t,i,o&&\"foreignObject\"!==x,r,f,r?r[0]:t.__k&&m(t,0),e,s),null!=r)for(a=r.length;a--;)null!=r[a]&&p(r[a]);e||(a=\"value\",void 0!==g&&(g!==l[a]||\"progress\"===x&&!g||\"option\"===x&&g!==k[a])&&T(l,a,g,k[a],!1),a=\"checked\",void 0!==b&&b!==l[a]&&T(l,a,b,k[a],!1))}return l}function z(n,u,t){try{\"function\"==typeof n?n(u):n.current=u}catch(n){l.__e(n,t)}}function N(n,u,t){var i,o;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!==n.__e||z(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null,n.__c=void 0}if(i=n.__k)for(o=0;o<i.length;o++)i[o]&&N(i[o],u,t||\"function\"!=typeof n.type);t||null==n.__e||p(n.__e),n.__=n.__e=n.__d=void 0}function O(n,l,u){return this.constructor(n,u)}function q(u,t,i){var o,r,f,e;l.__&&l.__(u,t),r=(o=\"function\"==typeof i)?null:i&&i.__k||t.__k,f=[],e=[],L(t,u=(!o&&i||t).__k=y(g,null,[u]),r||c,c,void 0!==t.ownerSVGElement,!o&&i?[i]:r?null:t.firstChild?n.call(t.childNodes):null,f,!o&&i?i:r?r.__e:t.firstChild,o,e),M(f,u,e)}function B(n,l){q(n,l,B)}function E(l,u,t){var i,o,r,f,e=v({},l.props);for(r in l.type&&l.type.defaultProps&&(f=l.type.defaultProps),u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:e[r]=void 0===u[r]&&void 0!==f?f[r]:u[r];return arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),d(l.type,e,i||l.key,o||l.ref,null)}function F(n,l){var u={__c:l=\"__cC\"+e++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,t;return this.getChildContext||(u=[],(t={})[l]=this,this.getChildContext=function(){return t},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(function(n){n.__e=!0,w(n)})},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=s.slice,l={__e:function(n,l,u,t){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&null==n.constructor},b.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=v({},this.state),\"function\"==typeof n&&(n=n(v({},u),this.props)),n&&v(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),w(this))},b.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),w(this))},b.prototype.render=g,i=[],r=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,f=function(n,l){return n.__v.__b-l.__v.__b},x.__r=0,e=0;export{b as Component,g as Fragment,E as cloneElement,F as createContext,y as createElement,_ as createRef,y as h,B as hydrate,t as isValidElement,l as options,q as render,$ as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","import { ErrorProperties } from '../extensions/exception-autocapture/error-conversion'\nimport type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ErrorEventArgs,\n ErrorMetadata,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n} from '../types'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis &\n Record<string, any> & {\n __PosthogExtensions__?: PostHogExtensions\n\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n }\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n parseErrorAsProperties?: (\n [event, source, lineno, colno, error]: ErrorEventArgs,\n metadata?: ErrorMetadata\n ) => ErrorProperties\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: Properties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: Properties) => void) => () => void\n }\n rrweb?: { record: any; version: string }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n canActivateRepeatedly?: (survey: any) => boolean\n generateSurveys?: (posthog: PostHog) => any | undefined\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n tracingHeadersPatchFns?: {\n _patchFetch: (sessionManager?: SessionIdManager) => () => void\n _patchXHR: (sessionManager?: SessionIdManager) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\nexport const ArrayProto = Array.prototype\nexport const nativeForEach = ArrayProto.forEach\nexport const nativeIndexOf = ArrayProto.indexOf\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import { PostHog } from './posthog-core'\nimport type { SegmentAnalytics } from './extensions/segment-integration'\nimport { recordOptions } from './extensions/replay/sessionrecording-utils'\n\nexport type Property = any\nexport type Properties = Record<string, Property>\n\nexport const COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'\n\nexport const knownUnsafeEditableEvent = [\n '$snapshot',\n '$pageview',\n '$pageleave',\n '$set',\n 'survey dismissed',\n 'survey sent',\n 'survey shown',\n '$identify',\n '$groupidentify',\n '$create_alias',\n '$$client_ingestion_warning',\n '$web_experiment_applied',\n '$feature_enrollment_update',\n '$feature_flag_called',\n] as const\n\n/**\n * These events can be processed by the `beforeCapture` function\n * but can cause unexpected confusion in data.\n *\n * Some features of PostHog rely on receiving 100% of these events\n */\nexport type KnownUnsafeEditableEvent = (typeof knownUnsafeEditableEvent)[number]\n\n/**\n * These are known events PostHog events that can be processed by the `beforeCapture` function\n * That means PostHog functionality does not rely on receiving 100% of these for calculations\n * So, it is safe to sample them to reduce the volume of events sent to PostHog\n */\nexport type KnownEventName =\n | '$heatmaps_data'\n | '$opt_in'\n | '$exception'\n | '$$heatmap'\n | '$web_vitals'\n | '$dead_click'\n | '$autocapture'\n | typeof COPY_AUTOCAPTURE_EVENT\n | '$rageclick'\n\nexport type EventName =\n | KnownUnsafeEditableEvent\n | KnownEventName\n // magic value so that the type of EventName is a set of known strings or any other string\n // which means you get autocomplete for known strings\n // but no type complaints when you add an arbitrary string\n | (string & {})\n\nexport interface CaptureResult {\n uuid: string\n event: EventName\n properties: Properties\n $set?: Properties\n $set_once?: Properties\n timestamp?: Date\n}\n\nexport type AutocaptureCompatibleElement = 'a' | 'button' | 'form' | 'input' | 'select' | 'textarea' | 'label'\nexport type DomAutocaptureEvents = 'click' | 'change' | 'submit'\n\n/**\n * If an array is passed for an allowlist, autocapture events will only be sent for elements matching\n * at least one of the elements in the array. Multiple allowlists can be used\n */\nexport interface AutocaptureConfig {\n /**\n * List of URLs to allow autocapture on, can be strings to match\n * or regexes e.g. ['https://example.com', 'test.com/.*']\n * this is useful when you want to autocapture on specific pages only\n *\n * if you set both url_allowlist and url_ignorelist,\n * we check the allowlist first and then the ignorelist.\n * the ignorelist can override the allowlist\n */\n url_allowlist?: (string | RegExp)[]\n\n /**\n * List of URLs to not allow autocapture on, can be strings to match\n * or regexes e.g. ['https://example.com', 'test.com/.*']\n * this is useful when you want to autocapture on most pages but not some specific ones\n *\n * if you set both url_allowlist and url_ignorelist,\n * we check the allowlist first and then the ignorelist.\n * the ignorelist can override the allowlist\n */\n url_ignorelist?: (string | RegExp)[]\n\n /**\n * List of DOM events to allow autocapture on e.g. ['click', 'change', 'submit']\n */\n dom_event_allowlist?: DomAutocaptureEvents[]\n\n /**\n * List of DOM elements to allow autocapture on\n * e.g. ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']\n * we consider the tree of elements from the root to the target element of the click event\n * so for the tree div > div > button > svg\n * if the allowlist has button then we allow the capture when the button or the svg is the click target\n * but not if either of the divs are detected as the click target\n */\n element_allowlist?: AutocaptureCompatibleElement[]\n\n /**\n * List of CSS selectors to allow autocapture on\n * e.g. ['[ph-capture]']\n * we consider the tree of elements from the root to the target element of the click event\n * so for the tree div > div > button > svg\n * and allow list config `['[id]']`\n * we will capture the click if the click-target or its parents has any id\n */\n css_selector_allowlist?: string[]\n\n /**\n * Exclude certain element attributes from autocapture\n * E.g. ['aria-label'] or [data-attr-pii]\n */\n element_attribute_ignorelist?: string[]\n\n capture_copied_text?: boolean\n}\n\nexport interface BootstrapConfig {\n distinctID?: string\n isIdentifiedID?: boolean\n featureFlags?: Record<string, boolean | string>\n featureFlagPayloads?: Record<string, JsonType>\n /**\n * Optionally provide a sessionID, this is so that you can provide an existing sessionID here to continue a user's session across a domain or device. It MUST be:\n * - unique to this user\n * - a valid UUID v7\n * - the timestamp part must be <= the timestamp of the first event in the session\n * - the timestamp of the last event in the session must be < the timestamp part + 24 hours\n * **/\n sessionID?: string\n}\n\nexport type SupportedWebVitalsMetrics = 'LCP' | 'CLS' | 'FCP' | 'INP'\n\nexport interface PerformanceCaptureConfig {\n /** works with session replay to use the browser's native performance observer to capture performance metrics */\n network_timing?: boolean\n /** use chrome's web vitals library to wrap fetch and capture web vitals */\n web_vitals?: boolean\n /**\n * We observe very large values reported by the Chrome web vitals library\n * These outliers are likely not real, useful values, and we exclude them\n * You can set this to 0 in order to include all values, NB this is not recommended\n * if not set this defaults to 15 minutes\n */\n __web_vitals_max_value?: number\n /**\n * By default all 4 metrics are captured\n * You can set this config to restrict which metrics are captured\n * e.g. ['CLS', 'FCP'] to only capture those two metrics\n * NB setting this does not override whether the capture is enabled\n */\n web_vitals_allowed_metrics?: SupportedWebVitalsMetrics[]\n /**\n * we delay flushing web vitals metrics to reduce the number of events we send\n * this is the maximum time we will wait before sending the metrics\n * if not set it defaults to 5 seconds\n */\n web_vitals_delayed_flush_ms?: number\n}\n\nexport interface DeadClickCandidate {\n node: Element\n originalEvent: MouseEvent\n timestamp: number\n // time between click and the most recent scroll\n scrollDelayMs?: number\n // time between click and the most recent mutation\n mutationDelayMs?: number\n // time between click and the most recent selection changed event\n selectionChangedDelayMs?: number\n // if neither scroll nor mutation seen before threshold passed\n absoluteDelayMs?: number\n}\n\nexport type DeadClicksAutoCaptureConfig = {\n // by default if a click is followed by a sroll within 100ms it is not a dead click\n scroll_threshold_ms?: number\n // by default if a click is followed by a selection change within 100ms it is not a dead click\n selection_change_threshold_ms?: number\n // by default if a click is followed by a mutation within 2500ms it is not a dead click\n mutation_threshold_ms?: number\n /**\n * Allows setting behavior for when a dead click is captured.\n * For e.g. to support capture to heatmaps\n *\n * If not provided the default behavior is to auto-capture dead click events\n *\n * Only intended to be provided by the SDK\n */\n __onCapture?: ((click: DeadClickCandidate, properties: Properties) => void) | undefined\n} & Pick<AutocaptureConfig, 'element_attribute_ignorelist'>\n\nexport interface HeatmapConfig {\n /*\n * how often to send batched data in $$heatmap_data events\n * if set to 0 or not set, sends using the default interval of 1 second\n * */\n flush_interval_milliseconds: number\n}\n\nexport type BeforeSendFn = (cr: CaptureResult | null) => CaptureResult | null\n\nexport interface PostHogConfig {\n api_host: string\n /** @deprecated - This property is no longer supported */\n api_method?: string\n api_transport?: 'XHR' | 'fetch'\n ui_host: string | null\n token: string\n autocapture: boolean | AutocaptureConfig\n rageclick: boolean\n cross_subdomain_cookie: boolean\n persistence: 'localStorage' | 'cookie' | 'memory' | 'localStorage+cookie' | 'sessionStorage'\n persistence_name: string\n /** @deprecated - Use 'persistence_name' instead */\n cookie_name?: string\n loaded: (posthog_instance: PostHog) => void\n\n /** @deprecated - Use `save_campaign_params` instead */\n store_google?: boolean\n save_campaign_params: boolean\n\n custom_campaign_params: string[]\n // a list of strings to be tested against navigator.userAgent to determine if the source is a bot\n // this is **added to** the default list of bots that we check\n // defaults to the empty array\n custom_blocked_useragents: string[]\n save_referrer: boolean\n capture_pageview: boolean\n capture_pageleave: boolean | 'if_capture_pageview'\n\n /** @deprecated Use `debug` instead */\n verbose?: boolean\n debug: boolean\n\n cookie_expiration: number\n upgrade: boolean\n disable_session_recording: boolean\n disable_persistence: boolean\n /** @deprecated - use `disable_persistence` instead */\n disable_cookie?: boolean\n disable_surveys: boolean\n disable_web_experiments: boolean\n /** If set, posthog-js will never load external scripts such as those needed for Session Replay or Surveys. */\n disable_external_dependency_loading?: boolean\n prepare_external_dependency_script?: (script: HTMLScriptElement) => HTMLScriptElement | null\n enable_recording_console_log?: boolean\n secure_cookie: boolean\n ip: boolean\n /** Starts the SDK in an opted out state requiring opt_in_capturing() to be called before events will b captured */\n opt_out_capturing_by_default: boolean\n opt_out_capturing_persistence_type: 'localStorage' | 'cookie'\n /** If set to true this will disable persistence if the user is opted out of capturing. @default false */\n opt_out_persistence_by_default?: boolean\n /** Opt out of user agent filtering such as googlebot or other bots. Defaults to `false` */\n opt_out_useragent_filter: boolean\n\n opt_out_capturing_cookie_prefix: string | null\n opt_in_site_apps: boolean\n respect_dnt: boolean\n /** @deprecated - use `property_denylist` instead */\n property_blacklist?: string[]\n property_denylist: string[]\n request_headers: { [header_name: string]: string }\n on_request_error?: (error: RequestResponse) => void\n /** @deprecated - use `request_headers` instead */\n xhr_headers?: { [header_name: string]: string }\n /** @deprecated - use `on_request_error` instead */\n on_xhr_error?: (failedRequest: XMLHttpRequest) => void\n request_batching: boolean\n properties_string_max_length: number\n session_recording: SessionRecordingOptions\n session_idle_timeout_seconds: number\n mask_all_element_attributes: boolean\n mask_all_text: boolean\n mask_personal_data_properties: boolean\n custom_personal_data_properties: string[]\n advanced_disable_decide: boolean\n advanced_disable_feature_flags: boolean\n advanced_disable_feature_flags_on_first_load: boolean\n advanced_disable_toolbar_metrics: boolean\n feature_flag_request_timeout_ms: number\n get_device_id: (uuid: string) => string\n name: string\n\n /**\n * This function is called when collecting properties for an event.\n * It allows you to edit data before it is sent\n * @deprecated - use `before_send` instead\n */\n sanitize_properties: ((properties: Properties, event_name: string) => Properties) | null\n /**\n * this is a read-only function that can be used to react to event capture\n * @deprecated - use `before_send` instead - NB before_send is not read only\n */\n _onCapture: (eventName: string, eventData: CaptureResult) => void\n /**\n * This function or array of functions - if provided - are called immediately before sending data to the server.\n * It allows you to edit data before it is sent, or choose not to send it all.\n * if provided as an array the functions are called in the order they are provided\n * any one function returning null means the event will not be sent\n */\n before_send?: BeforeSendFn | BeforeSendFn[]\n capture_performance?: boolean | PerformanceCaptureConfig\n // Should only be used for testing. Could negatively impact performance.\n disable_compression: boolean\n bootstrap: BootstrapConfig\n segment?: SegmentAnalytics\n /* @deprecated - use `capture_heatmaps` instead */\n enable_heatmaps?: boolean\n capture_heatmaps?: boolean | HeatmapConfig\n capture_dead_clicks?: boolean | DeadClicksAutoCaptureConfig\n disable_scroll_properties?: boolean\n // Let the pageview scroll stats use a custom css selector for the root element, e.g. `main`\n scroll_root_selector?: string | string[]\n\n /** You can control whether events from PostHog-js have person processing enabled with the `person_profiles` config setting. There are three options:\n * - `person_profiles: 'always'` _(default)_ - we will process persons data for all events\n * - `person_profiles: 'never'` - we won't process persons for any event. This means that anonymous users will not be merged once they sign up or login, so you lose the ability to create funnels that track users from anonymous to identified. All events (including `$identify`) will be sent with `$process_person_profile: False`.\n * - `person_profiles: 'identified_only'` - we will only process persons when you call `posthog.identify`, `posthog.alias`, `posthog.setPersonProperties`, `posthog.group`, `posthog.setPersonPropertiesForFlags` or `posthog.setGroupPropertiesForFlags` Anonymous users won't get person profiles.\n */\n person_profiles?: 'always' | 'never' | 'identified_only'\n /** @deprecated - use `person_profiles` instead */\n process_person?: 'always' | 'never' | 'identified_only'\n\n /** Client side rate limiting */\n rate_limiting?: {\n /** The average number of events per second that should be permitted (defaults to 10) */\n events_per_second?: number\n /** How many events can be captured in a burst. This defaults to 10 times the events_per_second count */\n events_burst_limit?: number\n }\n\n /** Used when sending data via `fetch`, use with care, this is intentionally meant to be used with NextJS `fetch`\n * Incorrect usage may cause out-of-date data for feature flags, actions tracking, etc.\n * See https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options\n */\n fetch_options?: {\n cache?: RequestInit['cache']\n next_options?: NextOptions\n }\n\n /**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * whether to wrap fetch and add tracing headers to the request\n * */\n __add_tracing_headers?: boolean\n\n /**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * enables the new RemoteConfig approach to loading config instead of decide\n * */\n __preview_remote_config?: boolean\n\n /**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * whether to send a sentinel value for distinct id, device id, and session id, which will be replaced server-side by a cookieless hash\n * */\n __preview_experimental_cookieless_mode?: boolean\n\n // ------- RETIRED CONFIGS -------\n\n /** @deprecated - NOT USED ANYMORE, kept here for backwards compatibility reasons */\n inapp_protocol?: string\n\n /** @deprecated - NOT USED ANYMORE, kept here for backwards compatibility reasons */\n inapp_link_new_window?: boolean\n}\n\nexport interface OptInOutCapturingOptions {\n capture: (event: string, properties: Properties, options: CaptureOptions) => void\n capture_event_name: string\n capture_properties: Properties\n enable_persistence: boolean\n clear_persistence: boolean\n persistence_type: 'cookie' | 'localStorage' | 'localStorage+cookie'\n cookie_prefix: string\n cookie_expiration: number\n cross_subdomain_cookie: boolean\n secure_cookie: boolean\n}\n\nexport interface SessionRecordingOptions {\n blockClass?: string | RegExp\n blockSelector?: string | null\n ignoreClass?: string\n maskTextClass?: string | RegExp\n maskTextSelector?: string | null\n maskTextFn?: ((text: string, element: HTMLElement | null) => string) | null\n maskAllInputs?: boolean\n maskInputOptions?: recordOptions['maskInputOptions']\n maskInputFn?: ((text: string, element?: HTMLElement) => string) | null\n slimDOMOptions?: recordOptions['slimDOMOptions']\n collectFonts?: boolean\n inlineStylesheet?: boolean\n recordCrossOriginIframes?: boolean\n /**\n * Allows local config to override remote canvas recording settings from the decide response\n */\n captureCanvas?: SessionRecordingCanvasOptions\n /** @deprecated - use maskCapturedNetworkRequestFn instead */\n maskNetworkRequestFn?: ((data: NetworkRequest) => NetworkRequest | null | undefined) | null\n /** Modify the network request before it is captured. Returning null or undefined stops it being captured */\n maskCapturedNetworkRequestFn?: ((data: CapturedNetworkRequest) => CapturedNetworkRequest | null | undefined) | null\n // our settings here only support a subset of those proposed for rrweb's network capture plugin\n recordHeaders?: boolean\n recordBody?: boolean\n // ADVANCED: while a user is active we take a full snapshot of the browser every interval. For very few sites playback performance might be better with different interval. Set to 0 to disable\n full_snapshot_interval_millis?: number\n /*\n ADVANCED: whether to partially compress rrweb events before sending them to the server,\n defaults to true, can be set to false to disable partial compression\n NB requests are still compressed when sent to the server regardless of this setting\n */\n compress_events?: boolean\n /*\n ADVANCED: alters the threshold before a recording considers a user has become idle.\n Normally only altered alongside changes to session_idle_timeout_ms.\n Default is 5 minutes.\n */\n session_idle_threshold_ms?: number\n /*\n ADVANCED: alters the refill rate for the token bucket mutation throttling\n Normally only altered alongside posthog support guidance.\n Accepts values between 0 and 100\n Default is 10.\n */\n __mutationRateLimiterRefillRate?: number\n /*\n ADVANCED: alters the bucket size for the token bucket mutation throttling\n Normally only altered alongside posthog support guidance.\n Accepts values between 0 and 100\n Default is 100.\n */\n __mutationRateLimiterBucketSize?: number\n}\n\nexport type SessionIdChangedCallback = (\n sessionId: string,\n windowId: string | null | undefined,\n changeReason?: { noSessionId: boolean; activityTimeout: boolean; sessionPastMaximumLength: boolean }\n) => void\n\nexport enum Compression {\n GZipJS = 'gzip-js',\n Base64 = 'base64',\n}\n\n// Request types - these should be kept minimal to what request.ts needs\n\n// Minimal class to allow interop between different request methods (xhr / fetch)\nexport interface RequestResponse {\n statusCode: number\n text?: string\n json?: any\n}\n\nexport type RequestCallback = (response: RequestResponse) => void\n\n// See https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options\ntype NextOptions = { revalidate: false | 0 | number; tags: string[] }\n\nexport interface RequestOptions {\n url: string\n // Data can be a single object or an array of objects when batched\n data?: Record<string, any> | Record<string, any>[]\n headers?: Record<string, any>\n transport?: 'XHR' | 'fetch' | 'sendBeacon'\n method?: 'POST' | 'GET'\n urlQueryArgs?: { compression: Compression }\n callback?: RequestCallback\n timeout?: number\n noRetries?: boolean\n compression?: Compression | 'best-available'\n fetchOptions?: {\n cache?: RequestInit['cache']\n next?: NextOptions\n }\n}\n\n// Queued request types - the same as a request but with additional queueing information\n\nexport interface QueuedRequestOptions extends RequestOptions {\n batchKey?: string /** key of queue, e.g. 'sessionRecording' vs 'event' */\n}\n\n// Used explicitly for retriable requests\nexport interface RetriableRequestOptions extends QueuedRequestOptions {\n retriesPerformedSoFar?: number\n}\n\nexport interface CaptureOptions {\n $set?: Properties /** used with $identify */\n $set_once?: Properties /** used with $identify */\n _url?: string /** Used to override the desired endpoint for the captured event */\n _batchKey?: string /** key of queue, e.g. 'sessionRecording' vs 'event' */\n _noTruncate?: boolean /** if set, overrides and disables config.properties_string_max_length */\n send_instantly?: boolean /** if set skips the batched queue */\n skip_client_rate_limiting?: boolean /** if set skips the client side rate limiting */\n transport?: RequestOptions['transport'] /** if set, overrides the desired transport method */\n timestamp?: Date\n}\n\nexport type FlagVariant = { flag: string; variant: string }\n\nexport type SessionRecordingCanvasOptions = {\n recordCanvas?: boolean | null\n canvasFps?: number | null\n // the API returns a decimal between 0 and 1 as a string\n canvasQuality?: string | null\n}\n\nexport interface RemoteConfig {\n supportedCompression: Compression[]\n autocapture_opt_out?: boolean\n /**\n * originally capturePerformance was replay only and so boolean true\n * is equivalent to { network_timing: true }\n * now capture performance can be separately enabled within replay\n * and as a standalone web vitals tracker\n * people can have them enabled separately\n * they work standalone but enhance each other\n * TODO: deprecate this so we make a new config that doesn't need this explanation\n */\n capturePerformance?: boolean | PerformanceCaptureConfig\n analytics?: {\n endpoint?: string\n }\n elementsChainAsString?: boolean\n // this is currently in development and may have breaking changes without a major version bump\n autocaptureExceptions?: boolean | { endpoint?: string }\n sessionRecording?: SessionRecordingCanvasOptions & {\n endpoint?: string\n consoleLogRecordingEnabled?: boolean\n // the API returns a decimal between 0 and 1 as a string\n sampleRate?: string | null\n minimumDurationMilliseconds?: number\n linkedFlag?: string | FlagVariant | null\n networkPayloadCapture?: Pick<NetworkRecordOptions, 'recordBody' | 'recordHeaders'>\n urlTriggers?: SessionRecordingUrlTrigger[]\n scriptConfig?: { script?: string | undefined }\n urlBlocklist?: SessionRecordingUrlTrigger[]\n eventTriggers?: string[]\n }\n surveys?: boolean\n toolbarParams: ToolbarParams\n editorParams?: ToolbarParams /** @deprecated, renamed to toolbarParams, still present on older API responses */\n toolbarVersion: 'toolbar' /** @deprecated, moved to toolbarParams */\n isAuthenticated: boolean\n siteApps: { id: string; url: string }[]\n heatmaps?: boolean\n defaultIdentifiedOnly?: boolean\n captureDeadClicks?: boolean\n hasFeatureFlags?: boolean // Indicates if the team has any flags enabled (if not we don't need to load them)\n}\n\nexport interface DecideResponse extends RemoteConfig {\n featureFlags: Record<string, string | boolean>\n featureFlagPayloads: Record<string, JsonType>\n errorsWhileComputingFlags: boolean\n}\n\nexport type SiteAppGlobals = {\n event: {\n uuid: string\n event: EventName\n properties: Properties\n timestamp?: Date\n elements_chain?: string\n distinct_id?: string\n }\n person: {\n properties: Properties\n }\n groups: Record<string, { id: string; type: string; properties: Properties }>\n}\n\nexport type SiteAppLoader = {\n id: string\n init: (config: { posthog: PostHog; callback: (success: boolean) => void }) => {\n processEvent?: (globals: SiteAppGlobals) => void\n }\n}\n\nexport type SiteApp = {\n id: string\n loaded: boolean\n errored: boolean\n processEvent?: (globals: SiteAppGlobals) => void\n}\n\nexport type FeatureFlagsCallback = (\n flags: string[],\n variants: Record<string, string | boolean>,\n context?: {\n errorsLoading?: boolean\n }\n) => void\n\nexport interface PersistentStore {\n is_supported: () => boolean\n error: (error: any) => void\n parse: (name: string) => any\n get: (name: string) => any\n set: (\n name: string,\n value: any,\n expire_days?: number | null,\n cross_subdomain?: boolean,\n secure?: boolean,\n debug?: boolean\n ) => void\n remove: (name: string, cross_subdomain?: boolean) => void\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Breaker = {}\nexport type EventHandler = (event: Event) => boolean | void\n\nexport type ToolbarUserIntent = 'add-action' | 'edit-action'\nexport type ToolbarSource = 'url' | 'localstorage'\nexport type ToolbarVersion = 'toolbar'\n\n/* sync with posthog */\nexport interface ToolbarParams {\n token?: string /** public posthog-js token */\n temporaryToken?: string /** private temporary user token */\n actionId?: number\n userIntent?: ToolbarUserIntent\n source?: ToolbarSource\n toolbarVersion?: ToolbarVersion\n instrument?: boolean\n distinctId?: string\n userEmail?: string\n dataAttributes?: string[]\n featureFlags?: Record<string, string | boolean>\n}\n\nexport type SnippetArrayItem = [method: string, ...args: any[]]\n\nexport type JsonRecord = { [key: string]: JsonType }\nexport type JsonType = string | number | boolean | null | JsonRecord | Array<JsonType>\n\n/** A feature that isn't publicly available yet.*/\nexport interface EarlyAccessFeature {\n // Sync this with the backend's EarlyAccessFeatureSerializer!\n name: string\n description: string\n stage: 'concept' | 'alpha' | 'beta'\n documentationUrl: string | null\n flagKey: string | null\n}\n\nexport type EarlyAccessFeatureCallback = (earlyAccessFeatures: EarlyAccessFeature[]) => void\n\nexport interface EarlyAccessFeatureResponse {\n earlyAccessFeatures: EarlyAccessFeature[]\n}\n\nexport type Headers = Record<string, string>\n\n/* for rrweb/network@1\n ** when that is released as part of rrweb this can be removed\n ** don't rely on this type, it may change without notice\n */\nexport type InitiatorType =\n | 'audio'\n | 'beacon'\n | 'body'\n | 'css'\n | 'early-hint'\n | 'embed'\n | 'fetch'\n | 'frame'\n | 'iframe'\n | 'icon'\n | 'image'\n | 'img'\n | 'input'\n | 'link'\n | 'navigation'\n | 'object'\n | 'ping'\n | 'script'\n | 'track'\n | 'video'\n | 'xmlhttprequest'\n\nexport type NetworkRecordOptions = {\n initiatorTypes?: InitiatorType[]\n maskRequestFn?: (data: CapturedNetworkRequest) => CapturedNetworkRequest | undefined\n recordHeaders?: boolean | { request: boolean; response: boolean }\n recordBody?: boolean | string[] | { request: boolean | string[]; response: boolean | string[] }\n recordInitialRequests?: boolean\n /**\n * whether to record PerformanceEntry events for network requests\n */\n recordPerformance?: boolean\n /**\n * the PerformanceObserver will only observe these entry types\n */\n performanceEntryTypeToObserve: string[]\n /**\n * the maximum size of the request/response body to record\n * NB this will be at most 1MB even if set larger\n */\n payloadSizeLimitBytes: number\n /**\n * some domains we should never record the payload\n * for example other companies session replay ingestion payloads aren't super useful but are gigantic\n * if this isn't provided we use a default list\n * if this is provided - we add the provided list to the default list\n * i.e. we never record the payloads on the default deny list\n */\n payloadHostDenyList?: string[]\n}\n\n/** @deprecated - use CapturedNetworkRequest instead */\nexport type NetworkRequest = {\n url: string\n}\n\n// In rrweb this is called NetworkRequest, but we already exposed that as having only URL\n// we also want to vary from the rrweb NetworkRequest because we want to include\n// all PerformanceEntry properties too.\n// that has 4 required properties\n// readonly duration: DOMHighResTimeStamp;\n// readonly entryType: string;\n// readonly name: string;\n// readonly startTime: DOMHighResTimeStamp;\n// NB: properties below here are ALPHA, don't rely on them, they may change without notice\n\n// we mirror PerformanceEntry since we read into this type from a PerformanceObserver,\n// but we don't want to inherit its readonly-iness\ntype Writable<T> = { -readonly [P in keyof T]: T[P] }\n\nexport type CapturedNetworkRequest = Writable<Omit<PerformanceEntry, 'toJSON'>> & {\n // properties below here are ALPHA, don't rely on them, they may change without notice\n method?: string\n initiatorType?: InitiatorType\n status?: number\n timeOrigin?: number\n timestamp?: number\n startTime?: number\n endTime?: number\n requestHeaders?: Headers\n requestBody?: string | null\n responseHeaders?: Headers\n responseBody?: string | null\n // was this captured before fetch/xhr could have been wrapped\n isInitial?: boolean\n}\n\nexport type ErrorEventArgs = [\n event: string | Event,\n source?: string | undefined,\n lineno?: number | undefined,\n colno?: number | undefined,\n error?: Error | undefined,\n]\n\nexport type ErrorMetadata = {\n handled?: boolean\n synthetic?: boolean\n syntheticException?: Error\n overrideExceptionType?: string\n overrideExceptionMessage?: string\n defaultExceptionType?: string\n defaultExceptionMessage?: string\n}\n\n// levels originally copied from Sentry to work with the sentry integration\n// and to avoid relying on a frequently changing @sentry/types dependency\n// but provided as an array of literal types, so we can constrain the level below\nexport const severityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'] as const\nexport declare type SeverityLevel = (typeof severityLevels)[number]\n\nexport interface ErrorProperties {\n $exception_type: string\n $exception_message: string\n $exception_level: SeverityLevel\n $exception_source?: string\n $exception_lineno?: number\n $exception_colno?: number\n $exception_DOMException_code?: string\n $exception_is_synthetic?: boolean\n $exception_stack_trace_raw?: string\n $exception_handled?: boolean\n $exception_personURL?: string\n}\n\nexport interface ErrorConversions {\n errorToProperties: (args: ErrorEventArgs) => ErrorProperties\n unhandledRejectionToProperties: (args: [ev: PromiseRejectionEvent]) => ErrorProperties\n}\n\nexport interface SessionRecordingUrlTrigger {\n url: string\n matching: 'regex'\n}\n","import { window } from './globals'\nimport { knownUnsafeEditableEvent, KnownUnsafeEditableEvent } from '../types'\nimport { includes } from './string-utils'\n\n// eslint-disable-next-line posthog-js/no-direct-array-check\nconst nativeIsArray = Array.isArray\nconst ObjProto = Object.prototype\nexport const hasOwnProperty = ObjProto.hasOwnProperty\nconst toString = ObjProto.toString\n\nexport const isArray =\n nativeIsArray ||\n function (obj: any): obj is any[] {\n return toString.call(obj) === '[object Array]'\n }\n\n// from a comment on http://dbj.org/dbj/?p=286\n// fails on only one very rare and deliberate custom object:\n// let bomb = { toString : undefined, valueOf: function(o) { return \"function BOMBA!\"; }};\nexport const isFunction = (x: unknown): x is (...args: any[]) => any => {\n // eslint-disable-next-line posthog-js/no-direct-function-check\n return typeof x === 'function'\n}\n\nexport const isNativeFunction = (x: unknown): x is (...args: any[]) => any =>\n isFunction(x) && x.toString().indexOf('[native code]') !== -1\n\n// When angular patches functions they pass the above `isNativeFunction` check (at least the MutationObserver)\nexport const isAngularZonePresent = (): boolean => {\n return !!(window as any).Zone\n}\n\n// Underscore Addons\nexport const isObject = (x: unknown): x is Record<string, any> => {\n // eslint-disable-next-line posthog-js/no-direct-object-check\n return x === Object(x) && !isArray(x)\n}\nexport const isEmptyObject = (x: unknown) => {\n if (isObject(x)) {\n for (const key in x) {\n if (hasOwnProperty.call(x, key)) {\n return false\n }\n }\n return true\n }\n return false\n}\nexport const isUndefined = (x: unknown): x is undefined => x === void 0\n\nexport const isString = (x: unknown): x is string => {\n // eslint-disable-next-line posthog-js/no-direct-string-check\n return toString.call(x) == '[object String]'\n}\n\nexport const isEmptyString = (x: unknown): boolean => isString(x) && x.trim().length === 0\n\nexport const isNull = (x: unknown): x is null => {\n // eslint-disable-next-line posthog-js/no-direct-null-check\n return x === null\n}\n\n/*\n sometimes you want to check if something is null or undefined\n that's what this is for\n */\nexport const isNullish = (x: unknown): x is null | undefined => isUndefined(x) || isNull(x)\n\nexport const isNumber = (x: unknown): x is number => {\n // eslint-disable-next-line posthog-js/no-direct-number-check\n return toString.call(x) == '[object Number]'\n}\nexport const isBoolean = (x: unknown): x is boolean => {\n // eslint-disable-next-line posthog-js/no-direct-boolean-check\n return toString.call(x) === '[object Boolean]'\n}\n\nexport const isDocument = (x: unknown): x is Document => {\n // eslint-disable-next-line posthog-js/no-direct-document-check\n return x instanceof Document\n}\n\nexport const isFormData = (x: unknown): x is FormData => {\n // eslint-disable-next-line posthog-js/no-direct-form-data-check\n return x instanceof FormData\n}\n\nexport const isFile = (x: unknown): x is File => {\n // eslint-disable-next-line posthog-js/no-direct-file-check\n return x instanceof File\n}\n\nexport const isKnownUnsafeEditableEvent = (x: unknown): x is KnownUnsafeEditableEvent => {\n return includes(knownUnsafeEditableEvent as unknown as string[], x)\n}\n","import Config from '../config'\nimport { isUndefined } from './type-utils'\nimport { assignableWindow, window } from './globals'\n\nexport type Logger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => void\n info: (...args: any[]) => void\n warn: (...args: any[]) => void\n error: (...args: any[]) => void\n critical: (...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string) => Logger\n}\n\nconst _createLogger = (prefix: string): Logger => {\n const logger: Logger = {\n _log: (level: 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string) => _createLogger(`${prefix} ${additionalPrefix}`),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","import { VNode, cloneElement, createContext } from 'preact'\nimport { PostHog } from '../../posthog-core'\nimport { MultipleSurveyQuestion, Survey, SurveyAppearance, SurveyQuestion } from '../../posthog-surveys-types'\nimport { document as _document, window as _window } from '../../utils/globals'\nimport { createLogger } from '../../utils/logger'\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\nconst SurveySeenPrefix = 'seenSurvey_'\n\nconst logger = createLogger('[Surveys]')\n\nexport const style = (appearance: SurveyAppearance | null) => {\n const positions = {\n left: 'left: 30px;',\n right: 'right: 30px;',\n center: `\n left: 50%;\n transform: translateX(-50%);\n `,\n }\n return `\n .survey-form, .thank-you-message {\n position: fixed;\n margin: 0px;\n bottom: 0px;\n color: black;\n font-weight: normal;\n font-family: ${appearance?.fontFamily || '-apple-system'}, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n text-align: left;\n max-width: ${parseInt(appearance?.maxWidth || '300')}px;\n width: 100%;\n z-index: ${parseInt(appearance?.zIndex || '99999')};\n border: 1.5px solid ${appearance?.borderColor || '#c9c6c6'};\n border-bottom: 0px;\n ${positions[appearance?.position || 'right'] || 'right: 30px;'}\n flex-direction: column;\n background: ${appearance?.backgroundColor || '#eeeded'};\n border-top-left-radius: 10px;\n border-top-right-radius: 10px;\n box-shadow: -6px 0 16px -8px rgb(0 0 0 / 8%), -9px 0 28px 0 rgb(0 0 0 / 5%), -12px 0 48px 16px rgb(0 0 0 / 3%);\n }\n\n .survey-box, .thank-you-message-container {\n padding: 20px 25px 10px;\n display: flex;\n flex-direction: column;\n border-radius: 10px;\n }\n\n .thank-you-message {\n text-align: center;\n }\n\n .form-submit[disabled] {\n opacity: 0.6;\n filter: grayscale(50%);\n cursor: not-allowed;\n }\n .survey-form textarea {\n color: #2d2d2d;\n font-size: 14px;\n font-family: ${appearance?.fontFamily || '-apple-system'}, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n background: white;\n color: black;\n outline: none;\n padding-left: 10px;\n padding-right: 10px;\n padding-top: 10px;\n border-radius: 6px;\n border-color: ${appearance?.borderColor || '#c9c6c6'};\n margin-top: 14px;\n width: 100%;\n box-sizing: border-box;\n }\n .survey-box:has(.survey-question:empty):not(:has(.survey-question-description)) textarea {\n margin-top: 0;\n }\n .form-submit {\n box-sizing: border-box;\n margin: 0;\n font-family: inherit;\n overflow: visible;\n text-transform: none;\n position: relative;\n display: inline-block;\n font-weight: 700;\n white-space: nowrap;\n text-align: center;\n border: 1.5px solid transparent;\n cursor: pointer;\n user-select: none;\n touch-action: manipulation;\n padding: 12px;\n font-size: 14px;\n border-radius: 6px;\n outline: 0;\n background: ${appearance?.submitButtonColor || 'black'} !important;\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);\n box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);\n width: 100%;\n }\n .form-cancel {\n display: flex;\n float: right;\n border: none;\n background: none;\n cursor: pointer;\n }\n .cancel-btn-wrapper {\n position: absolute;\n width: 35px;\n height: 35px;\n border-radius: 100%;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n background: white;\n border: 1.5px solid ${appearance?.borderColor || '#c9c6c6'};\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .bolded { font-weight: 600; }\n .buttons {\n display: flex;\n justify-content: center;\n }\n .footer-branding {\n font-size: 11px;\n margin-top: 10px;\n text-align: center;\n display: flex;\n justify-content: center;\n gap: 4px;\n align-items: center;\n font-weight: 500;\n background: ${appearance?.backgroundColor || '#eeeded'};\n text-decoration: none;\n backgroundColor: ${appearance?.backgroundColor || '#eeeded'};\n color: ${getContrastingTextColor(appearance?.backgroundColor || '#eeeded')};\n }\n .survey-question {\n font-weight: 500;\n font-size: 14px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .question-textarea-wrapper {\n display: flex;\n flex-direction: column;\n }\n .survey-question-description {\n font-size: 13px;\n padding-top: 5px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .ratings-number {\n font-size: 16px;\n font-weight: 600;\n padding: 8px 0px;\n border: none;\n }\n .ratings-number:hover {\n cursor: pointer;\n }\n .rating-options {\n margin-top: 14px;\n }\n .rating-options-number {\n display: grid;\n border-radius: 6px;\n overflow: hidden;\n border: 1.5px solid ${appearance?.borderColor || '#c9c6c6'};\n }\n .rating-options-number > .ratings-number {\n border-right: 1px solid ${appearance?.borderColor || '#c9c6c6'};\n }\n .rating-options-number > .ratings-number:last-of-type {\n border-right: 0px;\n }\n .rating-options-number .rating-active {\n background: ${appearance?.ratingButtonActiveColor || 'black'};\n }\n .rating-options-emoji {\n display: flex;\n justify-content: space-between;\n }\n .ratings-emoji {\n font-size: 16px;\n background-color: transparent;\n border: none;\n padding: 0px;\n }\n .ratings-emoji:hover {\n cursor: pointer;\n }\n .ratings-emoji.rating-active svg {\n fill: ${appearance?.ratingButtonActiveColor || 'black'};\n }\n .emoji-svg {\n fill: '#939393';\n }\n .rating-text {\n display: flex;\n flex-direction: row;\n font-size: 11px;\n justify-content: space-between;\n margin-top: 6px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n opacity: .60;\n }\n .multiple-choice-options {\n margin-top: 13px;\n font-size: 14px;\n }\n .survey-box:has(.survey-question:empty):not(:has(.survey-question-description)) .multiple-choice-options {\n margin-top: 0;\n }\n .multiple-choice-options .choice-option {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 13px;\n cursor: pointer;\n margin-bottom: 5px;\n position: relative;\n }\n .multiple-choice-options > .choice-option:last-of-type {\n margin-bottom: 0px;\n }\n .multiple-choice-options input {\n cursor: pointer;\n position: absolute;\n opacity: 0;\n }\n .choice-check {\n position: absolute;\n right: 10px;\n background: white;\n }\n .choice-check svg {\n display: none;\n }\n .multiple-choice-options .choice-option:hover .choice-check svg {\n display: inline-block;\n opacity: .25;\n }\n .multiple-choice-options input:checked + label + .choice-check svg {\n display: inline-block;\n opacity: 100% !important;\n }\n .multiple-choice-options input:checked + label {\n font-weight: bold;\n border: 1.5px solid rgba(0,0,0);\n }\n .multiple-choice-options input:checked + label input {\n font-weight: bold;\n }\n .multiple-choice-options label {\n width: 100%;\n cursor: pointer;\n padding: 10px;\n border: 1.5px solid rgba(0,0,0,.25);\n border-radius: 4px;\n background: white;\n }\n .multiple-choice-options .choice-option-open label {\n padding-right: 30px;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n max-width: 100%;\n }\n .multiple-choice-options .choice-option-open label span {\n width: 100%;\n }\n .multiple-choice-options .choice-option-open input:disabled + label {\n opacity: 0.6;\n }\n .multiple-choice-options .choice-option-open label input {\n position: relative;\n opacity: 1;\n flex-grow: 1;\n border: 0;\n outline: 0;\n }\n .thank-you-message-body {\n margin-top: 6px;\n font-size: 14px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .thank-you-message-header {\n margin: 10px 0px 0px;\n background: ${appearance?.backgroundColor || '#eeeded'};\n }\n .thank-you-message-container .form-submit {\n margin-top: 20px;\n margin-bottom: 10px;\n }\n .thank-you-message-countdown {\n margin-left: 6px;\n }\n .bottom-section {\n margin-top: 14px;\n }\n `\n}\n\nfunction nameToHex(name: string) {\n return {\n aliceblue: '#f0f8ff',\n antiquewhite: '#faebd7',\n aqua: '#00ffff',\n aquamarine: '#7fffd4',\n azure: '#f0ffff',\n beige: '#f5f5dc',\n bisque: '#ffe4c4',\n black: '#000000',\n blanchedalmond: '#ffebcd',\n blue: '#0000ff',\n blueviolet: '#8a2be2',\n brown: '#a52a2a',\n burlywood: '#deb887',\n cadetblue: '#5f9ea0',\n chartreuse: '#7fff00',\n chocolate: '#d2691e',\n coral: '#ff7f50',\n cornflowerblue: '#6495ed',\n cornsilk: '#fff8dc',\n crimson: '#dc143c',\n cyan: '#00ffff',\n darkblue: '#00008b',\n darkcyan: '#008b8b',\n darkgoldenrod: '#b8860b',\n darkgray: '#a9a9a9',\n darkgreen: '#006400',\n darkkhaki: '#bdb76b',\n darkmagenta: '#8b008b',\n darkolivegreen: '#556b2f',\n darkorange: '#ff8c00',\n darkorchid: '#9932cc',\n darkred: '#8b0000',\n darksalmon: '#e9967a',\n darkseagreen: '#8fbc8f',\n darkslateblue: '#483d8b',\n darkslategray: '#2f4f4f',\n darkturquoise: '#00ced1',\n darkviolet: '#9400d3',\n deeppink: '#ff1493',\n deepskyblue: '#00bfff',\n dimgray: '#696969',\n dodgerblue: '#1e90ff',\n firebrick: '#b22222',\n floralwhite: '#fffaf0',\n forestgreen: '#228b22',\n fuchsia: '#ff00ff',\n gainsboro: '#dcdcdc',\n ghostwhite: '#f8f8ff',\n gold: '#ffd700',\n goldenrod: '#daa520',\n gray: '#808080',\n green: '#008000',\n greenyellow: '#adff2f',\n honeydew: '#f0fff0',\n hotpink: '#ff69b4',\n 'indianred ': '#cd5c5c',\n indigo: '#4b0082',\n ivory: '#fffff0',\n khaki: '#f0e68c',\n lavender: '#e6e6fa',\n lavenderblush: '#fff0f5',\n lawngreen: '#7cfc00',\n lemonchiffon: '#fffacd',\n lightblue: '#add8e6',\n lightcoral: '#f08080',\n lightcyan: '#e0ffff',\n lightgoldenrodyellow: '#fafad2',\n lightgrey: '#d3d3d3',\n lightgreen: '#90ee90',\n lightpink: '#ffb6c1',\n lightsalmon: '#ffa07a',\n lightseagreen: '#20b2aa',\n lightskyblue: '#87cefa',\n lightslategray: '#778899',\n lightsteelblue: '#b0c4de',\n lightyellow: '#ffffe0',\n lime: '#00ff00',\n limegreen: '#32cd32',\n linen: '#faf0e6',\n magenta: '#ff00ff',\n maroon: '#800000',\n mediumaquamarine: '#66cdaa',\n mediumblue: '#0000cd',\n mediumorchid: '#ba55d3',\n mediumpurple: '#9370d8',\n mediumseagreen: '#3cb371',\n mediumslateblue: '#7b68ee',\n mediumspringgreen: '#00fa9a',\n mediumturquoise: '#48d1cc',\n mediumvioletred: '#c71585',\n midnightblue: '#191970',\n mintcream: '#f5fffa',\n mistyrose: '#ffe4e1',\n moccasin: '#ffe4b5',\n navajowhite: '#ffdead',\n navy: '#000080',\n oldlace: '#fdf5e6',\n olive: '#808000',\n olivedrab: '#6b8e23',\n orange: '#ffa500',\n orangered: '#ff4500',\n orchid: '#da70d6',\n palegoldenrod: '#eee8aa',\n palegreen: '#98fb98',\n paleturquoise: '#afeeee',\n palevioletred: '#d87093',\n papayawhip: '#ffefd5',\n peachpuff: '#ffdab9',\n peru: '#cd853f',\n pink: '#ffc0cb',\n plum: '#dda0dd',\n powderblue: '#b0e0e6',\n purple: '#800080',\n red: '#ff0000',\n rosybrown: '#bc8f8f',\n royalblue: '#4169e1',\n saddlebrown: '#8b4513',\n salmon: '#fa8072',\n sandybrown: '#f4a460',\n seagreen: '#2e8b57',\n seashell: '#fff5ee',\n sienna: '#a0522d',\n silver: '#c0c0c0',\n skyblue: '#87ceeb',\n slateblue: '#6a5acd',\n slategray: '#708090',\n snow: '#fffafa',\n springgreen: '#00ff7f',\n steelblue: '#4682b4',\n tan: '#d2b48c',\n teal: '#008080',\n thistle: '#d8bfd8',\n tomato: '#ff6347',\n turquoise: '#40e0d0',\n violet: '#ee82ee',\n wheat: '#f5deb3',\n white: '#ffffff',\n whitesmoke: '#f5f5f5',\n yellow: '#ffff00',\n yellowgreen: '#9acd32',\n }[name.toLowerCase()]\n}\n\nfunction hex2rgb(c: string) {\n if (c[0] === '#') {\n const hexColor = c.replace(/^#/, '')\n const r = parseInt(hexColor.slice(0, 2), 16)\n const g = parseInt(hexColor.slice(2, 4), 16)\n const b = parseInt(hexColor.slice(4, 6), 16)\n return 'rgb(' + r + ',' + g + ',' + b + ')'\n }\n return 'rgb(255, 255, 255)'\n}\n\nexport function getContrastingTextColor(color: string = defaultBackgroundColor) {\n let rgb\n if (color[0] === '#') {\n rgb = hex2rgb(color)\n }\n if (color.startsWith('rgb')) {\n rgb = color\n }\n // otherwise it's a color name\n const nameColorToHex = nameToHex(color)\n if (nameColorToHex) {\n rgb = hex2rgb(nameColorToHex)\n }\n if (!rgb) {\n return 'black'\n }\n const colorMatch = rgb.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)$/)\n if (colorMatch) {\n const r = parseInt(colorMatch[1])\n const g = parseInt(colorMatch[2])\n const b = parseInt(colorMatch[3])\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? 'black' : 'white'\n }\n return 'black'\n}\nexport function getTextColor(el: HTMLElement) {\n const backgroundColor = window.getComputedStyle(el).backgroundColor\n if (backgroundColor === 'rgba(0, 0, 0, 0)') {\n return 'black'\n }\n const colorMatch = backgroundColor.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)$/)\n if (!colorMatch) return 'black'\n\n const r = parseInt(colorMatch[1])\n const g = parseInt(colorMatch[2])\n const b = parseInt(colorMatch[3])\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? 'black' : 'white'\n}\n\nexport const defaultSurveyAppearance: SurveyAppearance = {\n backgroundColor: '#eeeded',\n submitButtonColor: 'black',\n submitButtonTextColor: 'white',\n ratingButtonColor: 'white',\n ratingButtonActiveColor: 'black',\n borderColor: '#c9c6c6',\n placeholder: 'Start typing...',\n whiteLabel: false,\n displayThankYouMessage: true,\n thankYouMessageHeader: 'Thank you for your feedback!',\n position: 'right',\n}\n\nexport const defaultBackgroundColor = '#eeeded'\n\nexport const createShadow = (styleSheet: string, surveyId: string, element?: Element) => {\n const div = document.createElement('div')\n div.className = `PostHogSurvey${surveyId}`\n const shadow = div.attachShadow({ mode: 'open' })\n if (styleSheet) {\n const styleElement = Object.assign(document.createElement('style'), {\n innerText: styleSheet,\n })\n shadow.appendChild(styleElement)\n }\n ;(element ? element : document.body).appendChild(div)\n return shadow\n}\n\nexport const sendSurveyEvent = (\n responses: Record<string, string | number | string[] | null> = {},\n survey: Survey,\n posthog?: PostHog\n) => {\n if (!posthog) {\n logger.error('[survey sent] event not captured, PostHog instance not found.')\n return\n }\n localStorage.setItem(getSurveySeenKey(survey), 'true')\n\n posthog.capture('survey sent', {\n $survey_name: survey.name,\n $survey_id: survey.id,\n $survey_iteration: survey.current_iteration,\n $survey_iteration_start_date: survey.current_iteration_start_date,\n $survey_questions: survey.questions.map((question) => question.question),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n ...responses,\n $set: {\n [getSurveyInteractionProperty(survey, 'responded')]: true,\n },\n })\n window.dispatchEvent(new Event('PHSurveySent'))\n}\n\nexport const dismissedSurveyEvent = (survey: Survey, posthog?: PostHog, readOnly?: boolean) => {\n // TODO: state management and unit tests for this would be nice\n if (!posthog) {\n logger.error('[survey dismissed] event not captured, PostHog instance not found.')\n return\n }\n if (readOnly) {\n return\n }\n posthog.capture('survey dismissed', {\n $survey_name: survey.name,\n $survey_id: survey.id,\n $survey_iteration: survey.current_iteration,\n $survey_iteration_start_date: survey.current_iteration_start_date,\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n $set: {\n [getSurveyInteractionProperty(survey, 'dismissed')]: true,\n },\n })\n localStorage.setItem(getSurveySeenKey(survey), 'true')\n window.dispatchEvent(new Event('PHSurveyClosed'))\n}\n\n// Use the Fisher-yates algorithm to shuffle this array\n// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\nexport const shuffle = (array: any[]) => {\n return array\n .map((a) => ({ sort: Math.floor(Math.random() * 10), value: a }))\n .sort((a, b) => a.sort - b.sort)\n .map((a) => a.value)\n}\n\nconst reverseIfUnshuffled = (unshuffled: any[], shuffled: any[]): any[] => {\n if (unshuffled.length === shuffled.length && unshuffled.every((val, index) => val === shuffled[index])) {\n return shuffled.reverse()\n }\n\n return shuffled\n}\n\nexport const getDisplayOrderChoices = (question: MultipleSurveyQuestion): string[] => {\n if (!question.shuffleOptions) {\n return question.choices\n }\n\n const displayOrderChoices = question.choices\n let openEndedChoice = ''\n if (question.hasOpenChoice) {\n // if the question has an open-ended choice, its always the last element in the choices array.\n openEndedChoice = displayOrderChoices.pop()!\n }\n\n const shuffledOptions = reverseIfUnshuffled(displayOrderChoices, shuffle(displayOrderChoices))\n\n if (question.hasOpenChoice) {\n question.choices.push(openEndedChoice)\n shuffledOptions.push(openEndedChoice)\n }\n\n return shuffledOptions\n}\n\nexport const getDisplayOrderQuestions = (survey: Survey): SurveyQuestion[] => {\n // retain the original questionIndex so we can correlate values in the webapp\n survey.questions.forEach((question, idx) => {\n question.originalQuestionIndex = idx\n })\n\n if (!survey.appearance || !survey.appearance.shuffleQuestions) {\n return survey.questions\n }\n\n return reverseIfUnshuffled(survey.questions, shuffle(survey.questions))\n}\n\nexport const hasEvents = (survey: Survey): boolean => {\n return survey.conditions?.events?.values?.length != undefined && survey.conditions?.events?.values?.length > 0\n}\n\nexport const canActivateRepeatedly = (survey: Survey): boolean => {\n return !!(survey.conditions?.events?.repeatedActivation && hasEvents(survey))\n}\n\n/**\n * getSurveySeen checks local storage for the surveySeen Key a\n * and overrides this value if the survey can be repeatedly activated by its events.\n * @param survey\n */\nexport const getSurveySeen = (survey: Survey): boolean => {\n const surveySeen = localStorage.getItem(getSurveySeenKey(survey))\n if (surveySeen) {\n // if a survey has already been seen,\n // we will override it with the event repeated activation value.\n return !canActivateRepeatedly(survey)\n }\n\n return false\n}\n\nexport const getSurveySeenKey = (survey: Survey): string => {\n let surveySeenKey = `${SurveySeenPrefix}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n surveySeenKey = `${SurveySeenPrefix}${survey.id}_${survey.current_iteration}`\n }\n\n return surveySeenKey\n}\n\nexport const getSurveySeenStorageKeys = (): string[] => {\n const surveyKeys = []\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key?.startsWith(SurveySeenPrefix)) {\n surveyKeys.push(key)\n }\n }\n\n return surveyKeys\n}\n\nconst getSurveyInteractionProperty = (survey: Survey, action: string): string => {\n let surveyProperty = `$survey_${action}/${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n surveyProperty = `$survey_${action}/${survey.id}/${survey.current_iteration}`\n }\n\n return surveyProperty\n}\n\ninterface SurveyContextProps {\n isPreviewMode: boolean\n previewPageIndex: number | undefined\n handleCloseSurveyPopup: () => void\n isPopup: boolean\n onPreviewSubmit: (res: string | string[] | number | null) => void\n}\n\nexport const SurveyContext = createContext<SurveyContextProps>({\n isPreviewMode: false,\n previewPageIndex: 0,\n handleCloseSurveyPopup: () => {},\n isPopup: true,\n onPreviewSubmit: () => {},\n})\n\ninterface RenderProps {\n component: VNode<{ className: string }>\n children: string\n renderAsHtml?: boolean\n style?: React.CSSProperties\n}\n\nexport const renderChildrenAsTextOrHtml = ({ component, children, renderAsHtml, style }: RenderProps) => {\n return renderAsHtml\n ? cloneElement(component, {\n dangerouslySetInnerHTML: { __html: children },\n style,\n })\n : cloneElement(component, {\n children,\n style,\n })\n}\n","/**\n * Having Survey types in types.ts was confusing tsc\n * and generating an invalid module.d.ts\n * See https://github.com/PostHog/posthog-js/issues/698\n */\n\nexport interface SurveyAppearance {\n // keep in sync with frontend/src/types.ts -> SurveyAppearance\n backgroundColor?: string\n submitButtonColor?: string\n // text color is deprecated, use auto contrast text color instead\n textColor?: string\n // deprecate submit button text eventually\n submitButtonText?: string\n submitButtonTextColor?: string\n descriptionTextColor?: string\n ratingButtonColor?: string\n ratingButtonActiveColor?: string\n ratingButtonHoverColor?: string\n whiteLabel?: boolean\n autoDisappear?: boolean\n displayThankYouMessage?: boolean\n thankYouMessageHeader?: string\n thankYouMessageDescription?: string\n thankYouMessageDescriptionContentType?: SurveyQuestionDescriptionContentType\n thankYouMessageCloseButtonText?: string\n borderColor?: string\n position?: 'left' | 'right' | 'center'\n placeholder?: string\n shuffleQuestions?: boolean\n surveyPopupDelaySeconds?: number\n // widget options\n widgetType?: 'button' | 'tab' | 'selector'\n widgetSelector?: string\n widgetLabel?: string\n widgetColor?: string\n fontFamily?: string\n // questionable: Not in frontend/src/types.ts -> SurveyAppearance, but used in site app\n maxWidth?: string\n zIndex?: string\n}\n\nexport enum SurveyType {\n Popover = 'popover',\n API = 'api',\n Widget = 'widget',\n}\n\nexport type SurveyQuestion = BasicSurveyQuestion | LinkSurveyQuestion | RatingSurveyQuestion | MultipleSurveyQuestion\n\nexport type SurveyQuestionDescriptionContentType = 'html' | 'text'\n\ninterface SurveyQuestionBase {\n question: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n optional?: boolean\n buttonText?: string\n originalQuestionIndex: number\n branching?: NextQuestionBranching | EndBranching | ResponseBasedBranching | SpecificQuestionBranching\n}\n\nexport interface BasicSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Open\n}\n\nexport interface LinkSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Link\n link?: string | null\n}\n\nexport interface RatingSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.Rating\n display: 'number' | 'emoji'\n scale: 3 | 5 | 7 | 10\n lowerBoundLabel: string\n upperBoundLabel: string\n}\n\nexport interface MultipleSurveyQuestion extends SurveyQuestionBase {\n type: SurveyQuestionType.SingleChoice | SurveyQuestionType.MultipleChoice\n choices: string[]\n hasOpenChoice?: boolean\n shuffleOptions?: boolean\n}\n\nexport enum SurveyQuestionType {\n Open = 'open',\n MultipleChoice = 'multiple_choice',\n SingleChoice = 'single_choice',\n Rating = 'rating',\n Link = 'link',\n}\n\nexport enum SurveyQuestionBranchingType {\n NextQuestion = 'next_question',\n End = 'end',\n ResponseBased = 'response_based',\n SpecificQuestion = 'specific_question',\n}\n\ninterface NextQuestionBranching {\n type: SurveyQuestionBranchingType.NextQuestion\n}\n\ninterface EndBranching {\n type: SurveyQuestionBranchingType.End\n}\n\ninterface ResponseBasedBranching {\n type: SurveyQuestionBranchingType.ResponseBased\n responseValues: Record<string, any>\n}\n\ninterface SpecificQuestionBranching {\n type: SurveyQuestionBranchingType.SpecificQuestion\n index: number\n}\n\nexport interface SurveyResponse {\n surveys: Survey[]\n}\n\nexport type SurveyCallback = (surveys: Survey[]) => void\n\nexport type SurveyUrlMatchType = 'regex' | 'not_regex' | 'exact' | 'is_not' | 'icontains' | 'not_icontains'\n\nexport interface SurveyElement {\n text?: string\n $el_text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\nexport interface SurveyRenderReason {\n visible: boolean\n disabledReason?: string\n}\n\nexport interface Survey {\n // Sync this with the backend's SurveyAPISerializer!\n id: string\n name: string\n description: string\n type: SurveyType\n feature_flag_keys:\n | {\n key: string\n value?: string\n }[]\n | null\n linked_flag_key: string | null\n targeting_flag_key: string | null\n internal_targeting_flag_key: string | null\n questions: SurveyQuestion[]\n appearance: SurveyAppearance | null\n conditions: {\n url?: string\n selector?: string\n seenSurveyWaitPeriodInDays?: number\n urlMatchType?: SurveyUrlMatchType\n events: {\n repeatedActivation?: boolean\n values: {\n name: string\n }[]\n } | null\n actions: {\n values: SurveyActionType[]\n } | null\n } | null\n start_date: string | null\n end_date: string | null\n current_iteration: number | null\n current_iteration_start_date: string | null\n}\n\nexport interface SurveyActionType {\n id: number\n name: string | null\n steps?: ActionStepType[]\n}\n\n/** Sync with plugin-server/src/types.ts */\nexport type ActionStepStringMatching = 'contains' | 'exact' | 'regex'\n\nexport interface ActionStepType {\n event?: string | null\n selector?: string | null\n /** @deprecated Only `selector` should be used now. */\n tag_name?: string\n text?: string | null\n /** @default StringMatching.Exact */\n text_matching?: ActionStepStringMatching | null\n href?: string | null\n /** @default ActionStepStringMatching.Exact */\n href_matching?: ActionStepStringMatching | null\n url?: string | null\n /** @default StringMatching.Contains */\n url_matching?: ActionStepStringMatching | null\n}\n","import { Breaker, EventHandler, Properties } from '../types'\nimport { hasOwnProperty, isArray, isFormData, isFunction, isNull, isNullish, isString } from './type-utils'\nimport { logger } from './logger'\nimport { nativeForEach, nativeIndexOf, window } from './globals'\n\nconst breaker: Breaker = {}\n\nexport function eachArray<E = any>(\n obj: E[] | null | undefined,\n iterator: (value: E, key: number) => void | Breaker,\n thisArg?: any\n): void {\n if (isArray(obj)) {\n if (nativeForEach && obj.forEach === nativeForEach) {\n obj.forEach(iterator, thisArg)\n } else if ('length' in obj && obj.length === +obj.length) {\n for (let i = 0, l = obj.length; i < l; i++) {\n if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {\n return\n }\n }\n }\n }\n}\n\n/**\n * @param {*=} obj\n * @param {function(...*)=} iterator\n * @param {Object=} thisArg\n */\nexport function each(obj: any, iterator: (value: any, key: any) => void | Breaker, thisArg?: any): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n return eachArray(obj, iterator, thisArg)\n }\n if (isFormData(obj)) {\n for (const pair of obj.entries()) {\n if (iterator.call(thisArg, pair[1], pair[0]) === breaker) {\n return\n }\n }\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n if (iterator.call(thisArg, obj[key], key) === breaker) {\n return\n }\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n eachArray(args, function (source) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n })\n return obj\n}\n\nexport const extendArray = function <T>(obj: T[], ...args: T[][]): T[] {\n eachArray(args, function (source) {\n eachArray(source, function (item) {\n obj.push(item)\n })\n })\n return obj\n}\n\nexport const include = function (\n obj: null | string | Array<any> | Record<string, any>,\n target: any\n): boolean | Breaker {\n let found = false\n if (isNull(obj)) {\n return found\n }\n if (nativeIndexOf && obj.indexOf === nativeIndexOf) {\n return obj.indexOf(target) != -1\n }\n each(obj, function (value) {\n if (found || (found = value === target)) {\n return breaker\n }\n return\n })\n return found\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const isValidRegex = function (str: string): boolean {\n try {\n new RegExp(str)\n } catch {\n return false\n }\n return true\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if (isString(v) && v.length > 0) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number | null\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value) && !isNull(maxStringLength)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\nexport const registerEvent = (function () {\n // written by Dean Edwards, 2005\n // with input from Tino Zijdel - crisp@xs4all.nl\n // with input from Carl Sverre - mail@carlsverre.com\n // with input from PostHog\n // http://dean.edwards.name/weblog/2005/10/add-event/\n // https://gist.github.com/1930440\n\n /**\n * @param {Object} element\n * @param {string} type\n * @param {function(...*)} handler\n * @param {boolean=} oldSchool\n * @param {boolean=} useCapture\n */\n const register_event = function (\n element: Element | Window | Document | Node,\n type: string,\n handler: EventHandler,\n oldSchool?: boolean,\n useCapture?: boolean\n ) {\n if (!element) {\n logger.error('No valid element provided to register_event')\n return\n }\n\n if (element.addEventListener && !oldSchool) {\n element.addEventListener(type, handler, !!useCapture)\n } else {\n const ontype = 'on' + type\n const old_handler = (element as any)[ontype] // can be undefined\n ;(element as any)[ontype] = makeHandler(element, handler, old_handler)\n }\n }\n\n function makeHandler(\n element: Element | Window | Document | Node,\n new_handler: EventHandler,\n old_handlers: EventHandler\n ) {\n return function (event: Event): boolean | void {\n event = event || fixEvent(window?.event)\n\n // this basically happens in firefox whenever another script\n // overwrites the onload callback and doesn't pass the event\n // object to previously defined callbacks. All the browsers\n // that don't define window.event implement addEventListener\n // so the dom_loaded handler will still be fired as usual.\n if (!event) {\n return undefined\n }\n\n let ret = true\n let old_result: any\n\n if (isFunction(old_handlers)) {\n old_result = old_handlers(event)\n }\n const new_result = new_handler.call(element, event)\n\n if (false === old_result || false === new_result) {\n ret = false\n }\n\n return ret\n }\n }\n\n function fixEvent(event: Event | undefined): Event | undefined {\n if (event) {\n event.preventDefault = fixEvent.preventDefault\n event.stopPropagation = fixEvent.stopPropagation\n }\n return event\n }\n fixEvent.preventDefault = function () {\n ;(this as any as Event).returnValue = false\n }\n fixEvent.stopPropagation = function () {\n ;(this as any as Event).cancelBubble = true\n }\n\n return register_event\n})()\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n","import { each, isValidRegex } from './'\n\nimport { isArray, isFile, isUndefined } from './type-utils'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const isUrlMatchingRegex = function (url: string, pattern: string): boolean {\n if (!isValidRegex(pattern)) return false\n return new RegExp(pattern).test(url)\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n const queryParams: string = withoutHash.split('?')[1] || ''\n\n const queryParts = queryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","export class SimpleEventEmitter {\n private events: { [key: string]: ((...args: any[]) => void)[] } = {}\n\n constructor() {\n this.events = {}\n }\n\n on(event: string, listener: (...args: any[]) => void): () => void {\n if (!this.events[event]) {\n this.events[event] = []\n }\n this.events[event].push(listener)\n\n return () => {\n this.events[event] = this.events[event].filter((x) => x !== listener)\n }\n }\n\n emit(event: string, payload: any): void {\n for (const listener of this.events[event] || []) {\n listener(payload)\n }\n for (const listener of this.events['*'] || []) {\n listener(event, payload)\n }\n }\n}\n","import { PostHog } from '../../posthog-core'\nimport { ActionStepStringMatching, ActionStepType, SurveyActionType, SurveyElement } from '../../posthog-surveys-types'\nimport { SimpleEventEmitter } from '../../utils/simple-event-emitter'\nimport { CaptureResult } from '../../types'\nimport { isUndefined } from '../../utils/type-utils'\nimport { window } from '../../utils/globals'\nimport { isUrlMatchingRegex } from '../../utils/request-utils'\n\nexport class ActionMatcher {\n private readonly actionRegistry?: Set<SurveyActionType>\n private readonly instance?: PostHog\n private readonly actionEvents: Set<string>\n private _debugEventEmitter = new SimpleEventEmitter()\n\n constructor(instance?: PostHog) {\n this.instance = instance\n this.actionEvents = new Set<string>()\n this.actionRegistry = new Set<SurveyActionType>()\n }\n\n init() {\n if (!isUndefined(this.instance?._addCaptureHook)) {\n const matchEventToAction = (eventName: string, eventPayload: any) => {\n this.on(eventName, eventPayload)\n }\n this.instance?._addCaptureHook(matchEventToAction)\n }\n }\n\n register(actions: SurveyActionType[]): void {\n if (isUndefined(this.instance?._addCaptureHook)) {\n return\n }\n\n actions.forEach((action) => {\n this.actionRegistry?.add(action)\n action.steps?.forEach((step) => {\n this.actionEvents?.add(step?.event || '')\n })\n })\n\n if (this.instance?.autocapture) {\n const selectorsToWatch: Set<string> = new Set<string>()\n actions.forEach((action) => {\n action.steps?.forEach((step) => {\n if (step?.selector) {\n selectorsToWatch.add(step?.selector)\n }\n })\n })\n this.instance?.autocapture.setElementSelectors(selectorsToWatch)\n }\n }\n\n on(eventName: string, eventPayload?: CaptureResult) {\n if (eventPayload == null || eventName.length == 0) {\n return\n }\n\n if (!this.actionEvents.has(eventName) && !this.actionEvents.has(<string>eventPayload?.event)) {\n return\n }\n\n if (this.actionRegistry && this.actionRegistry?.size > 0) {\n this.actionRegistry.forEach((action) => {\n if (this.checkAction(eventPayload, action)) {\n this._debugEventEmitter.emit('actionCaptured', action.name)\n }\n })\n }\n }\n\n _addActionHook(callback: (actionName: string, eventPayload?: any) => void): void {\n this.onAction('actionCaptured', (data) => callback(data))\n }\n\n private checkAction(event?: CaptureResult, action?: SurveyActionType): boolean {\n if (action?.steps == null) {\n return false\n }\n\n for (const step of action.steps) {\n if (this.checkStep(event, step)) {\n return true\n }\n }\n\n return false\n }\n\n onAction(event: 'actionCaptured', cb: (...args: any[]) => void): () => void {\n return this._debugEventEmitter.on(event, cb)\n }\n\n private checkStep = (event?: CaptureResult, step?: ActionStepType): boolean => {\n return this.checkStepEvent(event, step) && this.checkStepUrl(event, step) && this.checkStepElement(event, step)\n }\n\n private checkStepEvent = (event?: CaptureResult, step?: ActionStepType): boolean => {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.event && event?.event !== step?.event) {\n return false // EVENT NAME IS A MISMATCH\n }\n return true\n }\n\n private checkStepUrl(event?: CaptureResult, step?: ActionStepType): boolean {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.url) {\n const eventUrl = event?.properties?.$current_url\n if (!eventUrl || typeof eventUrl !== 'string') {\n return false // URL IS UNKNOWN\n }\n if (!ActionMatcher.matchString(eventUrl, step?.url, step?.url_matching || 'contains')) {\n return false // URL IS A MISMATCH\n }\n }\n return true\n }\n\n private static matchString(url: string, pattern: string, matching: ActionStepStringMatching): boolean {\n switch (matching) {\n case 'regex':\n return !!window && isUrlMatchingRegex(url, pattern)\n case 'exact':\n return pattern === url\n case 'contains':\n // Simulating SQL LIKE behavior (_ = any single character, % = any zero or more characters)\n // eslint-disable-next-line no-case-declarations\n const adjustedRegExpStringPattern = ActionMatcher.escapeStringRegexp(pattern)\n .replace(/_/g, '.')\n .replace(/%/g, '.*')\n return isUrlMatchingRegex(url, adjustedRegExpStringPattern)\n\n default:\n return false\n }\n }\n\n private static escapeStringRegexp(pattern: string): string {\n // Escape characters with special meaning either inside or outside character sets.\n // Use a simple backslash escape when it’s always valid, and a `\\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar.\n return pattern.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d')\n }\n\n private checkStepElement(event?: CaptureResult, step?: ActionStepType): boolean {\n // CHECK CONDITIONS, OTHERWISE SKIPPED\n if (step?.href || step?.tag_name || step?.text) {\n const elements = this.getElementsList(event)\n if (\n !elements.some((element) => {\n if (\n step?.href &&\n !ActionMatcher.matchString(element.href || '', step?.href, step?.href_matching || 'exact')\n ) {\n return false // ELEMENT HREF IS A MISMATCH\n }\n if (step?.tag_name && element.tag_name !== step?.tag_name) {\n return false // ELEMENT TAG NAME IS A MISMATCH\n }\n if (\n step?.text &&\n !(\n ActionMatcher.matchString(element.text || '', step?.text, step?.text_matching || 'exact') ||\n ActionMatcher.matchString(\n element.$el_text || '',\n step?.text,\n step?.text_matching || 'exact'\n )\n )\n ) {\n return false // ELEMENT TEXT IS A MISMATCH\n }\n return true\n })\n ) {\n // AT LEAST ONE ELEMENT MUST BE A SUBMATCH\n return false\n }\n }\n\n if (step?.selector) {\n const elementSelectors = event?.properties?.$element_selectors as unknown as string[]\n if (!elementSelectors) {\n return false // SELECTOR IS A MISMATCH\n }\n if (!elementSelectors.includes(step?.selector)) {\n return false // SELECTOR IS A MISMATCH\n }\n }\n\n return true\n }\n\n private getElementsList(event?: CaptureResult): SurveyElement[] {\n if (event?.properties.$elements == null) {\n return []\n }\n\n return event?.properties.$elements as unknown as SurveyElement[]\n }\n}\n","import { Survey } from '../posthog-surveys-types'\nimport { SURVEYS_ACTIVATED } from '../constants'\n\nimport { CaptureResult } from '../types'\nimport { ActionMatcher } from '../extensions/surveys/action-matcher'\nimport { PostHog } from '../posthog-core'\nimport { isUndefined } from './type-utils'\n\nexport class SurveyEventReceiver {\n // eventToSurveys is a mapping of event name to all the surveys that are activated by it\n private readonly eventToSurveys: Map<string, string[]>\n // actionToSurveys is a mapping of action name to all the surveys that are activated by it\n private readonly actionToSurveys: Map<string, string[]>\n // actionMatcher can look at CaptureResult payloads and match an event to its corresponding action.\n private actionMatcher?: ActionMatcher | null\n private readonly instance?: PostHog\n private static SURVEY_SHOWN_EVENT_NAME = 'survey shown'\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.eventToSurveys = new Map<string, string[]>()\n this.actionToSurveys = new Map<string, string[]>()\n }\n\n register(surveys: Survey[]): void {\n if (isUndefined(this.instance?._addCaptureHook)) {\n return\n }\n\n this.setupEventBasedSurveys(surveys)\n this.setupActionBasedSurveys(surveys)\n }\n\n private setupActionBasedSurveys(surveys: Survey[]) {\n const actionBasedSurveys = surveys.filter(\n (survey: Survey) => survey.conditions?.actions && survey.conditions?.actions?.values?.length > 0\n )\n\n if (actionBasedSurveys.length === 0) {\n return\n }\n\n if (this.actionMatcher == null) {\n this.actionMatcher = new ActionMatcher(this.instance)\n this.actionMatcher.init()\n // match any actions to its corresponding survey.\n const matchActionToSurvey = (actionName: string) => {\n this.onAction(actionName)\n }\n\n this.actionMatcher._addActionHook(matchActionToSurvey)\n }\n\n actionBasedSurveys.forEach((survey) => {\n if (\n survey.conditions &&\n survey.conditions?.actions &&\n survey.conditions?.actions?.values &&\n survey.conditions?.actions?.values?.length > 0\n ) {\n // register the known set of actions with\n // the action-matcher so it can match\n // events to actions\n this.actionMatcher?.register(survey.conditions.actions.values)\n\n // maintain a mapping of (Action1) => [Survey1, Survey2, Survey3]\n // where Surveys 1-3 are all activated by Action1\n survey.conditions?.actions?.values?.forEach((action) => {\n if (action && action.name) {\n const knownSurveys: string[] | undefined = this.actionToSurveys.get(action.name)\n if (knownSurveys) {\n knownSurveys.push(survey.id)\n }\n this.actionToSurveys.set(action.name, knownSurveys || [survey.id])\n }\n })\n }\n })\n }\n\n private setupEventBasedSurveys(surveys: Survey[]) {\n const eventBasedSurveys = surveys.filter(\n (survey: Survey) => survey.conditions?.events && survey.conditions?.events?.values?.length > 0\n )\n\n if (eventBasedSurveys.length === 0) {\n return\n }\n\n // match any events to its corresponding survey.\n const matchEventToSurvey = (eventName: string, eventPayload?: CaptureResult) => {\n this.onEvent(eventName, eventPayload)\n }\n this.instance?._addCaptureHook(matchEventToSurvey)\n\n surveys.forEach((survey) => {\n // maintain a mapping of (Event1) => [Survey1, Survey2, Survey3]\n // where Surveys 1-3 are all activated by Event1\n survey.conditions?.events?.values?.forEach((event) => {\n if (event && event.name) {\n const knownSurveys: string[] | undefined = this.eventToSurveys.get(event.name)\n if (knownSurveys) {\n knownSurveys.push(survey.id)\n }\n this.eventToSurveys.set(event.name, knownSurveys || [survey.id])\n }\n })\n })\n }\n\n onEvent(event: string, eventPayload?: CaptureResult): void {\n const existingActivatedSurveys: string[] = this.instance?.persistence?.props[SURVEYS_ACTIVATED] || []\n if (\n SurveyEventReceiver.SURVEY_SHOWN_EVENT_NAME == event &&\n eventPayload &&\n existingActivatedSurveys.length > 0\n ) {\n // remove survey that from activatedSurveys here.\n const surveyId = eventPayload?.properties?.$survey_id\n if (surveyId) {\n const index = existingActivatedSurveys.indexOf(surveyId)\n if (index >= 0) {\n existingActivatedSurveys.splice(index, 1)\n this._updateActivatedSurveys(existingActivatedSurveys)\n }\n }\n } else {\n if (this.eventToSurveys.has(event)) {\n this._updateActivatedSurveys(existingActivatedSurveys.concat(this.eventToSurveys.get(event) || []))\n }\n }\n }\n\n onAction(actionName: string): void {\n const existingActivatedSurveys: string[] = this.instance?.persistence?.props[SURVEYS_ACTIVATED] || []\n if (this.actionToSurveys.has(actionName)) {\n this._updateActivatedSurveys(existingActivatedSurveys.concat(this.actionToSurveys.get(actionName) || []))\n }\n }\n\n private _updateActivatedSurveys(activatedSurveys: string[]) {\n // we use a new Set here to remove duplicates.\n this.instance?.persistence?.register({\n [SURVEYS_ACTIVATED]: [...new Set(activatedSurveys)],\n })\n }\n\n getSurveys(): string[] {\n const existingActivatedSurveys = this.instance?.persistence?.props[SURVEYS_ACTIVATED]\n return existingActivatedSurveys ? existingActivatedSurveys : []\n }\n\n getEventToSurveys(): Map<string, string[]> {\n return this.eventToSurveys\n }\n\n _getActionMatcher(): ActionMatcher | null | undefined {\n return this.actionMatcher\n }\n}\n","import { SURVEYS } from './constants'\nimport { getSurveySeenStorageKeys } from './extensions/surveys/surveys-utils'\nimport { PostHog } from './posthog-core'\nimport {\n Survey,\n SurveyCallback,\n SurveyQuestionBranchingType,\n SurveyQuestionType,\n SurveyUrlMatchType,\n} from './posthog-surveys-types'\nimport { RemoteConfig } from './types'\nimport { assignableWindow, document, window } from './utils/globals'\nimport { createLogger } from './utils/logger'\nimport { isUrlMatchingRegex } from './utils/request-utils'\nimport { SurveyEventReceiver } from './utils/survey-event-receiver'\nimport { isNullish } from './utils/type-utils'\n\nconst logger = createLogger('[Surveys]')\n\nexport const surveyUrlValidationMap: Record<SurveyUrlMatchType, (conditionsUrl: string) => boolean> = {\n icontains: (conditionsUrl) =>\n !!window && window.location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) > -1,\n not_icontains: (conditionsUrl) =>\n !!window && window.location.href.toLowerCase().indexOf(conditionsUrl.toLowerCase()) === -1,\n regex: (conditionsUrl) => !!window && isUrlMatchingRegex(window.location.href, conditionsUrl),\n not_regex: (conditionsUrl) => !!window && !isUrlMatchingRegex(window.location.href, conditionsUrl),\n exact: (conditionsUrl) => window?.location.href === conditionsUrl,\n is_not: (conditionsUrl) => window?.location.href !== conditionsUrl,\n}\n\nfunction getRatingBucketForResponseValue(responseValue: number, scale: number) {\n if (scale === 3) {\n if (responseValue < 1 || responseValue > 3) {\n throw new Error('The response must be in range 1-3')\n }\n\n return responseValue === 1 ? 'negative' : responseValue === 2 ? 'neutral' : 'positive'\n } else if (scale === 5) {\n if (responseValue < 1 || responseValue > 5) {\n throw new Error('The response must be in range 1-5')\n }\n\n return responseValue <= 2 ? 'negative' : responseValue === 3 ? 'neutral' : 'positive'\n } else if (scale === 7) {\n if (responseValue < 1 || responseValue > 7) {\n throw new Error('The response must be in range 1-7')\n }\n\n return responseValue <= 3 ? 'negative' : responseValue === 4 ? 'neutral' : 'positive'\n } else if (scale === 10) {\n if (responseValue < 0 || responseValue > 10) {\n throw new Error('The response must be in range 0-10')\n }\n\n return responseValue <= 6 ? 'detractors' : responseValue <= 8 ? 'passives' : 'promoters'\n }\n\n throw new Error('The scale must be one of: 3, 5, 7, 10')\n}\n\nexport function getNextSurveyStep(\n survey: Survey,\n currentQuestionIndex: number,\n response: string | string[] | number | null\n) {\n const question = survey.questions[currentQuestionIndex]\n const nextQuestionIndex = currentQuestionIndex + 1\n\n if (!question.branching?.type) {\n if (currentQuestionIndex === survey.questions.length - 1) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n\n if (question.branching.type === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n } else if (question.branching.type === SurveyQuestionBranchingType.SpecificQuestion) {\n if (Number.isInteger(question.branching.index)) {\n return question.branching.index\n }\n } else if (question.branching.type === SurveyQuestionBranchingType.ResponseBased) {\n // Single choice\n if (question.type === SurveyQuestionType.SingleChoice) {\n // :KLUDGE: for now, look up the choiceIndex based on the response\n // TODO: once QuestionTypes.MultipleChoiceQuestion is refactored, pass the selected choiceIndex into this method\n const selectedChoiceIndex = question.choices.indexOf(`${response}`)\n\n if (question.branching?.responseValues?.hasOwnProperty(selectedChoiceIndex)) {\n const nextStep = question.branching.responseValues[selectedChoiceIndex]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n } else if (question.type === SurveyQuestionType.Rating) {\n if (typeof response !== 'number' || !Number.isInteger(response)) {\n throw new Error('The response type must be an integer')\n }\n\n const ratingBucket = getRatingBucketForResponseValue(response, question.scale)\n\n if (question.branching?.responseValues?.hasOwnProperty(ratingBucket)) {\n const nextStep = question.branching.responseValues[ratingBucket]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n }\n\n return nextQuestionIndex\n }\n\n logger.warn('Falling back to next question index due to unexpected branching type')\n return nextQuestionIndex\n}\n\n// use urlMatchType to validate url condition, fallback to contains for backwards compatibility\nexport function doesSurveyUrlMatch(survey: Survey): boolean {\n if (!survey.conditions?.url) {\n return true\n }\n\n return surveyUrlValidationMap[survey.conditions?.urlMatchType ?? 'icontains'](survey.conditions.url)\n}\n\nexport class PostHogSurveys {\n private _decideServerResponse?: boolean\n public _surveyEventReceiver: SurveyEventReceiver | null\n private _surveyManager: any\n\n constructor(private readonly instance: PostHog) {\n // we set this to undefined here because we need the persistence storage for this type\n // but that's not initialized until loadIfEnabled is called.\n this._surveyEventReceiver = null\n }\n\n onRemoteConfig(response: RemoteConfig) {\n this._decideServerResponse = !!response['surveys']\n logger.info(`decideServerResponse set to ${this._decideServerResponse}`)\n\n this.loadIfEnabled()\n }\n\n reset(): void {\n localStorage.removeItem('lastSeenSurveyDate')\n const surveyKeys = getSurveySeenStorageKeys()\n surveyKeys.forEach((key) => localStorage.removeItem(key))\n }\n\n loadIfEnabled() {\n if (this._surveyManager) {\n // Surveys already loaded.\n return\n }\n\n const disableSurveys = this.instance.config.disable_surveys\n\n if (disableSurveys) {\n logger.info('Disabled. Not loading surveys.')\n return\n }\n\n const phExtensions = assignableWindow?.__PosthogExtensions__\n\n if (!phExtensions) {\n logger.error('PostHog Extensions not found.')\n return\n }\n\n const generateSurveys = phExtensions.generateSurveys\n\n if (!this._decideServerResponse) {\n logger.warn('Decide not loaded yet. Not loading surveys.')\n return\n }\n\n if (this._surveyEventReceiver == null) {\n this._surveyEventReceiver = new SurveyEventReceiver(this.instance)\n }\n\n if (!generateSurveys) {\n const loadExternalDependency = phExtensions.loadExternalDependency\n\n if (loadExternalDependency) {\n loadExternalDependency(this.instance, 'surveys', (err) => {\n if (err) {\n logger.error('Could not load surveys script', err)\n return\n }\n\n this._surveyManager = phExtensions.generateSurveys?.(this.instance)\n })\n } else {\n logger.error('PostHog loadExternalDependency extension not found. Cannot load remote config.')\n }\n } else {\n this._surveyManager = generateSurveys(this.instance)\n }\n }\n\n getSurveys(callback: SurveyCallback, forceReload = false) {\n // In case we manage to load the surveys script, but config says not to load surveys\n // then we shouldn't return survey data\n if (this.instance.config.disable_surveys) {\n logger.info('Disabled. Not loading surveys.')\n\n return callback([])\n }\n\n if (this._surveyEventReceiver == null) {\n this._surveyEventReceiver = new SurveyEventReceiver(this.instance)\n }\n\n const existingSurveys = this.instance.get_property(SURVEYS)\n\n if (!existingSurveys || forceReload) {\n this.instance._send_request({\n url: this.instance.requestRouter.endpointFor(\n 'api',\n `/api/surveys/?token=${this.instance.config.token}`\n ),\n method: 'GET',\n callback: (response) => {\n const statusCode = response.statusCode\n if (statusCode !== 200 || !response.json) {\n logger.error(`Surveys API could not be loaded, status: ${statusCode}`)\n return callback([])\n }\n const surveys = response.json.surveys || []\n\n const eventOrActionBasedSurveys = surveys.filter(\n (survey: Survey) =>\n (survey.conditions?.events &&\n survey.conditions?.events?.values &&\n survey.conditions?.events?.values?.length > 0) ||\n (survey.conditions?.actions &&\n survey.conditions?.actions?.values &&\n survey.conditions?.actions?.values?.length > 0)\n )\n\n if (eventOrActionBasedSurveys.length > 0) {\n this._surveyEventReceiver?.register(eventOrActionBasedSurveys)\n }\n\n this.instance.persistence?.register({ [SURVEYS]: surveys })\n return callback(surveys)\n },\n })\n } else {\n logger.info('Surveys already loaded, using existing data.')\n return callback(existingSurveys)\n }\n }\n\n getActiveMatchingSurveys(callback: SurveyCallback, forceReload = false) {\n this.getSurveys((surveys) => {\n const activeSurveys = surveys.filter((survey) => {\n return !!(survey.start_date && !survey.end_date)\n })\n\n const conditionMatchedSurveys = activeSurveys.filter((survey) => {\n if (!survey.conditions) {\n return true\n }\n\n const urlCheck = doesSurveyUrlMatch(survey)\n const selectorCheck = survey.conditions?.selector\n ? document?.querySelector(survey.conditions.selector)\n : true\n return urlCheck && selectorCheck\n })\n\n // get all the surveys that have been activated so far with user actions.\n const activatedSurveys: string[] | undefined = this._surveyEventReceiver?.getSurveys()\n const targetingMatchedSurveys = conditionMatchedSurveys.filter((survey) => {\n if (\n !survey.linked_flag_key &&\n !survey.targeting_flag_key &&\n !survey.internal_targeting_flag_key &&\n !survey.feature_flag_keys?.length\n ) {\n return true\n }\n const linkedFlagCheck = survey.linked_flag_key\n ? this.instance.featureFlags.isFeatureEnabled(survey.linked_flag_key)\n : true\n const targetingFlagCheck = survey.targeting_flag_key\n ? this.instance.featureFlags.isFeatureEnabled(survey.targeting_flag_key)\n : true\n\n const hasEvents =\n survey.conditions?.events &&\n survey.conditions?.events?.values &&\n survey.conditions?.events?.values.length > 0\n\n const hasActions =\n survey.conditions?.actions &&\n survey.conditions?.actions?.values &&\n survey.conditions?.actions?.values.length > 0\n const eventBasedTargetingFlagCheck =\n hasEvents || hasActions ? activatedSurveys?.includes(survey.id) : true\n\n const overrideInternalTargetingFlagCheck = this._canActivateRepeatedly(survey)\n const internalTargetingFlagCheck =\n survey.internal_targeting_flag_key && !overrideInternalTargetingFlagCheck\n ? this.instance.featureFlags.isFeatureEnabled(survey.internal_targeting_flag_key)\n : true\n const flagsCheck = this.checkFlags(survey)\n return (\n linkedFlagCheck &&\n targetingFlagCheck &&\n internalTargetingFlagCheck &&\n eventBasedTargetingFlagCheck &&\n flagsCheck\n )\n })\n\n return callback(targetingMatchedSurveys)\n }, forceReload)\n }\n\n checkFlags(survey: Survey): boolean {\n if (!survey.feature_flag_keys?.length) {\n return true\n }\n\n return survey.feature_flag_keys.every(({ key, value }) => {\n if (!key || !value) {\n return true\n }\n return this.instance.featureFlags.isFeatureEnabled(value)\n })\n }\n getNextSurveyStep = getNextSurveyStep\n\n // this method is lazily loaded onto the window to avoid loading preact and other dependencies if surveys is not enabled\n private _canActivateRepeatedly(survey: Survey) {\n if (isNullish(assignableWindow.__PosthogExtensions__?.canActivateRepeatedly)) {\n logger.warn('init was not called')\n return false // TODO does it make sense to have a default here?\n }\n return assignableWindow.__PosthogExtensions__.canActivateRepeatedly(survey)\n }\n\n canRenderSurvey(surveyId: string) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n this.getSurveys((surveys) => {\n const survey = surveys.filter((x) => x.id === surveyId)[0]\n this._surveyManager.canRenderSurvey(survey)\n })\n }\n\n renderSurvey(surveyId: string, selector: string) {\n if (isNullish(this._surveyManager)) {\n logger.warn('init was not called')\n return\n }\n this.getSurveys((surveys) => {\n const survey = surveys.filter((x) => x.id === surveyId)[0]\n this._surveyManager.renderSurvey(survey, document?.querySelector(selector))\n })\n }\n}\n","import{options as n}from\"preact\";var t,r,u,i,o=0,f=[],c=[],e=n.__b,a=n.__r,v=n.diffed,l=n.__c,m=n.unmount;function d(t,u){n.__h&&n.__h(r,t,o||u),o=0;var i=r.__H||(r.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({__V:c}),i.__[t]}function h(n){return o=1,s(B,n)}function s(n,u,i){var o=d(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):B(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=!1;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),!(!i&&o.__c.props===n)&&(!c||c.call(this,n,t,r))};r.u=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function p(u,i){var o=d(t++,3);!n.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__H.__h.push(o))}function y(u,i){var o=d(t++,4);!n.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__h.push(o))}function _(n){return o=5,F(function(){return{current:n}},[])}function A(n,t,r){o=6,y(function(){return\"function\"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function F(n,r){var u=d(t++,7);return z(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function T(n,t){return o=8,F(function(){return n},t)}function q(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function x(t,r){n.useDebugValue&&n.useDebugValue(r?r(t):t)}function P(n){var u=d(t++,10),i=h();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function V(){var n=d(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function b(){for(var t;t=f.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(k),t.__H.__h.forEach(w),t.__H.__h=[]}catch(r){t.__H.__h=[],n.__e(r,t.__v)}}n.__b=function(n){r=null,e&&e(n)},n.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=c,n.__N=n.i=void 0})):(i.__h.forEach(k),i.__h.forEach(w),i.__h=[],t=0)),u=r},n.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==f.push(o)&&i===n.requestAnimationFrame||((i=n.requestAnimationFrame)||j)(b)),o.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==c&&(n.__=n.__V),n.i=void 0,n.__V=c})),u=r=null},n.__c=function(t,r){r.some(function(t){try{t.__h.forEach(k),t.__h=t.__h.filter(function(n){return!n.__||w(n)})}catch(u){r.some(function(n){n.__h&&(n.__h=[])}),r=[],n.__e(u,t.__v)}}),l&&l(t,r)},n.unmount=function(t){m&&m(t);var r,u=t.__c;u&&u.__H&&(u.__H.__.forEach(function(n){try{k(n)}catch(n){r=n}}),u.__H=void 0,r&&n.__e(r,u.__v))};var g=\"function\"==typeof requestAnimationFrame;function j(n){var t,r=function(){clearTimeout(u),g&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);g&&(t=requestAnimationFrame(r))}function k(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function w(n){var t=r;n.__c=n.__(),r=t}function z(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function B(n,t){return\"function\"==typeof t?t(n):t}export{T as useCallback,q as useContext,x as useDebugValue,p as useEffect,P as useErrorBoundary,V as useId,A as useImperativeHandle,y as useLayoutEffect,F as useMemo,s as useReducer,_ as useRef,h as useState};\n//# sourceMappingURL=hooks.module.js.map\n","export const satisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146 272q66 0 121.5-35.5T682-393h-52q-23 40-63 61.5T480.5-310q-46.5 0-87-21T331-393h-53q26 61 81 96.5T480-261Zm0 181q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const neutralEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm20 194h253v-49H354v49ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const dissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146.174 116Q413-417 358.5-379.5T278-280h53q22-42 62.173-65t87.5-23Q528-368 567.5-344.5T630-280h52q-25-63-79.826-100-54.826-37-122-37ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const veryDissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M480-417q-67 0-121.5 37.5T278-280h404q-25-63-80-100t-122-37Zm-183-72 50-45 45 45 31-36-45-45 45-45-31-36-45 45-50-45-31 36 45 45-45 45 31 36Zm272 0 44-45 51 45 31-36-45-45 45-45-31-36-51 45-44-45-31 36 44 45-44 45 31 36ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142 0 241-99t99-241q0-142-99-241t-241-99q-142 0-241 99t-99 241q0 142 99 241t241 99Z\" />\n </svg>\n)\nexport const verySatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M479.504-261Q537-261 585.5-287q48.5-26 78.5-72.4 6-11.6-.75-22.6-6.75-11-20.25-11H316.918Q303-393 296.5-382t-.5 22.6q30 46.4 78.5 72.4 48.5 26 105.004 26ZM347-578l27 27q7.636 8 17.818 8Q402-543 410-551q8-8 8-18t-8-18l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.636-8 17.818Q276-559 284-551q8 8 18 8t18-8l27-27Zm267 0 27 27q7.714 8 18 8t18-8q8-7.636 8-17.818Q685-579 677-587l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.714-8 18t8 18q7.636 8 17.818 8Q579-543 587-551l27-27ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const cancelSVG = (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M0.164752 0.164752C0.384422 -0.0549175 0.740578 -0.0549175 0.960248 0.164752L6 5.20451L11.0398 0.164752C11.2594 -0.0549175 11.6156 -0.0549175 11.8352 0.164752C12.0549 0.384422 12.0549 0.740578 11.8352 0.960248L6.79549 6L11.8352 11.0398C12.0549 11.2594 12.0549 11.6156 11.8352 11.8352C11.6156 12.0549 11.2594 12.0549 11.0398 11.8352L6 6.79549L0.960248 11.8352C0.740578 12.0549 0.384422 12.0549 0.164752 11.8352C-0.0549175 11.6156 -0.0549175 11.2594 0.164752 11.0398L5.20451 6L0.164752 0.960248C-0.0549175 0.740578 -0.0549175 0.384422 0.164752 0.164752Z\"\n fill=\"black\"\n />\n </svg>\n)\nexport const IconPosthogLogo = (\n <svg width=\"77\" height=\"14\" viewBox=\"0 0 77 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_2415_6911)\">\n <mask\n id=\"mask0_2415_6911\"\n style={{ maskType: 'luminance' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width=\"77\"\n height=\"14\"\n >\n <path d=\"M0.5 0H76.5V14H0.5V0Z\" fill=\"white\" />\n </mask>\n <g mask=\"url(#mask0_2415_6911)\">\n <path\n d=\"M5.77226 8.02931C5.59388 8.37329 5.08474 8.37329 4.90634 8.02931L4.4797 7.20672C4.41155 7.07535 4.41155 6.9207 4.4797 6.78933L4.90634 5.96669C5.08474 5.62276 5.59388 5.62276 5.77226 5.96669L6.19893 6.78933C6.26709 6.9207 6.26709 7.07535 6.19893 7.20672L5.77226 8.02931ZM5.77226 12.6946C5.59388 13.0386 5.08474 13.0386 4.90634 12.6946L4.4797 11.872C4.41155 11.7406 4.41155 11.586 4.4797 11.4546L4.90634 10.632C5.08474 10.288 5.59388 10.288 5.77226 10.632L6.19893 11.4546C6.26709 11.586 6.26709 11.7406 6.19893 11.872L5.77226 12.6946Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M0.5 10.9238C0.5 10.508 1.02142 10.2998 1.32637 10.5938L3.54508 12.7327C3.85003 13.0267 3.63405 13.5294 3.20279 13.5294H0.984076C0.716728 13.5294 0.5 13.3205 0.5 13.0627V10.9238ZM0.5 8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.19753 13.3927C5.28831 13.4802 5.41144 13.5294 5.53982 13.5294H8.0421C8.47337 13.5294 8.68936 13.0267 8.3844 12.7327L1.32637 5.92856C1.02142 5.63456 0.5 5.84278 0.5 6.25854V8.67083ZM0.5 4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L10.0368 13.3927C10.1276 13.4802 10.2508 13.5294 10.3791 13.5294H12.8814C13.3127 13.5294 13.5287 13.0267 13.2237 12.7327L1.32637 1.26329C1.02142 0.969312 0.5 1.17752 0.5 1.59327V4.00556ZM5.33931 4.00556C5.33931 4.12932 5.39033 4.24802 5.4811 4.33554L14.1916 12.7327C14.4965 13.0267 15.0179 12.8185 15.0179 12.4028V9.99047C15.0179 9.86671 14.9669 9.74799 14.8762 9.66049L6.16568 1.26329C5.86071 0.969307 5.33931 1.17752 5.33931 1.59327V4.00556ZM11.005 1.26329C10.7 0.969307 10.1786 1.17752 10.1786 1.59327V4.00556C10.1786 4.12932 10.2296 4.24802 10.3204 4.33554L14.1916 8.06748C14.4965 8.36148 15.0179 8.15325 15.0179 7.7375V5.3252C15.0179 5.20144 14.9669 5.08272 14.8762 4.99522L11.005 1.26329Z\"\n fill=\"#F9BD2B\"\n />\n <path\n d=\"M21.0852 10.981L16.5288 6.58843C16.2238 6.29443 15.7024 6.50266 15.7024 6.91841V13.0627C15.7024 13.3205 15.9191 13.5294 16.1865 13.5294H23.2446C23.5119 13.5294 23.7287 13.3205 23.7287 13.0627V12.5032C23.7287 12.2455 23.511 12.0396 23.2459 12.0063C22.4323 11.9042 21.6713 11.546 21.0852 10.981ZM18.0252 12.0365C17.5978 12.0365 17.251 11.7021 17.251 11.2901C17.251 10.878 17.5978 10.5436 18.0252 10.5436C18.4527 10.5436 18.7996 10.878 18.7996 11.2901C18.7996 11.7021 18.4527 12.0365 18.0252 12.0365Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M0.5 13.0627C0.5 13.3205 0.716728 13.5294 0.984076 13.5294H3.20279C3.63405 13.5294 3.85003 13.0267 3.54508 12.7327L1.32637 10.5938C1.02142 10.2998 0.5 10.508 0.5 10.9238V13.0627ZM5.33931 5.13191L1.32637 1.26329C1.02142 0.969306 0.5 1.17752 0.5 1.59327V4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L5.33931 8.86412V5.13191ZM1.32637 5.92855C1.02142 5.63455 0.5 5.84278 0.5 6.25853V8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.33931 13.5294V9.79717L1.32637 5.92855Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M10.1787 5.3252C10.1787 5.20144 10.1277 5.08272 10.0369 4.99522L6.16572 1.26329C5.8608 0.969306 5.33936 1.17752 5.33936 1.59327V4.00556C5.33936 4.12932 5.39037 4.24802 5.48114 4.33554L10.1787 8.86412V5.3252ZM5.33936 13.5294H8.04214C8.47341 13.5294 8.6894 13.0267 8.38443 12.7327L5.33936 9.79717V13.5294ZM5.33936 5.13191V8.67083C5.33936 8.79459 5.39037 8.91331 5.48114 9.00081L10.1787 13.5294V9.99047C10.1787 9.86671 10.1277 9.74803 10.0369 9.66049L5.33936 5.13191Z\"\n fill=\"#F54E00\"\n />\n <path\n d=\"M29.375 11.6667H31.3636V8.48772H33.0249C34.8499 8.48772 36.0204 7.4443 36.0204 5.83052C36.0204 4.21681 34.8499 3.17334 33.0249 3.17334H29.375V11.6667ZM31.3636 6.84972V4.81136H32.8236C33.5787 4.81136 34.0318 5.19958 34.0318 5.83052C34.0318 6.4615 33.5787 6.84972 32.8236 6.84972H31.3636ZM39.618 11.7637C41.5563 11.7637 42.9659 10.429 42.9659 8.60905C42.9659 6.78905 41.5563 5.45438 39.618 5.45438C37.6546 5.45438 36.2701 6.78905 36.2701 8.60905C36.2701 10.429 37.6546 11.7637 39.618 11.7637ZM38.1077 8.60905C38.1077 7.63838 38.7118 6.97105 39.618 6.97105C40.5116 6.97105 41.1157 7.63838 41.1157 8.60905C41.1157 9.57972 40.5116 10.2471 39.618 10.2471C38.7118 10.2471 38.1077 9.57972 38.1077 8.60905ZM46.1482 11.7637C47.6333 11.7637 48.6402 10.8658 48.6402 9.81025C48.6402 7.33505 45.2294 8.13585 45.2294 7.16518C45.2294 6.8983 45.5189 6.72843 45.9342 6.72843C46.3622 6.72843 46.8782 6.98318 47.0418 7.54132L48.527 6.94678C48.2375 6.06105 47.1677 5.45438 45.8713 5.45438C44.4743 5.45438 43.6058 6.25518 43.6058 7.21372C43.6058 9.53118 46.9663 8.88812 46.9663 9.84665C46.9663 10.1864 46.6391 10.417 46.1482 10.417C45.4434 10.417 44.9525 9.94376 44.8015 9.3735L43.3164 9.93158C43.6436 10.8537 44.6001 11.7637 46.1482 11.7637ZM53.4241 11.606L53.2982 10.0651C53.0843 10.1743 52.8074 10.2106 52.5808 10.2106C52.1278 10.2106 51.8257 9.89523 51.8257 9.34918V7.03172H53.3612V5.55145H51.8257V3.78001H49.9755V5.55145H48.9687V7.03172H49.9755V9.57972C49.9755 11.06 51.0202 11.7637 52.3921 11.7637C52.7696 11.7637 53.122 11.7031 53.4241 11.606ZM59.8749 3.17334V6.47358H56.376V3.17334H54.3874V11.6667H56.376V8.11158H59.8749V11.6667H61.8761V3.17334H59.8749ZM66.2899 11.7637C68.2281 11.7637 69.6378 10.429 69.6378 8.60905C69.6378 6.78905 68.2281 5.45438 66.2899 5.45438C64.3265 5.45438 62.942 6.78905 62.942 8.60905C62.942 10.429 64.3265 11.7637 66.2899 11.7637ZM64.7796 8.60905C64.7796 7.63838 65.3837 6.97105 66.2899 6.97105C67.1835 6.97105 67.7876 7.63838 67.7876 8.60905C67.7876 9.57972 67.1835 10.2471 66.2899 10.2471C65.3837 10.2471 64.7796 9.57972 64.7796 8.60905ZM73.2088 11.4725C73.901 11.4725 74.5177 11.242 74.845 10.8416V11.424C74.845 12.1034 74.2786 12.5767 73.4102 12.5767C72.7935 12.5767 72.2523 12.2854 72.1642 11.788L70.4776 12.0428C70.7042 13.1955 71.925 13.972 73.4102 13.972C75.361 13.972 76.6574 12.8679 76.6574 11.2298V5.55145H74.8324V6.07318C74.4926 5.69705 73.9136 5.45438 73.171 5.45438C71.409 5.45438 70.3014 6.61918 70.3014 8.46345C70.3014 10.3077 71.409 11.4725 73.2088 11.4725ZM72.1012 8.46345C72.1012 7.55345 72.655 6.97105 73.5109 6.97105C74.3793 6.97105 74.9331 7.55345 74.9331 8.46345C74.9331 9.37345 74.3793 9.95585 73.5109 9.95585C72.655 9.95585 72.1012 9.37345 72.1012 8.46345Z\"\n fill=\"currentColor\"\n />\n </g>\n </g>\n <defs>\n <clipPath id=\"clip0_2415_6911\">\n <rect width=\"76\" height=\"14\" fill=\"white\" transform=\"translate(0.5)\" />\n </clipPath>\n </defs>\n </svg>\n)\nexport const checkSVG = (\n <svg width=\"16\" height=\"12\" viewBox=\"0 0 16 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.30769 10.6923L4.77736 11.2226C4.91801 11.3633 5.10878 11.4423 5.30769 11.4423C5.5066 11.4423 5.69737 11.3633 5.83802 11.2226L5.30769 10.6923ZM15.5303 1.53033C15.8232 1.23744 15.8232 0.762563 15.5303 0.46967C15.2374 0.176777 14.7626 0.176777 14.4697 0.46967L15.5303 1.53033ZM1.53033 5.85429C1.23744 5.56139 0.762563 5.56139 0.46967 5.85429C0.176777 6.14718 0.176777 6.62205 0.46967 6.91495L1.53033 5.85429ZM5.83802 11.2226L15.5303 1.53033L14.4697 0.46967L4.77736 10.162L5.83802 11.2226ZM0.46967 6.91495L4.77736 11.2226L5.83802 10.162L1.53033 5.85429L0.46967 6.91495Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n","import { IconPosthogLogo } from '../icons'\n// import { getContrastingTextColor } from '../surveys-utils'\n\nexport function PostHogLogo() {\n // const textColor = getContrastingTextColor(backgroundColor)\n\n return (\n <a\n href=\"https://posthog.com\"\n target=\"_blank\"\n rel=\"noopener\"\n // style={{ backgroundColor: backgroundColor, color: textColor }}\n className=\"footer-branding\"\n >\n Survey by {IconPosthogLogo}\n </a>\n )\n}\n","import { window } from '../../../utils/globals'\n\nimport { SurveyAppearance } from '../../../posthog-surveys-types'\n\nimport { useContext } from 'preact/hooks'\nimport { SurveyContext, defaultSurveyAppearance, getContrastingTextColor } from '../surveys-utils'\nimport { PostHogLogo } from './PostHogLogo'\n\nexport function BottomSection({\n text,\n submitDisabled,\n appearance,\n onSubmit,\n link,\n onPreviewSubmit,\n}: {\n text: string\n submitDisabled: boolean\n appearance: SurveyAppearance\n onSubmit: () => void\n link?: string | null\n onPreviewSubmit?: () => void\n}) {\n const { isPreviewMode, isPopup } = useContext(SurveyContext)\n const textColor =\n appearance.submitButtonTextColor ||\n getContrastingTextColor(appearance.submitButtonColor || defaultSurveyAppearance.submitButtonColor)\n return (\n <div className=\"bottom-section\">\n <div className=\"buttons\">\n <button\n className=\"form-submit\"\n disabled={submitDisabled && !isPreviewMode}\n type=\"button\"\n style={isPopup ? { color: textColor } : {}}\n onClick={() => {\n if (isPreviewMode) {\n onPreviewSubmit?.()\n return\n }\n if (link) {\n window?.open(link)\n }\n onSubmit()\n }}\n >\n {text}\n </button>\n </div>\n {!appearance.whiteLabel && <PostHogLogo />}\n </div>\n )\n}\n","import { SurveyContext, defaultSurveyAppearance, renderChildrenAsTextOrHtml } from '../surveys-utils'\nimport { cancelSVG } from '../icons'\nimport { useContext } from 'preact/hooks'\nimport { SurveyQuestionDescriptionContentType } from '../../../posthog-surveys-types'\nimport { h } from 'preact'\n\nexport function QuestionHeader({\n question,\n description,\n descriptionContentType,\n backgroundColor,\n forceDisableHtml,\n}: {\n question: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n forceDisableHtml: boolean\n backgroundColor?: string\n}) {\n const { isPopup } = useContext(SurveyContext)\n return (\n <div style={isPopup ? { backgroundColor: backgroundColor || defaultSurveyAppearance.backgroundColor } : {}}>\n <div className=\"survey-question\">{question}</div>\n {description &&\n renderChildrenAsTextOrHtml({\n component: h('div', { className: 'survey-question-description' }),\n children: description,\n renderAsHtml: !forceDisableHtml && descriptionContentType !== 'text',\n })}\n </div>\n )\n}\n\nexport function Cancel({ onClick }: { onClick: () => void }) {\n const { isPreviewMode } = useContext(SurveyContext)\n\n return (\n <div className=\"cancel-btn-wrapper\" onClick={onClick} disabled={isPreviewMode}>\n <button className=\"form-cancel\" onClick={onClick} disabled={isPreviewMode}>\n {cancelSVG}\n </button>\n </div>\n )\n}\n","import { BottomSection } from './BottomSection'\nimport { Cancel } from './QuestionHeader'\nimport { SurveyAppearance, SurveyQuestionDescriptionContentType } from '../../../posthog-surveys-types'\nimport { defaultSurveyAppearance, getContrastingTextColor, renderChildrenAsTextOrHtml } from '../surveys-utils'\nimport { h } from 'preact'\n\nimport { useContext } from 'preact/hooks'\nimport { SurveyContext } from '../../surveys/surveys-utils'\n\nexport function ConfirmationMessage({\n header,\n description,\n contentType,\n forceDisableHtml,\n appearance,\n onClose,\n styleOverrides,\n}: {\n header: string\n description: string\n forceDisableHtml: boolean\n contentType?: SurveyQuestionDescriptionContentType\n appearance: SurveyAppearance\n onClose: () => void\n styleOverrides?: React.CSSProperties\n}) {\n const textColor = getContrastingTextColor(appearance.backgroundColor || defaultSurveyAppearance.backgroundColor)\n\n const { isPopup } = useContext(SurveyContext)\n\n return (\n <>\n <div className=\"thank-you-message\" style={{ ...styleOverrides }}>\n <div className=\"thank-you-message-container\">\n {isPopup && <Cancel onClick={() => onClose()} />}\n <h3 className=\"thank-you-message-header\" style={{ color: textColor }}>\n {header}\n </h3>\n {description &&\n renderChildrenAsTextOrHtml({\n component: h('div', { className: 'thank-you-message-body' }),\n children: description,\n renderAsHtml: !forceDisableHtml && contentType !== 'text',\n style: { color: textColor },\n })}\n {isPopup && (\n <BottomSection\n text={appearance.thankYouMessageCloseButtonText || 'Close'}\n submitDisabled={false}\n appearance={appearance}\n onSubmit={() => onClose()}\n />\n )}\n </div>\n </div>\n </>\n )\n}\n","import { useEffect, useRef, useState } from 'preact/hooks'\nimport { SurveyAppearance } from '../../../posthog-surveys-types'\nimport * as Preact from 'preact'\nimport { getTextColor } from '../surveys-utils'\n\nexport function useContrastingTextColor(options: {\n appearance: SurveyAppearance\n defaultTextColor?: string\n forceUpdate?: boolean\n}): {\n ref: Preact.RefObject<HTMLElement>\n textColor: string\n} {\n const ref = useRef<HTMLElement>(null)\n const [textColor, setTextColor] = useState(options.defaultTextColor ?? 'black')\n\n // TODO: useContext to get the background colors instead of querying the DOM\n useEffect(() => {\n if (ref.current) {\n const color = getTextColor(ref.current)\n setTextColor(color)\n }\n }, [options.appearance, options.forceUpdate])\n\n return {\n ref,\n textColor,\n }\n}\n","import { RefObject } from 'preact'\nimport { useMemo, useRef, useState } from 'preact/hooks'\nimport {\n BasicSurveyQuestion,\n LinkSurveyQuestion,\n MultipleSurveyQuestion,\n RatingSurveyQuestion,\n SurveyAppearance,\n SurveyQuestionType,\n} from '../../../posthog-surveys-types'\nimport { isArray, isNull } from '../../../utils/type-utils'\nimport { useContrastingTextColor } from '../hooks/useContrastingTextColor'\nimport {\n checkSVG,\n dissatisfiedEmoji,\n neutralEmoji,\n satisfiedEmoji,\n veryDissatisfiedEmoji,\n verySatisfiedEmoji,\n} from '../icons'\nimport { getDisplayOrderChoices } from '../surveys-utils'\nimport { BottomSection } from './BottomSection'\nimport { QuestionHeader } from './QuestionHeader'\n\ninterface CommonProps {\n forceDisableHtml: boolean\n appearance: SurveyAppearance\n onSubmit: (res: string | string[] | number | null) => void\n onPreviewSubmit: (res: string | string[] | number | null) => void\n}\n\nexport function OpenTextQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: BasicSurveyQuestion\n}) {\n const textRef = useRef(null)\n const [text, setText] = useState('')\n\n return (\n <div ref={textRef}>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n backgroundColor={appearance.backgroundColor}\n forceDisableHtml={forceDisableHtml}\n />\n <textarea rows={4} placeholder={appearance?.placeholder} onInput={(e) => setText(e.currentTarget.value)} />\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={!text && !question.optional}\n appearance={appearance}\n onSubmit={() => onSubmit(text)}\n onPreviewSubmit={() => onPreviewSubmit(text)}\n />\n </div>\n )\n}\n\nexport function LinkQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: LinkSurveyQuestion\n}) {\n return (\n <>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n forceDisableHtml={forceDisableHtml}\n />\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={false}\n link={question.link}\n appearance={appearance}\n onSubmit={() => onSubmit('link clicked')}\n onPreviewSubmit={() => onPreviewSubmit('link clicked')}\n />\n </>\n )\n}\n\nexport function RatingQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: RatingSurveyQuestion\n displayQuestionIndex: number\n}) {\n const scale = question.scale\n const starting = question.scale === 10 ? 0 : 1\n const [rating, setRating] = useState<number | null>(null)\n\n return (\n <>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n forceDisableHtml={forceDisableHtml}\n backgroundColor={appearance.backgroundColor}\n />\n <div className=\"rating-section\">\n <div className=\"rating-options\">\n {question.display === 'emoji' && (\n <div className=\"rating-options-emoji\">\n {(question.scale === 3 ? threeScaleEmojis : fiveScaleEmojis).map((emoji, idx) => {\n const active = idx + 1 === rating\n return (\n <button\n className={`ratings-emoji question-${displayQuestionIndex}-rating-${idx} ${\n active ? 'rating-active' : null\n }`}\n value={idx + 1}\n key={idx}\n type=\"button\"\n onClick={() => {\n setRating(idx + 1)\n }}\n style={{\n fill: active\n ? appearance.ratingButtonActiveColor\n : appearance.ratingButtonColor,\n borderColor: appearance.borderColor,\n }}\n >\n {emoji}\n </button>\n )\n })}\n </div>\n )}\n {question.display === 'number' && (\n <div\n className=\"rating-options-number\"\n style={{ gridTemplateColumns: `repeat(${scale - starting + 1}, minmax(0, 1fr))` }}\n >\n {getScaleNumbers(question.scale).map((number, idx) => {\n const active = rating === number\n return (\n <RatingButton\n key={idx}\n displayQuestionIndex={displayQuestionIndex}\n active={active}\n appearance={appearance}\n num={number}\n setActiveNumber={(num) => {\n setRating(num)\n }}\n />\n )\n })}\n </div>\n )}\n </div>\n <div className=\"rating-text\">\n <div>{question.lowerBoundLabel}</div>\n <div>{question.upperBoundLabel}</div>\n </div>\n </div>\n <BottomSection\n text={question.buttonText || appearance?.submitButtonText || 'Submit'}\n submitDisabled={isNull(rating) && !question.optional}\n appearance={appearance}\n onSubmit={() => onSubmit(rating)}\n onPreviewSubmit={() => onPreviewSubmit(rating)}\n />\n </>\n )\n}\n\nexport function RatingButton({\n num,\n active,\n displayQuestionIndex,\n appearance,\n setActiveNumber,\n}: {\n num: number\n active: boolean\n displayQuestionIndex: number\n appearance: SurveyAppearance\n setActiveNumber: (num: number) => void\n}) {\n const { textColor, ref } = useContrastingTextColor({ appearance, defaultTextColor: 'black', forceUpdate: active })\n return (\n <button\n ref={ref as RefObject<HTMLButtonElement>}\n className={`ratings-number question-${displayQuestionIndex}-rating-${num} ${\n active ? 'rating-active' : null\n }`}\n type=\"button\"\n onClick={() => {\n setActiveNumber(num)\n }}\n style={{\n color: textColor,\n backgroundColor: active ? appearance.ratingButtonActiveColor : appearance.ratingButtonColor,\n borderColor: appearance.borderColor,\n }}\n >\n {num}\n </button>\n )\n}\n\nexport function MultipleChoiceQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: CommonProps & {\n question: MultipleSurveyQuestion\n displayQuestionIndex: number\n}) {\n const textRef = useRef(null)\n const choices = useMemo(() => getDisplayOrderChoices(question), [question])\n const [selectedChoices, setSelectedChoices] = useState<string | string[] | null>(\n question.type === SurveyQuestionType.MultipleChoice ? [] : null\n )\n const [openChoiceSelected, setOpenChoiceSelected] = useState(false)\n const [openEndedInput, setOpenEndedInput] = useState('')\n\n const inputType = question.type === SurveyQuestionType.SingleChoice ? 'radio' : 'checkbox'\n return (\n <div ref={textRef}>\n <QuestionHeader\n question={question.question}\n description={question.description}\n descriptionContentType={question.descriptionContentType}\n forceDisableHtml={forceDisableHtml}\n backgroundColor={appearance.backgroundColor}\n />\n <div className=\"multiple-choice-options\">\n {/* Remove the last element from the choices, if hasOpenChoice is set */}\n {/* shuffle all other options here if question.shuffleOptions is set */}\n {/* Always ensure that the open ended choice is the last option */}\n {choices.map((choice: string, idx: number) => {\n let choiceClass = 'choice-option'\n const val = choice\n const option = choice\n if (!!question.hasOpenChoice && idx === question.choices.length - 1) {\n choiceClass += ' choice-option-open'\n }\n return (\n <div className={choiceClass}>\n <input\n type={inputType}\n id={`surveyQuestion${displayQuestionIndex}Choice${idx}`}\n name={`question${displayQuestionIndex}`}\n value={val}\n disabled={!val}\n onInput={() => {\n if (question.hasOpenChoice && idx === question.choices.length - 1) {\n return setOpenChoiceSelected(!openChoiceSelected)\n }\n if (question.type === SurveyQuestionType.SingleChoice) {\n return setSelectedChoices(val)\n }\n if (\n question.type === SurveyQuestionType.MultipleChoice &&\n isArray(selectedChoices)\n ) {\n if (selectedChoices.includes(val)) {\n // filter out values because clicking on a selected choice should deselect it\n return setSelectedChoices(\n selectedChoices.filter((choice) => choice !== val)\n )\n }\n return setSelectedChoices([...selectedChoices, val])\n }\n }}\n />\n <label\n htmlFor={`surveyQuestion${displayQuestionIndex}Choice${idx}`}\n style={{ color: 'black' }}\n >\n {question.hasOpenChoice && idx === question.choices.length - 1 ? (\n <>\n <span>{option}:</span>\n <input\n type=\"text\"\n id={`surveyQuestion${displayQuestionIndex}Choice${idx}Open`}\n name={`question${displayQuestionIndex}`}\n onInput={(e) => {\n const userValue = e.currentTarget.value\n if (question.type === SurveyQuestionType.SingleChoice) {\n return setSelectedChoices(userValue)\n }\n if (\n question.type === SurveyQuestionType.MultipleChoice &&\n isArray(selectedChoices)\n ) {\n return setOpenEndedInput(userValue)\n }\n }}\n />\n </>\n ) : (\n option\n )}\n </label>\n <span className=\"choice-check\" style={{ color: 'black' }}>\n {checkSVG}\n </span>\n </div>\n )\n })}\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={\n (isNull(selectedChoices) ||\n (isArray(selectedChoices) && !openChoiceSelected && selectedChoices.length === 0) ||\n (isArray(selectedChoices) &&\n openChoiceSelected &&\n !openEndedInput &&\n selectedChoices.length === 0 &&\n !question.optional)) &&\n !question.optional\n }\n appearance={appearance}\n onSubmit={() => {\n if (openChoiceSelected && question.type === SurveyQuestionType.MultipleChoice) {\n if (isArray(selectedChoices)) {\n onSubmit([...selectedChoices, openEndedInput])\n }\n } else {\n onSubmit(selectedChoices)\n }\n }}\n onPreviewSubmit={() => {\n if (openChoiceSelected && question.type === SurveyQuestionType.MultipleChoice) {\n if (isArray(selectedChoices)) {\n onPreviewSubmit([...selectedChoices, openEndedInput])\n }\n } else {\n onPreviewSubmit(selectedChoices)\n }\n }}\n />\n </div>\n )\n}\n\nconst threeScaleEmojis = [dissatisfiedEmoji, neutralEmoji, satisfiedEmoji]\nconst fiveScaleEmojis = [veryDissatisfiedEmoji, dissatisfiedEmoji, neutralEmoji, satisfiedEmoji, verySatisfiedEmoji]\nconst fiveScaleNumbers = [1, 2, 3, 4, 5]\nconst sevenScaleNumbers = [1, 2, 3, 4, 5, 6, 7]\nconst tenScaleNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nfunction getScaleNumbers(scale: number): number[] {\n switch (scale) {\n case 5:\n return fiveScaleNumbers\n case 7:\n return sevenScaleNumbers\n case 10:\n return tenScaleNumbers\n default:\n return fiveScaleNumbers\n }\n}\n","import { PostHog } from '../posthog-core'\nimport { doesSurveyUrlMatch } from '../posthog-surveys'\nimport {\n Survey,\n SurveyAppearance,\n SurveyQuestion,\n SurveyQuestionBranchingType,\n SurveyQuestionType,\n SurveyRenderReason,\n SurveyType,\n} from '../posthog-surveys-types'\n\nimport * as Preact from 'preact'\nimport { useContext, useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport { document as _document, window as _window } from '../utils/globals'\nimport { createLogger } from '../utils/logger'\nimport { isNull, isNumber } from '../utils/type-utils'\nimport { createWidgetShadow, createWidgetStyle } from './surveys-widget'\nimport { ConfirmationMessage } from './surveys/components/ConfirmationMessage'\nimport { Cancel } from './surveys/components/QuestionHeader'\nimport {\n LinkQuestion,\n MultipleChoiceQuestion,\n OpenTextQuestion,\n RatingQuestion,\n} from './surveys/components/QuestionTypes'\nimport {\n createShadow,\n defaultSurveyAppearance,\n dismissedSurveyEvent,\n getContrastingTextColor,\n getDisplayOrderQuestions,\n getSurveySeen,\n sendSurveyEvent,\n style,\n SurveyContext,\n} from './surveys/surveys-utils'\nconst logger = createLogger('[Surveys]')\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\n\nexport class SurveyManager {\n private posthog: PostHog\n private surveyInFocus: string | null\n\n constructor(posthog: PostHog) {\n this.posthog = posthog\n // This is used to track the survey that is currently in focus. We only show one survey at a time.\n this.surveyInFocus = null\n }\n\n private canShowNextEventBasedSurvey = (): boolean => {\n // with event based surveys, we need to show the next survey without reloading the page.\n // A simple check for div elements with the class name pattern of PostHogSurvey_xyz doesn't work here\n // because preact leaves behind the div element for any surveys responded/dismissed with a <style> node.\n // To alleviate this, we check the last div in the dom and see if it has any elements other than a Style node.\n // if the last PostHogSurvey_xyz div has only one style node, we can show the next survey in the queue\n // without reloading the page.\n const surveyPopups = document.querySelectorAll(`div[class^=PostHogSurvey]`)\n if (surveyPopups.length > 0) {\n return surveyPopups[surveyPopups.length - 1].shadowRoot?.childElementCount === 1\n }\n return true\n }\n\n private handlePopoverSurvey = (survey: Survey): void => {\n const surveyWaitPeriodInDays = survey.conditions?.seenSurveyWaitPeriodInDays\n const lastSeenSurveyDate = localStorage.getItem(`lastSeenSurveyDate`)\n if (surveyWaitPeriodInDays && lastSeenSurveyDate) {\n const today = new Date()\n const diff = Math.abs(today.getTime() - new Date(lastSeenSurveyDate).getTime())\n const diffDaysFromToday = Math.ceil(diff / (1000 * 3600 * 24))\n if (diffDaysFromToday < surveyWaitPeriodInDays) {\n return\n }\n }\n\n const surveySeen = getSurveySeen(survey)\n if (!surveySeen) {\n this.addSurveyToFocus(survey.id)\n const shadow = createShadow(style(survey?.appearance), survey.id)\n Preact.render(\n <SurveyPopup\n key={'popover-survey'}\n posthog={this.posthog}\n survey={survey}\n removeSurveyFromFocus={this.removeSurveyFromFocus}\n isPopup={true}\n />,\n shadow\n )\n }\n }\n\n private handleWidget = (survey: Survey): void => {\n const shadow = createWidgetShadow(survey)\n const surveyStyleSheet = style(survey.appearance)\n shadow.appendChild(Object.assign(document.createElement('style'), { innerText: surveyStyleSheet }))\n Preact.render(\n <FeedbackWidget\n key={'feedback-survey'}\n posthog={this.posthog}\n survey={survey}\n removeSurveyFromFocus={this.removeSurveyFromFocus}\n />,\n shadow\n )\n }\n\n private handleWidgetSelector = (survey: Survey): void => {\n const selectorOnPage =\n survey.appearance?.widgetSelector && document.querySelector(survey.appearance.widgetSelector)\n if (selectorOnPage) {\n if (document.querySelectorAll(`.PostHogWidget${survey.id}`).length === 0) {\n this.handleWidget(survey)\n } else if (document.querySelectorAll(`.PostHogWidget${survey.id}`).length === 1) {\n // we have to check if user selector already has a survey listener attached to it because we always have to check if it's on the page or not\n if (!selectorOnPage.getAttribute('PHWidgetSurveyClickListener')) {\n const surveyPopup = document\n .querySelector(`.PostHogWidget${survey.id}`)\n ?.shadowRoot?.querySelector(`.survey-form`) as HTMLFormElement\n selectorOnPage.addEventListener('click', () => {\n if (surveyPopup) {\n surveyPopup.style.display = surveyPopup.style.display === 'none' ? 'block' : 'none'\n surveyPopup.addEventListener('PHSurveyClosed', () => {\n this.removeSurveyFromFocus(survey.id)\n surveyPopup.style.display = 'none'\n })\n }\n })\n selectorOnPage.setAttribute('PHWidgetSurveyClickListener', 'true')\n }\n }\n }\n }\n\n /**\n * Sorts surveys by their appearance delay in ascending order. If a survey does not have an appearance delay,\n * it is considered to have a delay of 0.\n * @param surveys\n * @returns The surveys sorted by their appearance delay\n */\n private sortSurveysByAppearanceDelay(surveys: Survey[]): Survey[] {\n return surveys.sort(\n (a, b) => (a.appearance?.surveyPopupDelaySeconds || 0) - (b.appearance?.surveyPopupDelaySeconds || 0)\n )\n }\n\n /**\n * Checks the feature flags associated with this Survey to see if the survey can be rendered.\n * @param survey\n * @param instance\n */\n public canRenderSurvey = (survey: Survey): SurveyRenderReason => {\n const renderReason: SurveyRenderReason = {\n visible: false,\n }\n\n if (survey.end_date) {\n renderReason.disabledReason = `survey was completed on ${survey.end_date}`\n return renderReason\n }\n\n if (survey.type != SurveyType.Popover) {\n renderReason.disabledReason = `Only Popover survey types can be rendered`\n return renderReason\n }\n\n const linkedFlagCheck = survey.linked_flag_key\n ? this.posthog.featureFlags.isFeatureEnabled(survey.linked_flag_key)\n : true\n\n if (!linkedFlagCheck) {\n renderReason.disabledReason = `linked feature flag ${survey.linked_flag_key} is false`\n return renderReason\n }\n\n const targetingFlagCheck = survey.targeting_flag_key\n ? this.posthog.featureFlags.isFeatureEnabled(survey.targeting_flag_key)\n : true\n\n if (!targetingFlagCheck) {\n renderReason.disabledReason = `targeting feature flag ${survey.targeting_flag_key} is false`\n return renderReason\n }\n\n const internalTargetingFlagCheck = survey.internal_targeting_flag_key\n ? this.posthog.featureFlags.isFeatureEnabled(survey.internal_targeting_flag_key)\n : true\n\n if (!internalTargetingFlagCheck) {\n renderReason.disabledReason = `internal targeting feature flag ${survey.internal_targeting_flag_key} is false`\n return renderReason\n }\n\n renderReason.visible = true\n return renderReason\n }\n\n public renderSurvey = (survey: Survey, selector: Element): void => {\n Preact.render(\n <SurveyPopup\n key={'popover-survey'}\n posthog={this.posthog}\n survey={survey}\n removeSurveyFromFocus={this.removeSurveyFromFocus}\n isPopup={false}\n />,\n selector\n )\n }\n\n public callSurveysAndEvaluateDisplayLogic = (forceReload: boolean = false): void => {\n this.posthog?.getActiveMatchingSurveys((surveys) => {\n const nonAPISurveys = surveys.filter((survey) => survey.type !== 'api')\n\n // Create a queue of surveys sorted by their appearance delay. We will evaluate the display logic\n // for each survey in the queue in order, and only display one survey at a time.\n const nonAPISurveyQueue = this.sortSurveysByAppearanceDelay(nonAPISurveys)\n\n nonAPISurveyQueue.forEach((survey) => {\n // We only evaluate the display logic for one survey at a time\n if (!isNull(this.surveyInFocus)) {\n return\n }\n if (survey.type === SurveyType.Widget) {\n if (\n survey.appearance?.widgetType === 'tab' &&\n document.querySelectorAll(`.PostHogWidget${survey.id}`).length === 0\n ) {\n this.handleWidget(survey)\n }\n if (survey.appearance?.widgetType === 'selector' && survey.appearance?.widgetSelector) {\n this.handleWidgetSelector(survey)\n }\n }\n\n if (survey.type === SurveyType.Popover && this.canShowNextEventBasedSurvey()) {\n this.handlePopoverSurvey(survey)\n }\n })\n }, forceReload)\n }\n\n private addSurveyToFocus = (id: string): void => {\n if (!isNull(this.surveyInFocus)) {\n logger.error(`Survey ${[...this.surveyInFocus]} already in focus. Cannot add survey ${id}.`)\n }\n this.surveyInFocus = id\n }\n\n private removeSurveyFromFocus = (id: string): void => {\n if (this.surveyInFocus !== id) {\n logger.error(`Survey ${id} is not in focus. Cannot remove survey ${id}.`)\n }\n this.surveyInFocus = null\n }\n\n // Expose internal state and methods for testing\n public getTestAPI() {\n return {\n addSurveyToFocus: this.addSurveyToFocus,\n removeSurveyFromFocus: this.removeSurveyFromFocus,\n surveyInFocus: this.surveyInFocus,\n canShowNextEventBasedSurvey: this.canShowNextEventBasedSurvey,\n handleWidget: this.handleWidget,\n handlePopoverSurvey: this.handlePopoverSurvey,\n handleWidgetSelector: this.handleWidgetSelector,\n sortSurveysByAppearanceDelay: this.sortSurveysByAppearanceDelay,\n }\n }\n}\n\nexport const renderSurveysPreview = ({\n survey,\n parentElement,\n previewPageIndex,\n forceDisableHtml,\n onPreviewSubmit,\n}: {\n survey: Survey\n parentElement: HTMLElement\n previewPageIndex: number\n forceDisableHtml?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n}) => {\n const surveyStyleSheet = style(survey.appearance)\n const styleElement = Object.assign(document.createElement('style'), { innerText: surveyStyleSheet })\n\n // Remove previously attached <style>\n Array.from(parentElement.children).forEach((child) => {\n if (child instanceof HTMLStyleElement) {\n parentElement.removeChild(child)\n }\n })\n\n parentElement.appendChild(styleElement)\n const textColor = getContrastingTextColor(\n survey.appearance?.backgroundColor || defaultSurveyAppearance.backgroundColor || 'white'\n )\n\n Preact.render(\n <SurveyPopup\n key=\"surveys-render-preview\"\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={{\n position: 'relative',\n right: 0,\n borderBottom: `1px solid ${survey.appearance?.borderColor}`,\n borderRadius: 10,\n color: textColor,\n }}\n onPreviewSubmit={onPreviewSubmit}\n previewPageIndex={previewPageIndex}\n removeSurveyFromFocus={() => {}}\n isPopup={true}\n />,\n parentElement\n )\n}\n\nexport const renderFeedbackWidgetPreview = ({\n survey,\n root,\n forceDisableHtml,\n}: {\n survey: Survey\n root: HTMLElement\n forceDisableHtml?: boolean\n}) => {\n const widgetStyleSheet = createWidgetStyle(survey.appearance?.widgetColor)\n const styleElement = Object.assign(document.createElement('style'), { innerText: widgetStyleSheet })\n root.appendChild(styleElement)\n Preact.render(\n <FeedbackWidget\n key={'feedback-render-preview'}\n forceDisableHtml={forceDisableHtml}\n survey={survey}\n readOnly={true}\n removeSurveyFromFocus={() => {}}\n />,\n root\n )\n}\n\n// This is the main exported function\nexport function generateSurveys(posthog: PostHog) {\n // NOTE: Important to ensure we never try and run surveys without a window environment\n if (!document || !window) {\n return\n }\n\n const surveyManager = new SurveyManager(posthog)\n surveyManager.callSurveysAndEvaluateDisplayLogic(true)\n\n // recalculate surveys every second to check if URL or selectors have changed\n setInterval(() => {\n surveyManager.callSurveysAndEvaluateDisplayLogic(false)\n }, 1000)\n return surveyManager\n}\n\nexport function usePopupVisibility(\n survey: Survey,\n posthog: PostHog | undefined,\n millisecondDelay: number,\n isPreviewMode: boolean,\n removeSurveyFromFocus: (id: string) => void\n) {\n const [isPopupVisible, setIsPopupVisible] = useState(isPreviewMode || millisecondDelay === 0)\n const [isSurveySent, setIsSurveySent] = useState(false)\n\n useEffect(() => {\n if (!posthog) {\n logger.error('usePopupVisibility hook called without a PostHog instance.')\n return\n }\n if (isPreviewMode) {\n return\n }\n\n const handleSurveyClosed = () => {\n removeSurveyFromFocus(survey.id)\n setIsPopupVisible(false)\n }\n\n const handleSurveySent = () => {\n if (!survey.appearance?.displayThankYouMessage) {\n removeSurveyFromFocus(survey.id)\n setIsPopupVisible(false)\n } else {\n setIsSurveySent(true)\n removeSurveyFromFocus(survey.id)\n if (survey.appearance?.autoDisappear) {\n setTimeout(() => {\n setIsPopupVisible(false)\n }, 5000)\n }\n }\n }\n\n const showSurvey = () => {\n setIsPopupVisible(true)\n window.dispatchEvent(new Event('PHSurveyShown'))\n posthog.capture('survey shown', {\n $survey_name: survey.name,\n $survey_id: survey.id,\n $survey_iteration: survey.current_iteration,\n $survey_iteration_start_date: survey.current_iteration_start_date,\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n })\n localStorage.setItem('lastSeenSurveyDate', new Date().toISOString())\n }\n\n const handleShowSurveyWithDelay = () => {\n const timeoutId = setTimeout(() => {\n showSurvey()\n }, millisecondDelay)\n\n return () => {\n clearTimeout(timeoutId)\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed)\n window.removeEventListener('PHSurveySent', handleSurveySent)\n }\n }\n\n const handleShowSurveyImmediately = () => {\n showSurvey()\n return () => {\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed)\n window.removeEventListener('PHSurveySent', handleSurveySent)\n }\n }\n\n window.addEventListener('PHSurveyClosed', handleSurveyClosed)\n window.addEventListener('PHSurveySent', handleSurveySent)\n\n if (millisecondDelay > 0) {\n return handleShowSurveyWithDelay()\n } else {\n return handleShowSurveyImmediately()\n }\n }, [])\n\n // Add URL change listener to hide survey when URL no longer matches\n useEffect(() => {\n if (isPreviewMode || !survey.conditions?.url) {\n return\n }\n\n const checkUrlMatch = () => {\n const urlCheck = doesSurveyUrlMatch(survey)\n if (!urlCheck) {\n setIsPopupVisible(false)\n removeSurveyFromFocus(survey.id)\n }\n }\n\n // Listen for browser back/forward browser history changes\n window.addEventListener('popstate', checkUrlMatch)\n // Listen for hash changes, for SPA frameworks that use hash-based routing\n // The hashchange event is fired when the fragment identifier of the URL has changed (the part of the URL beginning with and following the # symbol).\n window.addEventListener('hashchange', checkUrlMatch)\n\n // Listen for SPA navigation\n const originalPushState = window.history.pushState\n const originalReplaceState = window.history.replaceState\n\n window.history.pushState = function (...args) {\n originalPushState.apply(this, args)\n checkUrlMatch()\n }\n\n window.history.replaceState = function (...args) {\n originalReplaceState.apply(this, args)\n checkUrlMatch()\n }\n\n return () => {\n window.removeEventListener('popstate', checkUrlMatch)\n window.removeEventListener('hashchange', checkUrlMatch)\n window.history.pushState = originalPushState\n window.history.replaceState = originalReplaceState\n }\n }, [isPreviewMode, survey, removeSurveyFromFocus])\n\n return { isPopupVisible, isSurveySent, setIsPopupVisible }\n}\n\ninterface SurveyPopupProps {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n style?: React.CSSProperties\n previewPageIndex?: number | undefined\n removeSurveyFromFocus: (id: string) => void\n isPopup?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n}\n\nexport function SurveyPopup({\n survey,\n forceDisableHtml,\n posthog,\n style,\n previewPageIndex,\n removeSurveyFromFocus,\n isPopup,\n onPreviewSubmit = () => {},\n}: SurveyPopupProps) {\n const isPreviewMode = Number.isInteger(previewPageIndex)\n // NB: The client-side code passes the millisecondDelay in seconds, but setTimeout expects milliseconds, so we multiply by 1000\n const surveyPopupDelayMilliseconds = survey.appearance?.surveyPopupDelaySeconds\n ? survey.appearance.surveyPopupDelaySeconds * 1000\n : 0\n const { isPopupVisible, isSurveySent, setIsPopupVisible } = usePopupVisibility(\n survey,\n posthog,\n surveyPopupDelayMilliseconds,\n isPreviewMode,\n removeSurveyFromFocus\n )\n const shouldShowConfirmation = isSurveySent || previewPageIndex === survey.questions.length\n const confirmationBoxLeftStyle = style?.left && isNumber(style?.left) ? { left: style.left - 40 } : {}\n\n if (isPreviewMode) {\n style = style || {}\n style.left = 'unset'\n style.right = 'unset'\n style.transform = 'unset'\n }\n\n return isPopupVisible ? (\n <SurveyContext.Provider\n value={{\n isPreviewMode,\n previewPageIndex: previewPageIndex,\n handleCloseSurveyPopup: () => dismissedSurveyEvent(survey, posthog, isPreviewMode),\n isPopup: isPopup || false,\n onPreviewSubmit,\n }}\n >\n {!shouldShowConfirmation ? (\n <Questions\n survey={survey}\n forceDisableHtml={!!forceDisableHtml}\n posthog={posthog}\n styleOverrides={style}\n />\n ) : (\n <ConfirmationMessage\n header={survey.appearance?.thankYouMessageHeader || 'Thank you!'}\n description={survey.appearance?.thankYouMessageDescription || ''}\n forceDisableHtml={!!forceDisableHtml}\n contentType={survey.appearance?.thankYouMessageDescriptionContentType}\n appearance={survey.appearance || defaultSurveyAppearance}\n styleOverrides={{ ...style, ...confirmationBoxLeftStyle }}\n onClose={() => setIsPopupVisible(false)}\n />\n )}\n </SurveyContext.Provider>\n ) : (\n <></>\n )\n}\n\nexport function Questions({\n survey,\n forceDisableHtml,\n posthog,\n styleOverrides,\n}: {\n survey: Survey\n forceDisableHtml: boolean\n posthog?: PostHog\n styleOverrides?: React.CSSProperties\n}) {\n const textColor = getContrastingTextColor(\n survey.appearance?.backgroundColor || defaultSurveyAppearance.backgroundColor\n )\n const [questionsResponses, setQuestionsResponses] = useState({})\n const { isPreviewMode, previewPageIndex, handleCloseSurveyPopup, isPopup, onPreviewSubmit } =\n useContext(SurveyContext)\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(previewPageIndex || 0)\n const surveyQuestions = useMemo(() => getDisplayOrderQuestions(survey), [survey])\n\n // Sync preview state\n useEffect(() => {\n setCurrentQuestionIndex(previewPageIndex ?? 0)\n }, [previewPageIndex])\n\n const onNextButtonClick = ({\n res,\n originalQuestionIndex,\n displayQuestionIndex,\n }: {\n res: string | string[] | number | null\n originalQuestionIndex: number\n displayQuestionIndex: number\n }) => {\n if (!posthog) {\n logger.error('onNextButtonClick called without a PostHog instance.')\n return\n }\n\n const responseKey =\n originalQuestionIndex === 0 ? `$survey_response` : `$survey_response_${originalQuestionIndex}`\n\n setQuestionsResponses({ ...questionsResponses, [responseKey]: res })\n\n // Old SDK, no branching\n if (!posthog.getNextSurveyStep) {\n const isLastDisplayedQuestion = displayQuestionIndex === survey.questions.length - 1\n if (isLastDisplayedQuestion) {\n sendSurveyEvent({ ...questionsResponses, [responseKey]: res }, survey, posthog)\n } else {\n setCurrentQuestionIndex(displayQuestionIndex + 1)\n }\n return\n }\n\n const nextStep = posthog.getNextSurveyStep(survey, displayQuestionIndex, res)\n if (nextStep === SurveyQuestionBranchingType.End) {\n sendSurveyEvent({ ...questionsResponses, [responseKey]: res }, survey, posthog)\n } else {\n setCurrentQuestionIndex(nextStep)\n }\n }\n\n return (\n <form\n className=\"survey-form\"\n style={\n isPopup\n ? {\n color: textColor,\n borderColor: survey.appearance?.borderColor,\n ...styleOverrides,\n }\n : {}\n }\n >\n {surveyQuestions.map((question, displayQuestionIndex) => {\n const { originalQuestionIndex } = question\n\n const isVisible = isPreviewMode\n ? currentQuestionIndex === originalQuestionIndex\n : currentQuestionIndex === displayQuestionIndex\n return (\n isVisible && (\n <div\n className=\"survey-box\"\n style={\n isPopup\n ? {\n backgroundColor:\n survey.appearance?.backgroundColor ||\n defaultSurveyAppearance.backgroundColor,\n }\n : {}\n }\n >\n {isPopup && <Cancel onClick={() => handleCloseSurveyPopup()} />}\n {getQuestionComponent({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance: survey.appearance || defaultSurveyAppearance,\n onSubmit: (res) =>\n onNextButtonClick({\n res,\n originalQuestionIndex,\n displayQuestionIndex,\n }),\n onPreviewSubmit,\n })}\n </div>\n )\n )\n })}\n </form>\n )\n}\n\nexport function FeedbackWidget({\n survey,\n forceDisableHtml,\n posthog,\n readOnly,\n removeSurveyFromFocus,\n}: {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n readOnly?: boolean\n removeSurveyFromFocus: (id: string) => void\n}): JSX.Element {\n const [showSurvey, setShowSurvey] = useState(false)\n const [styleOverrides, setStyle] = useState({})\n const widgetRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n if (!posthog) {\n logger.error('FeedbackWidget called without a PostHog instance.')\n return\n }\n if (readOnly) {\n return\n }\n\n if (survey.appearance?.widgetType === 'tab') {\n if (widgetRef.current) {\n const widgetPos = widgetRef.current.getBoundingClientRect()\n const style = {\n top: '50%',\n left: parseInt(`${widgetPos.right - 360}`),\n bottom: 'auto',\n borderRadius: 10,\n borderBottom: `1.5px solid ${survey.appearance?.borderColor || '#c9c6c6'}`,\n }\n setStyle(style)\n }\n }\n if (survey.appearance?.widgetType === 'selector') {\n const widget = document.querySelector(survey.appearance.widgetSelector || '')\n widget?.addEventListener('click', () => {\n setShowSurvey(!showSurvey)\n })\n widget?.setAttribute('PHWidgetSurveyClickListener', 'true')\n }\n }, [])\n\n return (\n <>\n {survey.appearance?.widgetType === 'tab' && (\n <div\n className=\"ph-survey-widget-tab\"\n ref={widgetRef}\n onClick={() => !readOnly && setShowSurvey(!showSurvey)}\n style={{ color: getContrastingTextColor(survey.appearance.widgetColor) }}\n >\n <div className=\"ph-survey-widget-tab-icon\"></div>\n {survey.appearance?.widgetLabel || ''}\n </div>\n )}\n {showSurvey && (\n <SurveyPopup\n key={'feedback-widget-survey'}\n posthog={posthog}\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={styleOverrides}\n removeSurveyFromFocus={removeSurveyFromFocus}\n isPopup={true}\n />\n )}\n </>\n )\n}\n\ninterface GetQuestionComponentProps {\n question: SurveyQuestion\n forceDisableHtml: boolean\n displayQuestionIndex: number\n appearance: SurveyAppearance\n onSubmit: (res: string | string[] | number | null) => void\n onPreviewSubmit: (res: string | string[] | number | null) => void\n}\n\nconst getQuestionComponent = ({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n}: GetQuestionComponentProps): JSX.Element => {\n const questionComponents = {\n [SurveyQuestionType.Open]: OpenTextQuestion,\n [SurveyQuestionType.Link]: LinkQuestion,\n [SurveyQuestionType.Rating]: RatingQuestion,\n [SurveyQuestionType.SingleChoice]: MultipleChoiceQuestion,\n [SurveyQuestionType.MultipleChoice]: MultipleChoiceQuestion,\n }\n\n const commonProps = {\n question,\n forceDisableHtml,\n appearance,\n onPreviewSubmit: (res: string | string[] | number | null) => {\n onPreviewSubmit(res)\n },\n onSubmit: (res: string | string[] | number | null) => {\n onSubmit(res)\n },\n }\n\n const additionalProps: Record<SurveyQuestionType, any> = {\n [SurveyQuestionType.Open]: {},\n [SurveyQuestionType.Link]: {},\n [SurveyQuestionType.Rating]: { displayQuestionIndex },\n [SurveyQuestionType.SingleChoice]: { displayQuestionIndex },\n [SurveyQuestionType.MultipleChoice]: { displayQuestionIndex },\n }\n\n const Component = questionComponents[question.type]\n const componentProps = { ...commonProps, ...additionalProps[question.type] }\n\n return <Component {...componentProps} />\n}\n","import { Survey } from '../posthog-surveys-types'\nimport { document as _document } from '../utils/globals'\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst document = _document as Document\n\nexport function createWidgetShadow(survey: Survey) {\n const div = document.createElement('div')\n div.className = `PostHogWidget${survey.id}`\n const shadow = div.attachShadow({ mode: 'open' })\n const widgetStyleSheet = createWidgetStyle(survey.appearance?.widgetColor)\n shadow.append(Object.assign(document.createElement('style'), { innerText: widgetStyleSheet }))\n document.body.appendChild(div)\n return shadow\n}\n\nexport function createWidgetStyle(widgetColor?: string) {\n return `\n .ph-survey-widget-tab {\n position: fixed;\n top: 50%;\n right: 0;\n background: ${widgetColor || '#e0a045'};\n color: white;\n transform: rotate(-90deg) translate(0, -100%);\n transform-origin: right top;\n min-width: 40px;\n padding: 8px 12px;\n font-weight: 500;\n border-radius: 3px 3px 0 0;\n text-align: center;\n cursor: pointer;\n z-index: 9999999;\n }\n .ph-survey-widget-tab:hover {\n padding-bottom: 13px;\n }\n .ph-survey-widget-button {\n position: fixed;\n }\n `\n}\n"],"names":["SURVEYS_ACTIVATED","EMPTY_OBJ","EMPTY_ARR","IS_NON_DIMENSIONAL","__u","win","window","undefined","global","globalThis","navigator","document","location","fetch","XMLHttpRequest","AbortController","userAgent","Compression","assignableWindow","nativeIsArray","Array","isArray","toString","Object","prototype","obj","call","isUndefined","x","isNull","isNumber","_createLogger","prefix","logger","_log","level","console","consoleLog","_len","arguments","length","args","_key","info","_len2","_key2","warn","_len3","_key3","error","_len4","_key4","critical","_len5","_key5","uninitializedWarning","methodName","concat","createLogger","additionalPrefix","_window","SurveySeenPrefix","hex2rgb","c","hexColor","replace","parseInt","slice","getContrastingTextColor","rgb","color","defaultBackgroundColor","startsWith","nameColorToHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","honeydew","hotpink","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","toLowerCase","colorMatch","match","r","g","b","Math","sqrt","SurveyType","SurveyQuestionType","SurveyQuestionBranchingType","defaultSurveyAppearance","backgroundColor","submitButtonColor","submitButtonTextColor","ratingButtonColor","ratingButtonActiveColor","borderColor","placeholder","whiteLabel","displayThankYouMessage","thankYouMessageHeader","position","sendSurveyEvent","_posthog$get_session_","responses","survey","posthog","localStorage","setItem","getSurveySeenKey","capture","_objectSpread","$survey_name","name","$survey_id","id","$survey_iteration","current_iteration","$survey_iteration_start_date","current_iteration_start_date","$survey_questions","questions","map","question","sessionRecordingUrl","get_session_replay_url","$set","getSurveyInteractionProperty","dispatchEvent","Event","dismissedSurveyEvent","readOnly","_posthog$get_session_2","shuffle","array","a","sort","floor","random","value","reverseIfUnshuffled","unshuffled","shuffled","every","val","index","reverse","getDisplayOrderQuestions","forEach","idx","originalQuestionIndex","appearance","shuffleQuestions","surveySeenKey","action","surveyProperty","SurveyContext","createContext","isPreviewMode","previewPageIndex","handleCloseSurveyPopup","isPopup","onPreviewSubmit","renderChildrenAsTextOrHtml","_ref","component","children","renderAsHtml","style","cloneElement","dangerouslySetInnerHTML","__html","isUrlMatchingRegex","url","pattern","str","RegExp","_unused","isValidRegex","test","SimpleEventEmitter","constructor","_defineProperty","this","events","on","event","listener","push","filter","emit","payload","ActionMatcher","instance","step","checkStepEvent","checkStepUrl","checkStepElement","actionEvents","Set","actionRegistry","init","_this$instance","_addCaptureHook","_this$instance2","matchEventToAction","eventName","eventPayload","register","actions","_this$instance3","_this$instance4","_this$actionRegistry","_action$steps","add","steps","_this$actionEvents","autocapture","_this$instance5","selectorsToWatch","_action$steps2","selector","setElementSelectors","_this$actionRegistry2","has","size","checkAction","_debugEventEmitter","_addActionHook","callback","onAction","data","checkStep","cb","_event$properties","eventUrl","properties","$current_url","matchString","url_matching","matching","adjustedRegExpStringPattern","escapeStringRegexp","href","tag_name","text","getElementsList","some","element","href_matching","text_matching","$el_text","_event$properties2","elementSelectors","$element_selectors","includes","$elements","SurveyEventReceiver","eventToSurveys","Map","actionToSurveys","surveys","setupEventBasedSurveys","setupActionBasedSurveys","actionBasedSurveys","_survey$conditions","_survey$conditions2","_survey$conditions2$a","_survey$conditions2$a2","conditions","values","actionMatcher","actionName","_survey$conditions3","_survey$conditions4","_survey$conditions4$a","_survey$conditions5","_survey$conditions5$a","_survey$conditions5$a2","_this$actionMatcher","_survey$conditions6","_survey$conditions6$a","_survey$conditions6$a2","knownSurveys","get","set","_survey$conditions7","_survey$conditions8","_survey$conditions8$e","_survey$conditions8$e2","matchEventToSurvey","onEvent","_survey$conditions9","_survey$conditions9$e","_survey$conditions9$e2","_this$instance3$persi","existingActivatedSurveys","persistence","props","SURVEY_SHOWN_EVENT_NAME","_eventPayload$propert","surveyId","indexOf","splice","_updateActivatedSurveys","_this$instance4$persi","activatedSurveys","_this$instance5$persi","getSurveys","_this$instance6","_this$instance6$persi","getEventToSurveys","_getActionMatcher","surveyUrlValidationMap","icontains","conditionsUrl","not_icontains","regex","not_regex","exact","is_not","getNextSurveyStep","currentQuestionIndex","response","_question$branching","nextQuestionIndex","branching","type","End","SpecificQuestion","Number","isInteger","ResponseBased","SingleChoice","_question$branching2","_question$branching2$","selectedChoiceIndex","choices","responseValues","hasOwnProperty","nextStep","Rating","_question$branching3","_question$branching3$","Error","ratingBucket","responseValue","scale","getRatingBucketForResponseValue","currentIndex","currentComponent","previousComponent","prevRaf","currentHook","afterPaintEffects","EMPTY","oldBeforeDiff","options","__b","oldBeforeRender","__r","oldAfterDiff","diffed","oldCommit","__c","oldBeforeUnmount","unmount","getHookState","__h","hooks","__H","__","__V","useState","initialState","useReducer","reducer","hookState","_reducer","invokeOrReturn","n","currentValue","__N","nextValue","setState","_hasScuFromHooks","updateHookState","f","p","s","stateHooks","prevScu","shouldUpdate","hookItem","shouldComponentUpdate","prevCWU","componentWillUpdate","__e","tmp","useEffect","state","__s","argsChanged","_pendingArgs","useRef","initialValue","useMemo","current","factory","useContext","context","provider","sub","flushAfterPaintEffects","shift","__P","invokeCleanup","invokeEffect","e","__v","vnode","t","requestAnimationFrame","afterNextFrame","commitQueue","hasErrored","HAS_RAF","raf","done","clearTimeout","timeout","cancelAnimationFrame","setTimeout","hook","comp","cleanup","oldArgs","newArgs","arg","satisfiedEmoji","_jsx","className","xmlns","height","viewBox","width","d","neutralEmoji","dissatisfiedEmoji","veryDissatisfiedEmoji","verySatisfiedEmoji","cancelSVG","fill","IconPosthogLogo","_jsxs","maskType","maskUnits","y","mask","transform","checkSVG","PostHogLogo","target","rel","BottomSection","submitDisabled","onSubmit","link","textColor","disabled","onClick","open","QuestionHeader","description","descriptionContentType","forceDisableHtml","h","Cancel","_ref2","ConfirmationMessage","header","contentType","onClose","styleOverrides","_Fragment","thankYouMessageCloseButtonText","useContrastingTextColor","_options$defaultTextC","ref","setTextColor","defaultTextColor","el","getComputedStyle","getTextColor","forceUpdate","OpenTextQuestion","textRef","setText","rows","onInput","currentTarget","buttonText","optional","LinkQuestion","RatingQuestion","_ref3","displayQuestionIndex","starting","rating","setRating","display","threeScaleEmojis","fiveScaleEmojis","emoji","active","gridTemplateColumns","getScaleNumbers","number","RatingButton","num","setActiveNumber","lowerBoundLabel","upperBoundLabel","submitButtonText","_ref4","MultipleChoiceQuestion","_ref5","shuffleOptions","displayOrderChoices","openEndedChoice","hasOpenChoice","pop","shuffledOptions","getDisplayOrderChoices","selectedChoices","setSelectedChoices","MultipleChoice","openChoiceSelected","setOpenChoiceSelected","openEndedInput","setOpenEndedInput","inputType","choice","choiceClass","option","htmlFor","userValue","fiveScaleNumbers","sevenScaleNumbers","tenScaleNumbers","_document","renderSurveysPreview","_survey$appearance5","_survey$appearance6","parentElement","surveyStyleSheet","fontFamily","maxWidth","zIndex","left","right","center","styleElement","assign","createElement","innerText","from","child","HTMLStyleElement","removeChild","appendChild","Preact","SurveyPopup","borderBottom","borderRadius","removeSurveyFromFocus","renderFeedbackWidgetPreview","_survey$appearance7","widgetColor","root","widgetStyleSheet","FeedbackWidget","usePopupVisibility","millisecondDelay","isPopupVisible","setIsPopupVisible","isSurveySent","setIsSurveySent","timeoutId","handleSurveyClosed","handleSurveySent","_survey$appearance8","_survey$appearance9","autoDisappear","showSurvey","Date","toISOString","addEventListener","removeEventListener","checkUrlMatch","urlCheck","_survey$conditions$ur","urlMatchType","doesSurveyUrlMatch","originalPushState","history","pushState","originalReplaceState","replaceState","apply","_survey$appearance10","_style","_style2","_survey$appearance11","_survey$appearance12","_survey$appearance13","surveyPopupDelayMilliseconds","surveyPopupDelaySeconds","shouldShowConfirmation","confirmationBoxLeftStyle","Provider","thankYouMessageDescription","thankYouMessageDescriptionContentType","Questions","_survey$appearance14","_survey$appearance15","questionsResponses","setQuestionsResponses","setCurrentQuestionIndex","surveyQuestions","_survey$appearance16","getQuestionComponent","res","responseKey","onNextButtonClick","_ref6","_survey$appearance20","_survey$appearance21","setShowSurvey","setStyle","widgetRef","_survey$appearance17","_survey$appearance19","widgetType","_survey$appearance18","widgetPos","getBoundingClientRect","top","bottom","widget","querySelector","widgetSelector","setAttribute","widgetLabel","_ref7","questionComponents","Open","Link","commonProps","additionalProps","Component","componentProps"],"mappings":"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","x_google_ignoreList":[1,14]}