(()=>{"use strict";class Preconditions{static checkArgument(cond,msg,...args){if(!cond)throw new Error(msg==null?"invalid argument":Preconditions.format(msg,...args))}static checkState(cond,msg,...args){if(!cond)throw new Error(msg==null?"invalid state":Preconditions.format(msg,...args))}static checkEquals(a,b,msg,...args){if(a!==b)throw new Error(msg==null?Preconditions.format("{} != {}",Preconditions.stringify(a),Preconditions.stringify(b)):Preconditions.format(msg,...args))}static stringify(x){if(x==null||typeof x==="symbol")return String(x);else try{return JSON.stringify(x)}catch(e){return String(x)}}static checkExists(x,msg,...args){if(x==null)throw new Error(msg==null?"argument is null":Preconditions.format(msg,...args));return x}static format(template,...args){let i=0;return template.replace(/\{}/g,(()=>i{const maybeFullstop=opts.message.endsWith(".")?"":".";return`[${opts.code}]: ${opts.message}${maybeFullstop}`.trim()};class CanvaErrorClass extends Error{constructor(opts){opts.code=appSandboxErrorCodeMapper(opts.code);super(formattedErrorMessage(opts));this.code=opts.code;this.name="CanvaError";this.rawMessage=opts.message;Object.setPrototypeOf(this,CanvaErrorClass.prototype)}}function setAppSandboxErrorCodeMapper(mapper){appSandboxErrorCodeMapper=mapper}let appSandboxErrorCodeMapper=code=>code;class MessageBus{constructor(handler,port,errorService){this.handler=handler;this.port=port;this.errorService=errorService;this.send=message=>{try{this.port.postMessage(message);return Result.Ok()}catch(e){this.errorService.errorException(e);return Result.Err(e)}};this.onMessageError=e=>{this.errorService.errorException(e)};this.onMessage=({data})=>{if(!data){this.errorService.error(new CanvaErrorClass({code:"internal_error",message:`missing data in 'MessageEvent'`}));return}try{this.handler.receive(data)}catch(e){this.errorService.errorException(e)}};this.port.onmessage=this.onMessage;this.port.onmessageerror=this.onMessageError}}function uuidv4(rng){const randomValues=getRandomValues(rng,31);let currentRandomValue=0;return`${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g,(function(c){const cN=Number(c);return(cN^randomValues[currentRandomValue++]&15>>cN/4).toString(16)}))}const HEX_CHARS="0123456789abcdef";function uuidv7(){const bytes=Uint8Array.from(getRandomValues(undefined,16));const now=Date.now();bytes[0]=Math.trunc(now/1099511627776)&255;bytes[1]=Math.trunc(now/4294967296)&255;bytes[2]=Math.trunc(now/16777216)&255;bytes[3]=Math.trunc(now/65536)&255;bytes[4]=Math.trunc(now/256)&255;bytes[5]=now&255;bytes[6]=112|bytes[6]&15;bytes[8]=128|bytes[8]&63;let hex="";for(let i=0;i<16;i++)hex+=HEX_CHARS[bytes[i]>>>4]+HEX_CHARS[bytes[i]&15];return`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`}function getRandomValues(rng,amount){if(!rng&&typeof window!=="undefined"&&typeof window.crypto!=="undefined"&&typeof window.crypto.getRandomValues==="function")return window.crypto.getRandomValues(new Uint8Array(amount));const random=rng??Math.random;return Array.from({length:amount},(()=>Math.floor(random()*255)))}const ACK_INTERVAL=9e3;const INITIAL_ACK_TIMEOUT=2e4;const SUBSEQUENT_ACK_TIMEOUT=3e4;class PromiseTimeoutError extends Error{constructor(){super("[internal_error] Comms promise timed out.")}}const REJECT_ON_NEXT_TICK_DELAY_MS=500;class PromiseWithTimeout{reset(newTimeoutMs){if(newTimeoutMs)this.timeoutMs=newTimeoutMs;this.setTimeout()}resolve(value){clearTimeout(this.timeoutId);this.resolveFn(value)}reject(reason){clearTimeout(this.timeoutId);this.rejectFn(reason)}promise(){return this.p}rejectOnNextTick(){this.timeoutId=setTimeout((()=>{this.rejectFn(new PromiseTimeoutError)}),REJECT_ON_NEXT_TICK_DELAY_MS)}setTimeout(){clearTimeout(this.timeoutId);this.timeoutId=setTimeout((()=>{this.rejectOnNextTick()}),Math.max(this.timeoutMs-REJECT_ON_NEXT_TICK_DELAY_MS,REJECT_ON_NEXT_TICK_DELAY_MS))}constructor(timeoutMs){this.timeoutMs=timeoutMs;this.p=new Promise(((resolve,reject)=>{this.resolveFn=resolve;this.rejectFn=reject}));this.setTimeout()}}const RECENT_TIMED_OUT_REQUEST_LIMIT=32;class Client{request(path,payload){const pendingRequests=this.pendingRequests;const recentTimedOutRequests=this.recentTimedOutRequests;const requestPromise=new PromiseWithTimeout(INITIAL_ACK_TIMEOUT);const requestId=this.requestIdGenerator();const resultPromise=awaitResult();const result=this.send(requestId,path,payload);if(!result.ok){this.errorService.errorException(result.error,{errorMessagePrefix:"unable to send request",tags:new Map([["type","request"],["path",path]])});requestPromise.reject(result.error)}return resultPromise;async function awaitResult(){pendingRequests.set(requestId,{path,requestPromise});try{const response=await requestPromise.promise();return Result.Ok(response)}catch(e){if(e instanceof PromiseTimeoutError){recentTimedOutRequests.set(requestId,[path,Date.now()]);if(recentTimedOutRequests.size>RECENT_TIMED_OUT_REQUEST_LIMIT)recentTimedOutRequests.delete(recentTimedOutRequests.keys().next().value);return Result.Err(new CanvaErrorClass({code:"internal_error",message:`Comms promise timed out (${path}).`}))}return Result.Err(e)}finally{pendingRequests.delete(requestId)}}}handleReply(msg){const{requestId,type}=msg;const{path,requestPromise:request}=this.pendingRequests.get(requestId)||{};if(!request){if(type!=="ack"){const[path,timestamp]=this.recentTimedOutRequests.get(requestId)??["not_recently_timed_out",undefined];const extra=timestamp!==undefined?new Map([["time_since_timeout",Date.now()-timestamp]]):undefined;this.errorService.error(`request has already been handled and resolved or was not sent from this client`,{tags:new Map([["type",type],["path",path]]),extra})}return}switch(type){case"response":request.resolve(msg.payload);return;case"ack":request.reset(SUBSEQUENT_ACK_TIMEOUT);return;case"error":this.errorService.addBreadCrumb({level:"info",category:"sandbox_comms",message:"Error response received",data:{["path"]:path??"unknown"}});const{code,message}=msg;request.reject(new CanvaErrorClass({code,message}));return;default:throw new UnreachableError(msg)}}constructor(send,errorService,requestIdGenerator=uuidv4){this.send=send;this.errorService=errorService;this.requestIdGenerator=requestIdGenerator;this.pendingRequests=new Map;this.recentTimedOutRequests=new Map}}const RequestHandlerErrorCodes={internalError:()=>"Something went wrong on our end, if this issue persists please contact us.",noHandlerForPath:path=>`No request handler configured for path: "${path}".`,handlerForPathAlreadyDefined:path=>`Handler for '${path}' is already defined.`};class RequestHandler{addErrorObserver(observer){this.errorObservers.add(observer);return()=>this.errorObservers.delete(observer)}handle(path,handler){if(this.requestHandler.has(path))throw new CanvaErrorClass({code:"internal_error",message:RequestHandlerErrorCodes.handlerForPathAlreadyDefined(path)});this.requestHandler.set(path,handler);return()=>this.requestHandler.delete(path)}async handleRequest(body){const{requestId,path,payload}=body;const handler=this.requestHandler.get(path);if(!handler){const result=this.messenger.sendError(requestId,"internal_error",RequestHandlerErrorCodes.noHandlerForPath(path));if(!result.ok)this.errorService.criticalException(result.error,{errorMessagePrefix:"unable to send error response",tags:new Map([["type","request"],["path",path]])});return}this.messenger.sendAck(requestId);const intervalId=setInterval((()=>this.messenger.sendAck(requestId)),ACK_INTERVAL);let observableError;try{const resPayload=await handler(payload);clearInterval(intervalId);this.messenger.sendResponse(requestId,resPayload)}catch(e){clearInterval(intervalId);let errorCode="internal_error";let errorMessage=RequestHandlerErrorCodes.internalError();if(e instanceof CanvaErrorClass){observableError=e;if(e.code==="internal_error")this.errorService.errorException(e,{errorMessagePrefix:"Internal error in comms handler",tags:new Map([["type","request"],["path",path]])});else{errorCode=e.code;errorMessage=e.rawMessage}}else if(this.reportNonCanvaErrors)this.errorService.errorException(e,{errorMessagePrefix:"Unexpected error type thrown from comms handler",tags:new Map([["type","request"],["path",path]])});else this.devConsole.error(e);const result=this.messenger.sendError(requestId,errorCode,errorMessage);if(!result.ok)this.errorService.criticalException(result.error,{errorMessagePrefix:"unable to send error response",tags:new Map([["type","request"],["path",path]])})}if(observableError==null)return;for(const cb of this.errorObservers)try{cb(observableError)}catch(e){this.errorService.warningException(e,{errorMessagePrefix:"Error executing errorObserver"})}}constructor(messenger,errorService,reportNonCanvaErrors,devConsole=console){this.messenger=messenger;this.errorService=errorService;this.reportNonCanvaErrors=reportNonCanvaErrors;this.devConsole=devConsole;this.requestHandler=new Map;this.errorObservers=new Set}}class SandboxCommsBase{constructor(port,errorService,reportNonCanvaErrors){this.request=(path,payload)=>this.client.request(path,payload);this.handle=(path,handler)=>this.requestHandler.handle(path,handler);this.addErrorObserver=observer=>this.requestHandler.addErrorObserver(observer);const handleMessage=message=>{switch(message.type){case"ack":case"error":case"response":this.client.handleReply(message);return;case"request":this.requestHandler.handleRequest(message);return;default:throw new UnreachableError(message)}};const messenger=new MangleSafeMessageBus(handleMessage,port,errorService.createChild("bus"));this.client=new Client(messenger.sendRequest,errorService.createChild("client"));this.requestHandler=new RequestHandler(messenger,errorService.createChild("requestHandler"),reportNonCanvaErrors)}}class MangleSafeMessageBus{sendResponse(requestId,payload){return this.bus.send({["type"]:"response",["requestId"]:requestId,["payload"]:payload})}sendError(requestId,code,message){return this.bus.send({["type"]:"error",["requestId"]:requestId,["code"]:code,["message"]:message})}sendAck(requestId){return this.bus.send({["type"]:"ack",["requestId"]:requestId})}constructor(handleMessage,port,errorService){this.handleMessage=handleMessage;this.sendRequest=(requestId,path,payload)=>this.bus.send({["type"]:"request",["requestId"]:requestId,["path"]:path,["payload"]:payload});this.onReceive=message=>{switch(message["type"]){case"ack":this.handleMessage({type:"ack",requestId:message["requestId"]});return;case"error":this.handleMessage({type:"error",requestId:message["requestId"],code:message["code"],message:message["message"]});return;case"response":this.handleMessage({type:"response",requestId:message["requestId"],payload:message["payload"]});return;case"request":this.handleMessage({type:"request",requestId:message["requestId"],path:message["path"],payload:message["payload"]});return;default:throw new UnreachableError(message)}};this.bus=new MessageBus({receive:this.onReceive},port,errorService)}}const VerifyError={MISSING_DATA:"missing 'data' field in MessageEvent",MISSING_SOURCE:"'sandboxCommsSource' is missing in MessageEvent data object",INVALID_SOURCE:"invalid source",UNKNOWN_CLIENT_ID:"unknown client id"};function createInitialiseMessage(sandboxCommsSource,clientId){return{["sandboxCommsSource"]:sandboxCommsSource,["clientId"]:clientId}}function verifyMessage(data,expectedSource,expectedClientId){if(!data)return Result.Err("missing 'data' field in MessageEvent");const msg=data;const source=msg["sandboxCommsSource"];if(!source)return Result.Err("'sandboxCommsSource' is missing in MessageEvent data object");if(source!==expectedSource)return Result.Err("invalid source");if(msg["clientId"]!==expectedClientId)return Result.Err("unknown client id");return Result.Ok()}async function connectToParent(errorService,parentOrigin,{parent,addEventListener,removeEventListener}=window,clientId){const portPromise=Promise.withResolvers();const messageHandler=({ports,data})=>{const msg=verifyMessage(data,"parent",clientId);if(!msg.ok){switch(msg.error){case VerifyError.INVALID_SOURCE:errorService.info(msg.error,{errorMessagePrefix:"failed to verify message",extra:new Map([["data.sandboxCommsSource",data?.sandboxCommsSource]])});break;case VerifyError.MISSING_DATA:case VerifyError.MISSING_SOURCE:case VerifyError.UNKNOWN_CLIENT_ID:break;default:throw new UnreachableError(msg.error)}return}if(ports.length!==1){errorService.error("invalid number of ports received from the parent");return}const[port]=ports;portPromise.resolve(port)};addEventListener("message",messageHandler);try{const initMessage=createInitialiseMessage("iframe",clientId);parent.postMessage(initMessage,parentOrigin);const port=await portPromise.promise;return Result.Ok(new SandboxCommsBase(port,errorService.createChild("comms"),false))}catch(e){return Result.Err(e)}finally{removeEventListener("message",messageHandler)}}function isPromiseLike(p){return p!=null&&p.then!=null}function memoize(fn,{invalidateOnError}={invalidateOnError:false}){let promiseDidReject=false;let result;const memoFn=(...args)=>{Preconditions.checkArgument(args.length===0);if(result==null||invalidateOnError&&(!result.ok||promiseDidReject))try{promiseDidReject=false;result=Result.Ok(fn());if(isPromiseLike(result.value))result.value.then(null,(_e=>promiseDidReject=true))}catch(e){result=Result.Err(e)}if(result.ok)return result.value;else throw result.error};return memoFn}function memoize1(fn){const cache=new WeakMap;const memoFn=(key,...rest)=>{Preconditions.checkArgument(rest.length===0);if(!cache.has(key))cache.set(key,fn(key));return cache.get(key)};return memoFn}const MessageKind={CONCRETE:1,ONEOF:2};const FieldLabel={CONSTANT:1,REQUIRED:2,OPTIONAL:3,REPEATED:4,MAP:5};const FieldKind={PRIMITIVE:1,MESSAGE:2,ENUM:3};const makeType=t=>t;const ProtoType={STRING:makeType({typeOfValue:"string"}),BOOLEAN:makeType({typeOfValue:"boolean",defaultValue:false,fixedSize:1}),DOUBLE:makeType({typeOfValue:"number",defaultValue:0,fixedSize:8}),INT32:makeType({typeOfValue:"number",defaultValue:0}),INT64:makeType({typeOfValue:"number",defaultValue:0}),BYTES:makeType({typeOfValue:"Uint8Array"})};function makeFieldConfig(tag,fieldLabel,typeOfValue,jsonFullKey,jsonFullValue,value,defaults,defaultField,defaultValue,obj,typeOfKey){return{tag,fieldLabel,typeOfValue,jsonFullKey,jsonFullValue,value,defaults,default:defaultField,defaultValue,obj,typeOfKey}}function constantField(params){const{tag,jsonFullKeyOrJsonMiniKey,jsonFullValue,value,defaults}=params;const jsonFullKey=jsonFullKeyOrJsonMiniKey===DISCRIMINATOR_JSON_MINI_KEY?undefined:jsonFullKeyOrJsonMiniKey;return makeFieldConfig(tag,FieldLabel.CONSTANT,"string",jsonFullKey,jsonFullValue,value,defaults,undefined,undefined,undefined,undefined)}function requiredField(valueType,jsonFullKey,tag,def){return makeFieldConfig(tag,FieldLabel.REQUIRED,valueType.typeOfValue,jsonFullKey,undefined,undefined,undefined,def!=null?def:valueType.defaultValue,valueType.defaultValue,undefined,undefined)}function optionalField(valueType,jsonFullKey,tag){return makeFieldConfig(tag,FieldLabel.OPTIONAL,valueType.typeOfValue,jsonFullKey,undefined,undefined,undefined,undefined,valueType.defaultValue,undefined,undefined)}function repeatedField(valueType,jsonFullKey,tag){return makeFieldConfig(tag,FieldLabel.REPEATED,valueType.typeOfValue,jsonFullKey,undefined,undefined,undefined,undefined,undefined,undefined,undefined)}function mapField(keyType,valueType){return(tagOrJsonFullKey,tagOrObj,maybeObj)=>{const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);let typeOfValue;if(valueType==="object")typeOfValue="object";else if(valueType==="enum")typeOfValue="string";else typeOfValue=valueType.typeOfValue;return makeFieldConfig(tag,FieldLabel.MAP,typeOfValue,jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,keyType.typeOfValue)}}class Proto{static constantString(jsonFullKeyOrJsonMiniKey,jsonFullValueOrTag,tagOrValue,maybeValue){const{tag,jsonFullKey:jsonFullValue,other1:value}=getOptions(jsonFullValueOrTag,tagOrValue,maybeValue);return constantField({tag,jsonFullKeyOrJsonMiniKey,jsonFullValue,value,defaults:false})}static constantStringWithDefault(jsonFullKeyOrJsonMiniKey,jsonFullValueOrTag,tagOrValue,maybeValue){const{tag,jsonFullKey:jsonFullValue,other1:value}=getOptions(jsonFullValueOrTag,tagOrValue,maybeValue);return constantField({tag,jsonFullKeyOrJsonMiniKey,jsonFullValue,value,defaults:true})}static requiredObject(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.REQUIRED,"object",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static optionalObject(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.OPTIONAL,"object",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static repeatedObject(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.REPEATED,"object",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static requiredStringEnum(tagOrJsonFullKey,tagOrObj,objOrDef,maybeDef){const{tag,jsonFullKey,other1:obj,other2:def}=getOptions(tagOrJsonFullKey,tagOrObj,objOrDef,maybeDef);return makeFieldConfig(tag,FieldLabel.REQUIRED,"string",jsonFullKey,undefined,undefined,undefined,def,undefined,obj,undefined)}static optionalStringEnum(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.OPTIONAL,"string",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static repeatedStringEnum(tagOrJsonFullKey,tagOrObj,maybeObj){const{tag,jsonFullKey,other1:obj}=getOptions(tagOrJsonFullKey,tagOrObj,maybeObj);return makeFieldConfig(tag,FieldLabel.REPEATED,"string",jsonFullKey,undefined,undefined,undefined,undefined,undefined,obj,undefined)}static createMessage(schema,options={}){const init=memoize((()=>{const fields=schema();const fieldNames=Object.keys(fields);const fieldsByTag={};const constantsByTag={};for(let i=0;i{throw new TypeError(`Unproducible oneof case ${pathTrace(path)}`)}:(message,path)=>{if(message==null||typeof message!=="object")throw new TypeError(`Expected type object, found: ${moreSpecificTypeof(message)} ${pathTrace(path)}`);const{fieldMetadata}=init();const res={};for(let i=0;i{const config=schema();const discriminatorKey=Object.keys(config)[0];let discriminatorTag;let discriminatorJsonKeyEncodings;const nameToObject=new Map;const serializedToObject=new Map;const tagToObject=new Map;for(let i=0;i{const{discriminatorKey,nameToObject}=init();const type=t[discriminatorKey];const obj=nameToObject.get(type);if(!obj)throw new TypeError(`Unknown oneof deserialized case: ${JSON.stringify(type)} ${pathTrace(path)}`);return obj.serializeWithPath(t,path)};const deserializeWithPath=(o,path)=>{const{serializedToObject,discriminatorJsonKeyEncodings,defaultObject}=init();const{primaryJsonKey,secondaryJsonKey}=discriminatorJsonKeyEncodings;let type=o[primaryJsonKey];if(type==null&&secondaryJsonKey)type=o[secondaryJsonKey];if(type==null&&defaultObject)return defaultObject.deserializeWithPath(o,path);const obj=serializedToObject.get(type);if(!obj)throw new TypeError(`Unknown oneof serialized case: ${JSON.stringify(type)} ${pathTrace(path)}`);return obj.deserializeWithPath(o,path)};return{init,serialize:t=>serializeWithPath(t,[]),serializeWithPath,deserialize:o=>deserializeWithPath(o,[]),deserializeWithPath}}static createEnumUtil(schema,baseNumber=0,options={}){const init=memoize((()=>{const config=schema();const values=[];const serializedToValue=new Map;const valueToSerialized=new Map;const valueToProtobufSerialized=new Map;const protobufSerializedToValue=new Map;const unproducible=new Set;let i=0;let index=1;while(i{const{unproducible}=init();if(unproducible&&unproducible.has(value))throw new TypeError(`Unproducible enum value: ${JSON.stringify(value)} ${path?pathTrace(path):""}`);const serialized=map.get(value);if(serialized==null)throw new TypeError(`The proto enum serializer failed to serialize value ${JSON.stringify(value)} into JSON.\nIt does not recognize value ${JSON.stringify(value)} as a valid member of the TypeScript enum.\n${path?pathTrace(path):""}`);return serialized};const deserializeWithPath=(jsonValue,path)=>{const value=init().serializedToValue.get(jsonValue);if(value==null)throw new TypeError(`The proto enum deserializer failed to deserialize JSON ${JSON.stringify(jsonValue)} into an enum value.\nIt does not recognize JSON ${JSON.stringify(jsonValue)} as a valid JSON value encoding of the enum.\n${pathTrace(path)}`);return value};return{values:()=>init().values,producibleValues:()=>{const{values,unproducible}=init();if(unproducible==null)return values;return values.filter((value=>!unproducible.has(value)))},serialize:value=>getSerialized(value,init().valueToSerialized,[]),serializeWithPath:(value,path)=>getSerialized(value,init().valueToSerialized,path),deserialize:jsonValue=>deserializeWithPath(jsonValue,[]),deserializeWithPath}}}Proto.requiredDouble=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.DOUBLE,jsonFullKey,tag,other1)};Proto.requiredInt32=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.INT32,jsonFullKey,tag,other1)};Proto.requiredInt64=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.INT64,jsonFullKey,tag,other1)};Proto.optionalDouble=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.DOUBLE,jsonFullKey,tag)};Proto.optionalInt32=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.INT32,jsonFullKey,tag)};Proto.optionalInt64=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.INT64,jsonFullKey,tag)};Proto.repeatedDouble=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.DOUBLE,jsonFullKey,tag)};Proto.repeatedInt32=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.INT32,jsonFullKey,tag)};Proto.repeatedInt64=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.INT64,jsonFullKey,tag)};Proto.requiredString=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.STRING,jsonFullKey,tag,other1)};Proto.optionalString=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.STRING,jsonFullKey,tag)};Proto.repeatedString=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.STRING,jsonFullKey,tag)};Proto.requiredBoolean=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.BOOLEAN,jsonFullKey,tag,other1)};Proto.optionalBoolean=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.BOOLEAN,jsonFullKey,tag)};Proto.repeatedBoolean=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.BOOLEAN,jsonFullKey,tag)};Proto.requiredBytes=(a,b,c)=>{const{tag,jsonFullKey,other1}=getOptions(a,b,c);return requiredField(ProtoType.BYTES,jsonFullKey,tag,other1)};Proto.optionalBytes=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return optionalField(ProtoType.BYTES,jsonFullKey,tag)};Proto.repeatedBytes=(a,b)=>{const{tag,jsonFullKey}=getOptions(a,b);return repeatedField(ProtoType.BYTES,jsonFullKey,tag)};Proto.booleanInt64Map=mapField(ProtoType.BOOLEAN,ProtoType.INT64);Proto.int32Int32Map=mapField(ProtoType.INT32,ProtoType.INT32);Proto.int32Int64Map=mapField(ProtoType.INT32,ProtoType.INT64);Proto.int32BoolMap=mapField(ProtoType.INT32,ProtoType.BOOLEAN);Proto.int32DoubleMap=mapField(ProtoType.INT32,ProtoType.DOUBLE);Proto.int32StringMap=mapField(ProtoType.INT32,ProtoType.STRING);Proto.int32StringEnumMap=mapField(ProtoType.INT32,"enum");Proto.int32ObjectMap=mapField(ProtoType.INT32,"object");Proto.int32BytesMap=mapField(ProtoType.INT32,ProtoType.BYTES);Proto.int64Int32Map=mapField(ProtoType.INT64,ProtoType.INT32);Proto.int64Int64Map=mapField(ProtoType.INT64,ProtoType.INT64);Proto.int64BooleanMap=mapField(ProtoType.INT64,ProtoType.BOOLEAN);Proto.int64DoubleMap=mapField(ProtoType.INT64,ProtoType.DOUBLE);Proto.int64StringMap=mapField(ProtoType.INT64,ProtoType.STRING);Proto.int64StringEnumMap=mapField(ProtoType.INT64,"enum");Proto.int64ObjectMap=mapField(ProtoType.INT64,"object");Proto.int64BytesMap=mapField(ProtoType.INT64,ProtoType.BYTES);Proto.doubleInt32Map=mapField(ProtoType.DOUBLE,ProtoType.INT32);Proto.doubleInt64Map=mapField(ProtoType.DOUBLE,ProtoType.INT64);Proto.doubleBoolMap=mapField(ProtoType.DOUBLE,ProtoType.BOOLEAN);Proto.doubleDoubleMap=mapField(ProtoType.DOUBLE,ProtoType.DOUBLE);Proto.doubleStringMap=mapField(ProtoType.DOUBLE,ProtoType.STRING);Proto.doubleStringEnumMap=mapField(ProtoType.DOUBLE,"enum");Proto.doubleObjectMap=mapField(ProtoType.DOUBLE,"object");Proto.doubleBytesMap=mapField(ProtoType.DOUBLE,ProtoType.BYTES);Proto.stringInt32Map=mapField(ProtoType.STRING,ProtoType.INT32);Proto.stringInt64Map=mapField(ProtoType.STRING,ProtoType.INT64);Proto.stringBooleanMap=mapField(ProtoType.STRING,ProtoType.BOOLEAN);Proto.stringDoubleMap=mapField(ProtoType.STRING,ProtoType.DOUBLE);Proto.stringStringMap=mapField(ProtoType.STRING,ProtoType.STRING);Proto.stringStringEnumMap=mapField(ProtoType.STRING,"enum");Proto.stringObjectMap=mapField(ProtoType.STRING,"object");Proto.stringBytesMap=mapField(ProtoType.STRING,ProtoType.BYTES);function deriveFieldMetadata(fields,dualDeserializationConfig){return Object.entries(fields).map((([name,config])=>{const fieldEncodings=deriveFieldEncodings(config,dualDeserializationConfig);return{config,name,primaryJsonKey:fieldEncodings.keyEncodings.primaryJsonKey,secondaryJsonKey:fieldEncodings.keyEncodings.secondaryJsonKey,primaryJsonValue:fieldEncodings.valueEncodings?.primaryJsonValue,secondaryJsonValue:fieldEncodings.valueEncodings?.secondaryJsonValue}}))}function deriveFieldEncodings(fieldConfig,dualDeserializationConfig){let valueEncodings;let jsonMiniKey=toJsonMini(fieldConfig.tag-1);if(fieldConfig.fieldLabel===FieldLabel.CONSTANT){const{primary:primaryJsonValue,secondary:secondaryJsonValue}=choosePrimaryAndSecondaryJSONFromConfig(jsonMiniKey,fieldConfig.jsonFullValue,dualDeserializationConfig);jsonMiniKey=DISCRIMINATOR_JSON_MINI_KEY;valueEncodings={primaryJsonValue,secondaryJsonValue}}const{primary:primaryJsonKey,secondary:secondaryJsonKey}=choosePrimaryAndSecondaryJSONFromConfig(jsonMiniKey,fieldConfig.jsonFullKey,dualDeserializationConfig);const keyEncodings={primaryJsonKey,secondaryJsonKey};return{keyEncodings,valueEncodings}}function choosePrimaryAndSecondaryJSONFromConfig(jsonMini,jsonFull,dualDeserializationConfig){if(!jsonFull){if(dualDeserializationConfig!==undefined)throw new Error("Dual Deserialization config templated but JSON full key/value wasn't");return{primary:jsonMini,secondary:undefined}}if(dualDeserializationConfig===undefined)return{primary:jsonFull,secondary:undefined};else if(dualDeserializationConfig===0)return{primary:jsonMini,secondary:jsonFull};else if(dualDeserializationConfig===1)return{primary:jsonFull,secondary:jsonMini};throw new Error("function should have been exhaustive, but wasn't")}function makeRepeatedTypeError(keyEncodings,value,expectedType,path){return new TypeError(`Expected repeated ${expectedType} value for key ${expectedKeys(keyEncodings)}, found: ${moreSpecificTypeof(value)} ${pathTrace(path)}`)}function makeOptionalTypeError(keyEncodings,value,expectedType,path){return new TypeError(`Expected optional ${expectedType} value for key ${expectedKeys(keyEncodings)}, found: ${moreSpecificTypeof(value)} ${pathTrace(path)}`)}function makeRequiredTypeError(keyEncodings,value,expectedType,path,index){const atIndex=index!==undefined?` at index ${index}`:"";return new TypeError(`Expected ${expectedType} value${atIndex} for key ${expectedKeys(keyEncodings)}, found: ${moreSpecificTypeof(value)} ${pathTrace(path)}`)}function expectedKeys(keyEncodings){const{primaryJsonKey,secondaryJsonKey}=keyEncodings;if(secondaryJsonKey)return`either "${primaryJsonKey}" OR "${secondaryJsonKey}"`;return`"${primaryJsonKey}"`}function expectedValues(valueEncodings){const{primaryJsonValue,secondaryJsonValue}=valueEncodings;if(secondaryJsonValue)return`either "${primaryJsonValue}" OR "${secondaryJsonValue}"`;return`"${primaryJsonValue}"`}function pathTrace(path){return`(path: .${path.join(".")})`}function moreSpecificTypeof(value){if(value===null)return"null";if(Array.isArray(value))return"array";return typeof value}const DualDeserializationConfig={MINI_PRIMARY_FULL_SECONDARY:0,FULL_PRIMARY_MINI_SECONDARY:1};const DISCRIMINATOR_JSON_MINI_KEY="A?";const JSON_MINI_ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";function toJsonMini(x){if(x0){builder.push(JSON_MINI_ALPHABET.charAt(x%JSON_MINI_ALPHABET.length));x=Math.floor(x/JSON_MINI_ALPHABET.length)}return builder.reverse().join("")}}function getOptions(tagOrJsonFullKey,tagOrOther1,other1OrOther2,maybeOther2){if(typeof tagOrJsonFullKey==="string")return{jsonFullKey:tagOrJsonFullKey,tag:tagOrOther1,other1:other1OrOther2,other2:maybeOther2};else return{tag:tagOrJsonFullKey,other1:tagOrOther1,other2:other1OrOther2}}function isCorrectWireType(value,typeOfValue){return typeof value===typeOfValue||isCorrectBytesWireType(value,typeOfValue)}function isCorrectBytesWireType(value,typeOfValue){return typeOfValue==="Uint8Array"&&typeof value==="string"}function toBase64(bytes){const binString=Array.from(bytes,(byte=>String.fromCodePoint(byte))).join("");return btoa(binString)}function fromBase64(base64){return Uint8Array.from(atob(base64),(m=>m.codePointAt(0)))}const ResizeEventRequest=Proto.createMessage((()=>({body:Proto.requiredObject("body",1,Dimensions)})),{dualDeserializationConfig:DualDeserializationConfig.MINI_PRIMARY_FULL_SECONDARY});const Dimensions=Proto.createMessage((()=>({scrollWidth:Proto.requiredInt32("scrollWidth",1),scrollHeight:Proto.requiredInt32("scrollHeight",2),offsetWidth:Proto.requiredInt32("offsetWidth",3),offsetHeight:Proto.requiredInt32("offsetHeight",4)})),{dualDeserializationConfig:DualDeserializationConfig.MINI_PRIMARY_FULL_SECONDARY});const ResizeEventResponse=Proto.createMessage((()=>({})));class HostRpcResizingSdkClient{resized(req){return this.hostRpc.exec(this.capabilities.serviceName,this.capabilities.resized,ResizeEventRequest.serialize(req)).then(ResizeEventResponse.deserialize)}constructor(hostRpc,capabilities){this.hostRpc=hostRpc;this.capabilities=capabilities}}function deserializeRequest(message_path,proto,request){if(request===undefined)throw new CanvaErrorClass({code:"internal_error",message:`${message_path}: request cannot be undefined.`});return proto.deserialize(request)}function handleMessageFromHost(comms,message_path,messageArgProto,messageHandler,responseProto){return comms.handle(message_path,(async messageObject=>{const message=deserializeRequest(message_path,messageArgProto,messageObject);const response=await messageHandler(message);if(responseProto)return responseProto.serialize(response)}))}async function runRequest(comms,messagePath,requestProto,request,responseProto){const response=await comms.request(messagePath,requestProto.serialize(request));if(!response.ok){if(response.error instanceof CanvaErrorClass)throw response.error;throw new CanvaErrorClass({code:"internal_error",message:`Something went wrong during request ${messagePath}`})}if(responseProto){if(response.value===undefined)throw new CanvaErrorClass({code:"internal_error",message:`Expected a response from ${messagePath}, but got nothing`});return responseProto.deserialize(response.value)}}const RESIZING_CLIENT_ID="canva-code-resizing-sdk";const RESIZING_CAPABILITIES={serviceName:RESIZING_CLIENT_ID,resized:"RESIZE_EVENT"};function setupResizingRequestHandlers(comms,handler){handleMessageFromHost(comms,RESIZING_CAPABILITIES.resized,ResizeEventRequest,(request=>handler.resized(request)),ResizeEventResponse)}class ResizingSdkClient extends HostRpcResizingSdkClient{constructor(comms){super({exec:async(serviceName,methodName,data)=>{Preconditions.checkState(serviceName===RESIZING_CAPABILITIES.serviceName);const res=await comms.request(methodName,data);return unwrapResult(res,methodName)},requestChannel:undefined},RESIZING_CAPABILITIES)}}function unwrapResult(result,messagePath){if(!result.ok)throw new Error(`Encountered an error while sending ${messagePath} request: ${result.error}`);if(result.value==null)throw new Error(`${messagePath}: Result cannot be empty`);return result.value}const SYSTEM_LOG_MARKER=Symbol("canvaSystemLog");class ConsoleErrorService{log(method,...args){console[method](SYSTEM_LOG_MARKER,`[CLIENT (${this.context})]`,...args)}report(method,severity,...args){const[error,extra]=args;this.beforeReportHandlers.forEach((handler=>handler(severity,error,extra)));this.log(method,...args)}createChild(name){const child=new ConsoleErrorService(`${this.context}:${name}`);child.beforeReportHandlers=this.beforeReportHandlers;return child}withOfflineStatus(){}setContext(context){this.log("debug","context set",context)}setTag(key,value){this.log("debug","tag set",key,value)}addBeforeSendHandler(){}addBeforeReportHandler(handler){this.beforeReportHandlers.push(handler)}setFilters(){}setSensitiveStrings(sensitiveStrings){}addBreadCrumb(breadCrumb){this.log("debug","breadcrumb added",breadCrumb)}debug(error,extra){this.report("debug","debug",error,extra)}info(...args){this.report("info","info",...args)}warn(...args){this.report("warn","warning",...args)}warning(error,extra){this.report("warn","warning",error,extra)}warningException(error,extra){this.report("warn","warning",error,extra)}error(error,extra){this.report("error","error",error,extra)}errorException(error,extra){this.report("error","error",error,extra)}critical(error,extra){this.report("error","fatal",error,extra)}criticalException(error,extra){this.report("error","fatal",error,extra)}constructor(context){this.context=context;this.beforeReportHandlers=[]}}class SdkResult{static ok(data){return new SdkResult(true,data,undefined)}static error(error){return new SdkResult(false,undefined,error)}get isOk(){return this._success}get isError(){return!this._success}get data(){if(!this._success)throw new Error("Cannot access data on error result");return this._data}get error(){if(this._success)throw new Error("Cannot access error on success result");return this._error}constructor(_success,_data,_error){this._success=_success;this._data=_data;this._error=_error}}const TARGET_ORIGIN="*";class ResizingSdk{setupHashNavigationScrolling(){const setup=()=>{window.addEventListener("hashchange",this.handleHashChange);if(window.location.hash!==""){const initialHash=window.location.hash;this.resetHashSilently();this.maybeScrollToHash(initialHash)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",setup):setup()}resetHashSilently(){try{window.history.replaceState(window.history.state,"",window.location.pathname+window.location.search)}catch{}}maybeScrollToHash(rawHash){const fragment=rawHash.startsWith("#")?rawHash.slice(1):rawHash;let decoded;try{decoded=decodeURIComponent(fragment)}catch{decoded=fragment}if(decoded===""||decoded==="top"){document.documentElement.scrollIntoView({behavior:"smooth",block:"start"});return}const target=document.getElementById(decoded)??document.getElementsByName(decoded)[0]??undefined;target?.scrollIntoView({behavior:"smooth",block:"start"})}observeStyleSheets(){const mutationObserver=new MutationObserver((mutationsList=>{let recomputeStyles=false;for(const mutation of mutationsList)switch(mutation.type){case"childList":recomputeStyles=recomputeStyles||[...mutation.addedNodes,...mutation.removedNodes].some((node=>{if(node.nodeType===Node.ELEMENT_NODE&&node!==this.stylesOverride){const tagName=node.tagName.toLowerCase();return tagName==="style"||tagName==="link"}}));break;case"characterData":{const element=mutation.target.parentElement;if(element==null)return;recomputeStyles=recomputeStyles||element.tagName.toLowerCase()==="style"&&element!==this.stylesOverride;break}default:break}recomputeStyles&&this.overrideViewportHeightUnits()}));mutationObserver.observe(document.head,{childList:true,subtree:true,characterData:true});this.overrideViewportHeightUnits()}overrideViewportHeightUnits(){const overrides=[];for(const styleSheet of document.styleSheets){if(styleSheet.ownerNode===this.stylesOverride)continue;for(const rule of this.maybeGetCssRuleList(styleSheet)??[]){if(rule==null||!(rule instanceof CSSStyleRule))continue;const attrs=[];for(const attr of["height","minHeight"]){const value=this.overrideAttributeViewportHeight(rule.style,attr);value&&attrs.push(value)}if(attrs.length>0)overrides.push(`${rule.selectorText} { ${attrs.join(" ")} }`)}}if(overrides.length===0)return;this.stylesOverride.innerText=overrides.join("\n");this.stylesOverride.parentNode==null&&document.head.appendChild(this.stylesOverride)}overrideAttributeViewportHeight(style,key){const attrValue=this.getAttributeViewportHeightValue(style,key);if(attrValue==null)return undefined;const attrKey=key.replace(/([A-Z])/g,(g=>`-${g[0].toLowerCase()}`));return`${attrKey}: ${attrValue} !important;`}getAttributeViewportHeightValue(style,key){const[_,vh]=style[key]?.match(/([\\.\d]+)?vh/)??[];if(vh==null)return undefined;return`calc(${vh} * min(var(--vh, 1vh), 1vh))`}maybeGetCssRuleList(styleSheet){try{return styleSheet.cssRules}catch(e){if(e instanceof DOMException&&e.name==="SecurityError")return undefined;throw e}}setViewportHeight(viewportHeight){document.documentElement.style.height=`${viewportHeight}px`;document.documentElement.style.setProperty("--vh",`${viewportHeight/100}px`);document.documentElement.style.overflow="visible";document.documentElement.style.scrollbarWidth="none";document.documentElement.style.fontSize="clamp(12px, calc(10.2241px + 0.4228vw), 16px)"}async setupParentCommunication(){const result=await this.connectToParent(this.errorService,TARGET_ORIGIN,window,RESIZING_CLIENT_ID);if(!result.ok)return SdkResult.error(new Error("Failed to connect to parent"));this.setViewportHeight(768);if(globalThis.ResizeObserver==null)this.errorService.warning("ResizeObserver is not supported");else{const observer=new globalThis.ResizeObserver((()=>{const{scrollWidth,scrollHeight,offsetWidth,offsetHeight}=document.body;this.commsClient?.resized({body:{scrollWidth:Math.max(scrollWidth,window.innerWidth),scrollHeight,offsetWidth,offsetHeight}})}));const observeElement=element=>{if(!element.tagName.toLowerCase().startsWith("canva-"))observer.observe(element,{box:"border-box"})};const mutationObserver=new MutationObserver((mutationsList=>{for(const mutation of mutationsList)if(mutation.type==="childList"){mutation.addedNodes.forEach((node=>{if(node.nodeType===Node.ELEMENT_NODE)observeElement(node)}));mutation.removedNodes.forEach((node=>{if(node.nodeType===Node.ELEMENT_NODE)observer.unobserve(node)}))}}));const overrideInlineViewportHeight=element=>{if(!element.hasAttribute("style"))return;for(const attr of["height","minHeight"]){const value=this.getAttributeViewportHeightValue(element.style,attr);if(value){const attrKey=attr.replace(/([A-Z])/g,(g=>`-${g[0].toLowerCase()}`));element.style.setProperty(attrKey,value)}}};const styleObserver=new MutationObserver((mutationsList=>{const targetSet=new Set;for(const mutation of mutationsList)switch(mutation.type){case"attributes":if(mutation.target instanceof HTMLElement)targetSet.add(mutation.target);break;case"childList":mutation.addedNodes.forEach((target=>{if(target instanceof HTMLElement){targetSet.add(target);target.querySelectorAll("[style]").forEach((child=>overrideInlineViewportHeight(child)))}}));break;case"characterData":continue;default:throw new UnreachableError(mutation.type)}targetSet.forEach((element=>overrideInlineViewportHeight(element)))}));const observe=()=>{this.observeStyleSheets();observeElement(document.body);for(const child of document.body.children)observeElement(child);mutationObserver.observe(document.body,{childList:true});document.querySelectorAll("[style]").forEach((element=>overrideInlineViewportHeight(element)));styleObserver.observe(document.body,{subtree:true,childList:true,attributes:true,attributeFilter:["style"]})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",observe):observe()}this.errorService.info("Successfully connected to parent");this.commsClient=this.createResizingClientComms(result.value);return SdkResult.ok(this.commsClient)}constructor(connectToParent,createResizingClientComms,errorService){this.connectToParent=connectToParent;this.createResizingClientComms=createResizingClientComms;this.errorService=errorService;this.stylesOverride=document.createElement("style");this.handleHashChange=()=>{const hash=window.location.hash;this.resetHashSilently();this.maybeScrollToHash(hash)};this.setupParentCommunication();this.setupHashNavigationScrolling()}}function getErrorService(){const telemetry=window.telemetrySdk?.errorService;return telemetry?.createChild("Resizing")??new ConsoleErrorService("Resizing")}const errorService=getErrorService();new ResizingSdk(connectToParent,(connection=>new ResizingSdkClient(connection)),errorService)})();