@spiffcommerce/core 35.0.1 → 36.1.0
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.
- package/CHANGELOG.md +26 -0
- package/dist/index.cjs +2667 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +74 -119
- package/dist/index.mjs +3385 -3597
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -7
- package/dist/index.js +0 -2730
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/types.ts","../src/util/exception.ts","../src/services/persistence.ts","../src/Configuration.ts","../src/util/crossplatform.ts","../src/services/server.ts","../src/customCanvas.ts","../src/util/image.ts","../src/util/color.ts","../src/util/illustration.ts","../src/services/asset.ts","../src/services/promiseCache.ts","../src/services/option.ts","../src/query.ts","../src/WorkflowManager/scenes/index.ts","../src/util/PromiseQueue/index.ts","../src/util/guid.ts","../src/Elements/SVGLayout.tsx","../src/util/math.ts","../src/Elements/Image.tsx","../src/Elements/Group.tsx","../src/Elements/Frame.tsx","../src/util/font.ts","../src/text/algorithm/traditional.ts","../src/text/shared.ts","../src/util/text.ts","../src/Elements/Textbox.tsx","../src/Elements/Illustration.tsx","../src/CommandContext.tsx","../src/util/frame.ts","../src/Elements/factory.ts","../src/LayoutsState.ts","../src/command.ts","../src/services/SilentStepHandler/index.ts","../src/services/shortener.ts","../src/util/Poller.ts","../src/services/steps/digitalContent.ts","../src/services/steps/frame/index.ts","../src/services/steps/illustration.ts","../src/services/steps/material.ts","../src/services/steps/model.ts","../src/services/steps/module.ts","../src/services/steps/picture.ts","../src/services/steps/question.ts","../src/services/steps/shape.ts","../src/services/toast.ts","../src/text/algorithm/autosize.ts","../src/services/steps/text/index.ts","../src/module/ModuleProduct.ts","../src/module/products/Vegemite/font.ts","../src/module/svg/elements.ts","../src/module/svg/modify.ts","../src/module/svg/Warp.ts","../src/module/products/Vegemite/index.ts","../src/module/resolver.ts","../src/generation/index.ts","../src/WorkflowManager/LayoutPreviewService/index.ts","../src/GlobalPropertyStateManager/query.ts","../src/Bundle/query.ts","../src/util/object.ts","../src/WorkflowManager/index.ts","../src/stepHandles/resource/variant.ts","../src/stepHandles/index.ts","../src/stepHandles/steps/illustration.ts","../src/stepHandles/steps/material.ts","../src/stepHandles/steps/model.ts","../src/stepHandles/steps/picture.ts","../src/stepHandles/steps/question.ts","../src/stepHandles/steps/shape.ts","../src/stepHandles/steps/text.ts","../src/stepHandles/steps/information.ts","../src/stepHandles/steps/digitalContent.ts","../src/stepHandles/steps/module.ts","../src/stepHandles/factory.ts","../src/services/design.ts","../src/WorkflowExperience/index.ts","../src/GlobalPropertyConfiguration/index.ts","../src/util/omitDeep.ts","../src/GlobalPropertyStateManager/index.ts","../src/Bundle/stateManager.ts","../src/services/metafield.ts","../src/productCollection.ts","../src/util/event.ts","../src/Bundle/index.ts","../src/flowService.ts","../src/integration.ts","../src/customer.ts","../src/services/graphql.ts","../src/services/userPool.ts","../src/currency.ts","../src/client.ts","../src/services/steps/frame/Service.ts","../src/WorkflowManager/mock.ts","../src/stepHandles/steps/frame.ts","../src/customerPortal/queries.ts","../src/customerPortal/functions.ts","../node_modules/@spiffcommerce/theme-bridge/dist/index.js","../src/addressValidation.ts","../src/util/integrationProduct.ts"],"sourcesContent":["import { FunctionComponent, ReactNode } from \"preact/compat\";\nimport { WorkflowManager } from \"./WorkflowManager\";\nimport type { RenderableContextService } from \"@spiffcommerce/preview\";\nimport type { ConversionConfiguration, ThemeInstallConfigurationGraphQl } from \"@spiffcommerce/theme-bridge\";\nimport { CanvasCommand } from \"./command\";\n\nexport enum AssetType {\n Data = \"Data\",\n Font = \"Font\",\n Frame = \"Frame\",\n Illustration = \"Illustration\",\n Image = \"Image\",\n Model = \"Model\",\n Material = \"Material\",\n Color = \"Color\",\n QuestionnaireCollateral = \"QuestionnaireCollateral\",\n RequestCollateral = \"RequestCollateral\",\n SignupCollateral = \"SignupCollateral\",\n Video = \"Video\",\n ColorProfile = \"ColorProfile\",\n Environment = \"Environment\",\n}\n\nexport interface Asset {\n /**\n * The path of the asset within the bucket.\n */\n key?: string;\n\n /**\n * The name of this asset, the file name by default, otherwise a name set by the user.\n */\n name?: string;\n\n /**\n * The time that this asset was uploaded.\n */\n createdAt?: string;\n\n /**\n * The ID of this asset's license.\n */\n licenseId?: string;\n\n /**\n * The content type registered with the bucket.\n */\n mimeType?: string;\n\n /**\n * The ID of the person that uploaded this asset.\n */\n ownerId?: string;\n\n /**\n * The price to use this asset.\n */\n price?: number;\n\n /**\n * The asset type being dealt with.\n */\n type?: AssetType;\n\n /**\n * True when this asset is publicly available to anyone.\n */\n public?: boolean;\n\n /**\n * All versions for this asset, including the \"latest\" one which is the default and represented\n * by the key of the asset itself.\n */\n objectVersions?: AssetObjectVersion[];\n\n /**\n * A list of tags for organisational purposes.\n */\n tags?: AssetTag[];\n\n hubLink?: string;\n\n fileLink?: string;\n\n newVersionLink?: string;\n\n invalidateLink?: string;\n\n versions?: AssetVersion[];\n\n metadata?: AssetMetadata[];\n\n assetConfiguration?: AssetConfiguration;\n}\n\nexport interface AssetConfiguration {\n colorOption?: OptionResource;\n channelNumbers: {\n id: string;\n number: number;\n }[];\n defaultColorVariants: {\n channelNumber: number;\n variant: VariantResource;\n }[];\n}\n\n/**\n * A tag for organisation of assets\n */\nexport interface AssetTag {\n /**\n * A unique ID.\n */\n id: string;\n /**\n * The human friendly display name of the tag.\n */\n name: string;\n /**\n * The key of the asset the tag is associated to.\n */\n assetKey: string;\n /**\n * The partner that owns that asset & tag.\n */\n partnerId: string;\n}\n\ninterface AssetMetadata {\n key: string;\n value: string;\n}\n\ninterface AssetVersion {\n name: string;\n\n link: string;\n}\n\n/**\n * An object version is a snapshow of an asset at a given point in time. Each time\n * the user updates the file associated to an asset a new object version is created.\n * Users can then see a timeline of all object versions and switch between them.\n */\nexport interface AssetObjectVersion {\n /**\n * The size of the file in bytes.\n */\n size: number;\n /**\n * A timestamp for when this version was created.\n */\n timestamp: string;\n /**\n * The id of the version, this is required in cases where we want to perform\n * specific operations on a version such as making it the latest one or deleting it.\n */\n versionId: string;\n /**\n * The url that this asset should be called on when we want to get it,\n * instead of the base key. This key is\n */\n versionedKey: string;\n}\n\nexport interface Step<T extends AnyStepData = AnyStepData> {\n conditions?: Condition[];\n data: T;\n globalPropertyAspectConfigurations?: GlobalPropertyAspectConfiguration[];\n conversionConfigurationFieldLinks?: ConversionConfigurationLink[];\n helpText?: string;\n mandatory?: boolean;\n relevantPanelName?: string;\n silent?: boolean;\n option?: OptionResource;\n overrideDefaultVariantId?: string;\n optionId?: string;\n stepName: string;\n stepTitle: string;\n tags?: string[];\n type: StepType;\n}\n\nexport interface GlobalPropertyAspectConfiguration {\n aspectName?: string;\n globalPropertyConfigurationId?: string;\n}\n\nexport interface ConversionConfigurationLink {\n identifier?: string;\n conversionConfigurationId?: string;\n}\n\nexport interface GlobalPropertyConfiguration {\n id: string;\n aspects: GlobalPropertyConfigurationAspect[];\n}\n\nexport enum GlobalPropertyConfigurationConditionMode {\n AND = \"AND\",\n OR = \"OR\",\n}\n\nexport interface GlobalPropertyConfigurationAspect {\n name: string;\n type: AspectType;\n title: string;\n description: string;\n entityId?: string;\n conditions?: GlobalPropertyConfigurationAspectCondition[];\n conditionMode?: GlobalPropertyConfigurationConditionMode;\n data?: GlobalPropertyConfigurationAspectData;\n mandatory?: boolean;\n}\n\nexport interface GlobalPropertyConfigurationAspectData {\n fileUpload?: GlobalPropertyConfigurationAspectFileUploadData;\n text?: GlobalPropertyConfigurationAspectTextData;\n}\n\nexport interface GlobalPropertyConfigurationAspectFileUploadData {\n colorPickerEnabled?: boolean;\n pmsPickerEnabled?: boolean;\n colorOptionId?: string;\n}\n\nexport interface GlobalPropertyConfigurationAspectTextData {\n templatingEnabled?: boolean;\n}\n\nexport interface GlobalPropertyConfigurationAspectCondition {\n targetAspectName?: string;\n action: AspectConditionAction;\n requiredVariantSelections: string[];\n}\n\nexport enum AspectConditionAction {\n Show = \"Show\",\n}\n\nexport enum AspectType {\n FileUpload = \"FileUpload\",\n Option = \"Option\",\n ColorOption = \"ColorOption\",\n Text = \"Text\",\n}\n\nexport enum StepType {\n Information = \"Information\",\n Bulk = \"Bulk\",\n DigitalContent = \"DigitalContent\",\n Finish = \"Finish\",\n Frame = \"Frame\",\n Illustration = \"Illustration\",\n Introduction = \"Introduction\",\n Material = \"Material\",\n Model = \"Model\",\n Module = \"Module\",\n Picture = \"Picture\",\n /**\n * @deprecated Use Frame instead.\n */\n Photo = \"Photo\",\n ProductOverlay = \"ProductOverlay\",\n Question = \"Question\",\n Shape = \"Shape\",\n SilentIllustration = \"SilentIllustration\",\n Text = \"Text\",\n}\n\nexport interface StepAspect {\n stepName: string;\n stepType: StepType;\n aspectType: StepAspectType;\n}\n\nexport enum StepAspectType {\n Color = \"Color\",\n Colors = \"Colors\",\n Selection = \"Selection\",\n Selections = \"Selections\",\n Text = \"Text\",\n Upload = \"Upload\",\n}\n\nexport interface Region {\n top: number;\n left: number;\n width: number;\n height: number;\n layer?: number;\n layerIndex?: number;\n rotation: number;\n panelId: string;\n immutable?: boolean;\n adjustmentBoundary?: { x: number; y: number; height: number; width: number };\n}\n\nexport interface Condition {\n requiredVariantSelections: string[];\n action: string;\n targetStepName: string;\n}\n\ninterface StepAsset {\n key: string;\n previewKey?: string;\n}\n\nexport interface OptionResource {\n id?: string;\n localId?: string;\n name: string;\n type?: string;\n variants?: VariantResource[];\n defaultVariant?: Pick<VariantResource, \"id\">;\n workflowId?: string;\n public?: boolean;\n displayType?: string;\n colorProfile?: Asset;\n integrationOptions?: IntegrationOptionResource[];\n}\n\nexport interface VariantResource {\n id?: string;\n name: string;\n enabled: boolean;\n priceModifier: number;\n\n asset?: Asset;\n material?: MaterialResource;\n thumbnail?: Asset;\n\n color?: string;\n localId?: string;\n default?: boolean;\n namedColor?: string;\n\n option?: OptionResource;\n}\n\nexport interface IntegrationOptionResource {\n id?: string;\n localId?: string;\n integrationId: string;\n externalProductId?: string;\n}\n\n/**\n * Represents a material resource that can be additively applied to\n * a material targeted in the scene.\n */\nexport type MaterialResource = {\n /**\n * A unique identified for this material.\n */\n id: string;\n /**\n * The name of this material\n */\n name: string;\n /**\n * Defines the base color of a surface before any other calculations are made.\n */\n albedoMapKey?: string;\n /**\n * Defines the transparency of a surface.\n */\n alphaMapKey?: string;\n /**\n * Defines shadowing on a surface.\n */\n ambientMapKey?: string;\n /**\n * Defines the amount of light being emitted from a surface.\n */\n emissionMapKey?: string;\n /**\n * Identical to roughness.\n */\n metallicMapKey?: string;\n /**\n * Defines the direction light will bounce in when it hits a point on a surface.\n */\n normalMapKey?: string;\n /**\n * Used to define how smooth a surface is.\n */\n roughnessMapKey?: string;\n /**\n * Used to define refraction of light on a surface.\n */\n refractionMapKey?: string;\n /**\n * The intensity of refraction, when refraction is enabled via a texture.\n */\n refractionIntensity?: number;\n /**\n * Use to define reflection of light on a surface.\n */\n reflectionMapKey?: string;\n /**\n * The intensity of reflection, when reflection is enabled via a texture.\n */\n reflectionIntensity?: number;\n /**\n * The rotation of the reflection map (around the up axis, in degrees), when reflection is enabled via a texture.\n */\n reflectionRotation?: number;\n /**\n * When enabled the material will be displayed with a clearcoat affect for simulating coated plastic surfaces.\n */\n clearCoat: MaterialEffectMode;\n /**\n * Index of refraction when clear coat is enabled.\n */\n clearCoatIOR?: number;\n /**\n * The date that this material resource was created\n */\n createdAt: string;\n /**\n * The date that this material resource was last updated.\n */\n updatedAt: string;\n};\n\n/**\n * Used to specify the behavior of a material effect such as clearcoat, sheen and translucency.\n */\nexport enum MaterialEffectMode {\n /**\n * When a material variant effect specifies 'None' the effect doesn't change in any way. This is the default behavior.\n */\n None = \"None\",\n /**\n * When a material variant effect specifies 'RemoveWhenSelected' the effect is removed.\n */\n RemoveWhenSelected = \"RemoveWhenSelected\",\n /**\n * When a material variant effect specifies 'ApplyWhenSelected' the effect is enabled.\n */\n ApplyWhenSelected = \"ApplyWhenSelected\",\n}\n\nexport type AnyStepData =\n | InformationStepData\n | BulkStepData\n | DigitalContentStepData\n | FinalizeStepData\n | FrameStepData\n | IllustrationStepData\n | MaterialStepData\n | ModelStepData\n | ModuleStepData\n | PictureStepData\n | QuestionStepData\n | ShapeStepData\n | SilentStepData\n | TextStepData;\n\nexport interface Animatable {\n lookAtAnimation?: CameraAnimation;\n modelAnimation?: ModelAnimation;\n}\n\nexport interface BulkStepData extends Animatable {\n aspects: StepAspect[];\n}\n\nexport interface InformationStepData extends Animatable, Placeable {\n content: string;\n}\n\nexport interface DigitalContentStepData extends Animatable, Placeable {\n baseUrl: string;\n varyUpload?: boolean;\n}\n\nexport interface FrameStepData extends Animatable, Placeable, Colorable {\n hideSelectionInCart?: boolean;\n hideImageInCart?: boolean;\n colorPickerEnabled?: boolean;\n displaySelectionOnFinishStep?: boolean;\n displayImageOnFinishStep?: boolean;\n disablePlaceholder?: boolean;\n initialZoomLevel?: number;\n markSelectionAsCustomField?: boolean;\n markImageAsCustomField?: boolean;\n maxColors?: number;\n focalBlur?: boolean;\n focalBlurRadius?: number;\n focalBlurStrength?: number;\n forceImageCover?: boolean;\n overlayImageKey?: string;\n placeholderImageKey?: string;\n placeholderImageUrl?: string;\n varySelection?: boolean;\n varyUpload?: boolean;\n whitelistedExtensions: string[];\n}\n\nexport interface IllustrationStepData extends Animatable, Placeable, Colorable {\n hideSelectionInCart?: boolean;\n hideColorsInCart?: boolean;\n displaySelectionOnFinishStep?: boolean;\n displayColorsOnFinishStep?: boolean;\n enableVariantSearch?: boolean;\n markSelectionAsCustomField?: boolean;\n markColorsAsCustomField?: boolean;\n assetKeys?: string[];\n assets?: StepAsset[];\n defaultAssetKey?: string;\n colorPickerEnabled?: boolean;\n pmsPickerEnabled?: boolean;\n varySelection?: boolean;\n varyColors?: boolean;\n}\n\nexport interface MaterialStepData extends Animatable {\n hideSelectionInCart?: boolean;\n displaySelectionOnFinishStep?: boolean;\n markSelectionAsCustomField?: boolean;\n targetMaterials: string[];\n varySelection?: boolean;\n}\n\nexport interface ModelStepData extends Animatable {\n replaceProductModel?: boolean;\n hideSelectionInCart?: boolean;\n displaySelectionOnFinishStep?: boolean;\n markSelectionAsCustomField?: boolean;\n varySelection?: boolean;\n}\n\nexport interface ModuleStepData extends Animatable, Placeable {\n hideTextInCart?: boolean;\n displayTextOnFinishStep?: boolean;\n markTextAsCustomField?: boolean;\n module: string;\n maxLength: number;\n varyText?: string;\n}\n\nexport interface PictureStepData extends Animatable, Placeable {\n hideSelectionInCart?: boolean;\n displaySelectionOnFinishStep?: boolean;\n enableVariantSearch?: boolean;\n markSelectionAsCustomField?: boolean;\n varySelection?: boolean;\n}\n\nexport interface QuestionStepData extends Animatable {\n hideSelectionsInCart?: boolean;\n displaySelectionsOnFinishStep?: boolean;\n markSelectionsAsCustomField?: boolean;\n varySelections?: boolean;\n}\n\nexport interface ShapeStepData extends Animatable, Placeable {\n hideSelectionInCart?: boolean;\n displaySelectionOnFinishStep?: boolean;\n markSelectionAsCustomField?: boolean;\n defaultColour?: string;\n excludeFromPrint?: boolean;\n varySelection?: boolean;\n}\n\nexport interface TextStepData extends Animatable, Placeable, Colorable {\n hideSelectionInCart?: boolean;\n hideFillImageInCart?: boolean;\n hideColorInCart?: boolean;\n hideStrokeInCart?: boolean;\n hideTextInCart?: boolean;\n displaySelectionOnFinishStep?: boolean;\n displayImageFillOnFinishStep?: boolean;\n displayColorOnFinishStep?: boolean;\n displayTextOnFinishStep?: boolean;\n displayStrokeOnFinishStep?: boolean;\n markSelectionAsCustomField?: boolean;\n markFillImageAsCustomField?: boolean;\n markColorAsCustomField?: boolean;\n markStrokeAsCustomField?: boolean;\n markTextAsCustomField?: boolean;\n allowNewlines?: boolean;\n defaultText: string;\n deleteDefaultOnFocus?: boolean;\n replaceableText?: string;\n font: string;\n colorPickerEnabled?: boolean;\n maxLength: number;\n maxSize?: number;\n minSize?: number;\n size: number;\n textAlign: string;\n colour: string;\n uppercase?: boolean;\n vertical?: boolean;\n verticalAlign: string;\n curved?: boolean;\n paths?: string[];\n userCanReplaceText?: boolean;\n varySelection?: boolean;\n varyText?: boolean;\n varyColor?: boolean;\n imageFillOption?: OptionResource;\n imageFillScale?: number;\n strokeEnabled?: boolean;\n strokeOption?: OptionResource;\n strokeThickness?: string;\n}\n\nexport interface SilentStepData extends Animatable, Placeable {\n asset?: Asset;\n excludeFromPrint?: boolean;\n}\n\ntype FinalizeStepData = Animatable;\n\n/**\n * A colorable step is a step that can have an optional color option assigned to help drive color palette choices.\n */\nexport interface Colorable {\n colorOption?: OptionResource;\n}\n\n/**\n * A placeable step is a step that can be placed on a canvas in a set of specific positions.\n */\nexport interface Placeable {\n regions: Region[];\n}\n\nexport interface StepService<T extends AnyStepData> {\n /**\n * Initialize the given step, or reload from serialized data if present.\n */\n init(stepData: Step<T>, workflowManager: WorkflowManager, reducerState?: LayoutsState): Promise<any>;\n}\n\nexport interface LayoutsState {\n layouts: { [id: string]: LayoutState };\n serializableWorkflow: SerializableWorkflow;\n}\n\n/**\n * A workflow step in the process of being serialized or deserialized.\n */\nexport interface SerializableStep {\n stepName: string;\n storage?: StepStorage;\n selectedVariants?: SerializableVariant[];\n}\n\nexport interface SerializableWorkflow {\n steps: SerializableStep[];\n}\n\nexport interface SerializableVariant {\n id: string;\n priceModifier: number;\n}\n\n// Non-variant information required to rehydrate a workflow step.\nexport interface StepStorage {\n bulkIsConnected?: boolean;\n color?: string;\n colorProfileAssetKey?: string;\n colors?: { [key: string]: IllustrationColorObject };\n colour?: string;\n currentFrameSources?: string[];\n customiseAllText?: boolean;\n defaultCleared?: boolean;\n fillImage?: TextFillImage;\n frameOffsetsList?: FrameOffsets[];\n framePatternData?: {\n originalAssetKey?: string;\n backgroundRemovedAssetKey?: string;\n useOriginalAsset?: boolean;\n };\n framePatternSrc?: string;\n inputText?: string;\n overrideGlobalConfiguration?: boolean;\n overrideGlobalConfigurations?: { [key: string]: boolean };\n strokeColor?: IllustrationColorObject;\n text?: string;\n videoShortUrl?: string;\n videoUrl?: string;\n}\n\nexport interface IllustrationColorObject {\n browserValue: string;\n spotColor?: { profileName: string; namedColor: string };\n pmsValue?: string;\n}\n\nexport interface FrameOffsets {\n regionIndex?: string;\n y: number;\n x: number;\n zoom: number;\n}\n\nexport interface LayoutState {\n /**\n * The elements currently on this layout.\n */\n elements: LayoutElement[];\n /**\n * A file describing the properties of this layout.\n */\n layout: ILayout;\n /**\n * A unique ID regenerated each time this layout is changed.\n */\n modificationID: string;\n}\n\n/**\n * Represents an element on the SVG canvas. This may comprise of multiple SVG elements when\n * output such as path elements, defs, etc. All concrete elements must implement this interface.\n */\nexport interface LayoutElement extends Layerable {\n /**\n * The unique identifier for this element.\n */\n id: string;\n /**\n * If the element was made from a workflow step, this is its step name.\n */\n stepName?: string;\n /**\n * If the element was made from a workflow step, this is its region.\n */\n stepRegion?: Region;\n /**\n * If the element was made from a workflow step, this the index of the region.\n */\n stepRegionIndex?: number;\n /**\n * The type of this element\n */\n type: LayoutElementType;\n /**\n * Horizontal offset from top left origin point.\n */\n x: number;\n /**\n * Vertical offset from top left origin point.\n */\n y: number;\n /**\n * The height in pixels of the element.\n */\n width: number;\n /**\n * The height in pixels of the element.\n */\n height: number;\n /**\n * The rotation in degrees.\n */\n rotation: number;\n\n /**\n * The element is considered immutable and shouldn't be modifiable by the user.\n */\n immutable?: boolean;\n /**\n * When true this element should be rendered on top of all other elements always.\n */\n productOverlay?: boolean;\n /**\n * When true, this element will be removed from SVGString output when\n * the removeExcludedElements flag is set to true.\n */\n excludeFromExport?: boolean;\n /**\n * Value to use as the mask attribute if the element does not correspond to a step.\n */\n mask?: string;\n /**\n * Injected by the LayoutsProvider if required. Shouldn't be\n * used by the user. This is a simple way to pass global rendering configuration\n * to individual elements without having to set up a react context.\n */\n _renderingConfiguration?: RenderingConfiguration;\n}\n\n/**\n * Represents a layerable entity. Layerable entities can be sorted within our system for rendering purposes.\n */\nexport interface Layerable {\n /**\n * The layer that this element exists on. Elements on a higher layer can never\n * be below an element on a lower layer. 0 by default.\n */\n layer?: number;\n /**\n * The index of this element on the current layer, if no layer is present it is assumed to be 0.\n * For the index 0 is lower, > 0 is higher\n */\n layerIndex?: number;\n}\n\nexport interface TextFillImage {\n src: string;\n width: number;\n height: number;\n scale: number;\n}\n\n/**\n * The reason we need to turn a layout into an SVG.\n */\nexport enum LayoutRenderingPurpose {\n ThreeD = \"ThreeD\",\n FreeDesign = \"FreeDesign\",\n Print = \"Print\",\n}\n\n/**\n * Specifies configuration for rendering a Papyrus canvas as an SVG string.\n */\nexport interface RenderingConfiguration {\n /**\n * Sets the viewbox to a custom value when subregions are desired.\n */\n region?: PreviewRegion;\n /**\n * Excludes marked elements from the SVG output when true.\n */\n removeExcludedElements?: boolean;\n\n purpose: LayoutRenderingPurpose;\n\n /**\n * When true any cached data will be ignored and assets will be rendered in full\n * with the properties they are provided.\n */\n omitCachedFields?: boolean;\n /**\n * When true, spot colors will be output, when provided, into any\n * fill or stroke style in an illustration.\n */\n spotColors?: boolean;\n\n colorProfiles?: ColorProfileProps[];\n\n /**\n * Allow for debug rendering on elements.\n */\n debug?: boolean;\n\n /**\n * Contents variables for templating text.\n */\n templatingContext?: { [key: string]: any };\n}\n\nexport interface ColorProfileProps {\n name: string;\n key: string;\n}\n\nexport interface PreviewRegion {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\n/**\n * The possible types for an element.\n */\nexport enum LayoutElementType {\n Frame = \"frame\",\n Group = \"group\",\n Image = \"image\",\n Pattern = \"pattern\",\n Illustration = \"illustration\",\n Textbox = \"textbox\",\n}\n\n/**\n * Represents a layout contained within a specific user created design.\n */\nexport interface ILayout {\n /**\n * The internal identifier for this layout.\n */\n id: string;\n\n /**\n * A link to the json resource describing this layout\n */\n layoutPath?: string;\n\n /**\n * The index this layout appears at in its design\n */\n index: number;\n\n /**\n * An id for the panel associated to this layout.\n */\n panelId: string;\n\n /**\n * The date this layout was created.\n */\n createdAt: Date;\n\n /**\n * The date this layout was last updated.\n */\n updatedAt: Date;\n\n /**\n * The height of the layout. This matches the background element on the canvas as a convenience.\n */\n height: number;\n\n /**\n * The width of the layout. This matches the background element on the canvas as a convenience.\n */\n width: number;\n /**\n * When true this layout should contain no background fill.\n */\n transparentBackground?: boolean;\n\n previewRegion?: {\n height: number;\n width: number;\n top: number;\n left: number;\n };\n\n useEditableArea?: boolean;\n editableArea?: {\n x: number;\n y: number;\n height: number;\n width: number;\n };\n\n name: string;\n title?: string;\n}\n\nexport interface FileInfo {\n /**\n * The name of the file.\n */\n name: string;\n\n /**\n * A blob object representing the\n * data of the file.\n */\n blob: Blob;\n}\n\n/**\n * A command along with a function to run afterwards.\n */\nexport interface CommandWithFollowup {\n command?: CanvasCommand;\n followup?: () => Promise<void>;\n}\n\nexport interface DesignResource {\n metadata?: { [key: string]: string };\n sku?: string;\n}\n\nexport interface DesignDetails {\n name: string;\n layouts: { index: number; panelId: string }[];\n workflowId: string;\n transactionId: string;\n previewImage?: string;\n useThreeDimPreview: boolean;\n metadata?: { key: string; value: string }[];\n selectedVariants?: { key: string; ids: string[] }[];\n}\n\n/**\n * The variant selections of a completed step.\n */\nexport interface SelectedVariants {\n [stepName: string]: {\n id: string;\n name: string;\n priceModifier: number;\n }[];\n}\n\n// The metadata and variant selections of a completed workflow.\nexport interface ExportedData {\n [name: string]: {\n value: string;\n priceModifier: number;\n };\n}\n\nexport interface DesignCreationMessage {\n additionalExternalProductId?: string;\n additionalExternalVariantId?: string;\n baseCost?: number;\n designExternalVariants?: DesignExternalVariant[];\n designProductId?: string;\n designProductVariantId?: string;\n event: string;\n exportedData: ExportedData;\n externalCartProductId?: string;\n externalCartProductVariantId?: string;\n lineItemImageUrl: string;\n metadata?: { [stepName: string]: string };\n optionsCost: number;\n processExecutionId?: string;\n quantity?: number;\n selectedVariants?: SelectedVariants;\n sku?: string;\n transactionId: string;\n transactionOwnerId?: string;\n weight?: number;\n workflowViewerLink: string;\n workflowViewerReadOnlyLink: string;\n}\n\nexport enum BundleDesignCreationCartAddMode {\n /** Uses default grouping method, which consolidates products into as few line items as possible */\n Default = \"Default\",\n /** Only adds the first transaction to the cart. */\n FirstTransaction = \"FirstTransaction\",\n /** Adds each transaction in the Bundle to the cart, without consolidation. */\n OneToOne = \"OneToOne\",\n}\n\nexport interface BundleDesignCreationMessage {\n bundleId: string;\n /**\n * The name assigned by the user for this design.\n */\n name: string;\n /**\n * The date this bundle is expected to be dispatched.\n */\n dispatchDate: string;\n /**\n * The purchase order associated with this bundle.\n */\n purchaseOrder: string;\n /**\n * The ID of the collection this bundle is using.\n */\n collectionId: string;\n /**\n * The name of the collection this bundle is using.\n */\n collectionName: string;\n /**\n * The line items associated with this bundle.\n */\n items: DesignCreationMessage[];\n /**\n * The ID of the user who owns this bundle.\n */\n bundleOwnerId?: string;\n /**\n * @deprecated\n */\n cartAddMode?: BundleDesignCreationCartAddMode;\n}\n\nexport interface DesignWorkflowMetadata {\n [key: string]: string;\n}\n\n/**\n * Represents a transaction.\n */\nexport interface Transaction {\n /**\n * A unique identifier for this transaction. Useful for reloading and\n * modifying state of the transaction.\n */\n id: string;\n\n /**\n * User-supplied name for the associated design.\n */\n designName?: string;\n\n /**\n * The workflow associated with this transaction.\n */\n workflowId?: string;\n\n /**\n * Temporary ID that grants write permission to the transaction.\n */\n transactionOwnerId?: string;\n\n /**\n * The current state of the design.\n */\n workflowState?: string;\n\n /**\n * URL to a partner-specific logo intended to display during the workflow experience.\n */\n customLogoLink?: string;\n\n /**\n * URL to a logo intended to display at the periphery of the workflow experience.\n */\n workflowFooterLogoLink?: string;\n\n /**\n * URL to the corresponding integration in the REST API.\n */\n restApiIntegrationLink?: string;\n\n /**\n * URL to redirect to when a workflow is finished.\n */\n callbackUrl?: string;\n\n /**\n * Product that this transaction belongs to.\n */\n product?: Product;\n\n /**\n * The ID of the product that this transaction belongs to.\n */\n productId?: string;\n\n /**\n * The integration product related to this lineitem.\n */\n integrationProduct?: IntegrationProductResource;\n\n /**\n * The ID of the integration product that this transaction belongs to.\n */\n integrationProductId?: string;\n\n /**\n * Whether this transaction has previously been ordered.\n */\n isOrdered?: boolean;\n\n /**\n * @deprecated use isOrdered to check whether transaction has been ordered instead.\n */\n lineItem?: LineItem;\n\n /**\n * The external product variant ID representing the design product related\n * to this transaction, null unless the createDesignProduct flag was set\n * and the design was finalized using createDesign operation.\n */\n /**@deprecated use externalCartProductVariantId or designExternalVariants[x].externalProductVariantId instead of this moving forward */\n externalDesignProductVariantId?: string;\n\n /**\n * The external product id representing the design product related\n * to this transaction, null unless the createDesignProduct flag was set\n * and the design was finalized using createDesign operation.\n */\n /**@deprecated use externalCartProductId or designExternalVariants[x].externalProductId instead of this moving forward. */\n externalDesignProductId?: string;\n\n /**\n * The external product id representing the product related to the transaction.\n * This value can hold any type of transaction such as design and standard products.\n */\n externalCartProductId?: string;\n\n /**\n * The external product variant id representing the product related to the transaction.\n * This value can hold any type of transaction such as design and standard products.\n */\n externalCartProductVariantId?: string;\n\n priceModifierTotal?: number;\n\n /**\n * URL to open the transaction in the workflow viewer.\n */\n workflowViewerLink?: string;\n\n workflowViewerReadOnlyLink?: string;\n\n previewImageLink?: string;\n\n lastSyncedAt?: string;\n\n /**\n * The users who have access to this transaction.\n */\n stakeholders?: Stakeholder[];\n\n /** The stakeholder of the currently logged in user, if applicable. */\n currentStakeholder?: Stakeholder;\n\n recipient?: Recipient;\n\n /**\n * The amount of this transaction that was, or will be, ordered\n */\n quantity?: number;\n\n createdAt?: string;\n\n printFileUrl1?: string;\n printFileUrl2?: string;\n printFileUrl3?: string;\n printFileUrl4?: string;\n printFileUrl5?: string;\n printFileName1?: string;\n printFileName2?: string;\n printFileName3?: string;\n printFileName4?: string;\n printFileName5?: string;\n\n /**\n * An array of objects containing information on additional products to add to the cart.\n * Typically only available when being passed to {@link DesignCreationMessage}\n */\n designExternalVariants?: DesignExternalVariant[];\n\n /**\n * A list of actions that have been associated to this transaction. To be used by the client to interact further post design.\n */\n transactionShareActions?: ShareAction[];\n\n /** Whether any share actions for this Transaction require the user to be authenticated as a stakeholder */\n hasAuthenticatedActions?: boolean;\n\n marketplaceThemeInstallConfiguration?: ThemeInstallConfigurationGraphQl;\n\n completed?: boolean;\n\n addressValidationStatus?: AddressValidationStatus;\n}\n\nexport enum AddressValidationStatus {\n Pending = \"Pending\",\n Failed = \"Failed\",\n Validated = \"Validated\",\n Overridden = \"Overridden\",\n}\n\nexport interface Recipient {\n id?: string;\n firstName?: string;\n lastName?: string;\n address?: string;\n suburb?: string;\n state?: string;\n email?: string;\n postalCode?: string;\n country?: string;\n mobile?: string;\n company?: string;\n apartment?: string;\n customField1?: string;\n customField2?: string;\n customField3?: string;\n customField4?: string;\n customField5?: string;\n conversionConfigurationId?: string;\n createdAt?: string;\n updatedAt?: string;\n deletedAt?: string;\n}\n\nexport interface ShareAction {\n id: string;\n type: ShareActionType;\n title?: string;\n precedence?: number;\n stakeholderType?: string;\n url?: string;\n}\n\nexport enum ShareActionType {\n Hyperlink = \"Hyperlink\",\n Edit = \"Edit\",\n Approve = \"Approve\",\n}\n\n/**\n * An object containing ids for an external product/variant that should be added to the cart alongside the base product/variant.\n */\nexport interface DesignExternalVariant {\n id?: string;\n externalProductId?: string;\n externalProductVariantId?: string;\n skuCode?: string;\n}\n\n/**\n * An integration product represents the connection of a product in SpiffCommerce with\n * a product on a third party platform.\n */\nexport interface IntegrationProductResource {\n /**\n * The ID of the IntegrationProduct entity. Used internally by SpiffCommerce.\n */\n id: string;\n /**\n * The ID of the product on the third party platform. For example a Shopify product ID.\n */\n externalProductId?: string;\n /**\n * The integration that this product is associated with. For example a Shopify integration.\n */\n integration?: Integration;\n\n /**\n * The ID of an additional product (on the third party platform) that should be added to the cart.\n */\n additionalExternalProductId?: string;\n\n /**\n * A supplementary ID for the additional product. Shopify uses the variant ids to add products to the cart.\n */\n additionalExternalVariantId?: string;\n\n /**\n * When the additionalExternalProductId is set, this is the IntegrationProduct that is associated with it.\n * If no Spiff product has been associated with the additionalExternalProductId, this will be null.\n */\n additionalIntegrationProduct?: IntegrationProductResource;\n\n /**\n * The product that this integration product is associated with.\n */\n product?: Product;\n}\n\nexport interface Integration {\n id: string;\n enabled: boolean;\n externalIntegrationId?: string;\n type?: IntegrationType;\n isCurrent?: boolean;\n theme: Theme;\n logo: string;\n partner: Partner;\n marketplaceThemeInstallConfiguration?: ThemeInstallConfigurationGraphQl;\n name?: string;\n}\n\nexport interface Theme {\n configuration?: string;\n fontAsset?: Asset;\n id?: string;\n name?: string;\n primaryColor?: string;\n secondaryColor?: string;\n textColor?: string;\n themeLayout?: {\n id?: string;\n name?: string;\n };\n}\n\nexport enum IntegrationType {\n Hub = \"Hub\",\n Shopify = \"Shopify\",\n}\n\n/**\n * Fields found in a variant within a line item resource.\n */\nexport interface LineItemVariant {\n currencyCode: string;\n optionName: string;\n priceModifier: number;\n stepName: string;\n variantName: string;\n}\n\nexport interface LineItem {\n id: string;\n transactionId?: string;\n previewImageUrl?: string;\n product: Product;\n quantity: number;\n metadata?: LineItemMetadata[];\n variants: LineItemVariant[];\n}\n\nexport interface LineItemMetadata {\n stepName: string;\n metadata: string;\n}\n\nexport interface ProductWorkflow {\n friendlyName: string;\n id: string;\n index?: number;\n present?: boolean;\n imageUrl: string;\n workflowName: string;\n}\n\nexport interface Partner {\n id?: string;\n name?: string;\n currencyCode?: string;\n customerDetailsPromptMarkdown?: string;\n activeAddons?: AddonHandle[];\n beta?: boolean;\n}\n\nexport enum AddonHandle {\n BackgroundRemover = \"BackgroundRemover\",\n ConversionAccelerator = \"Conversion Accelerator\",\n ProcessBuilder = \"ProcessBuilder\",\n}\n\nexport interface Product {\n /**\n * ID of the partner owner.\n */\n partnerId?: string;\n partner?: Partner;\n\n /**\n * Whether a line item for this product is delivered as soon as the order is received.\n */\n autoprint: boolean;\n\n /**\n * Whether this product can be quickprinted.\n */\n canQuickprint?: boolean;\n\n /**\n * The internal identifier for this product.\n */\n id: string;\n\n /**\n * The human friendly name of the product.\n */\n name: string;\n\n /**\n * A description of the Product, written in Markdown.\n */\n description?: string;\n\n /**\n * A URL to the image asset associated with this product.\n */\n imageUrl?: string;\n\n /**\n * A resource url for a 3D model used to represent this product\n * in the 3d editor. If not available we assume the product doesn't support 3D.\n */\n modelUrl?: string;\n\n /**\n * A URL for the image used as an overlay on any workflows\n * that incorporate a product overlay step.\n */\n overlayImageUrl?: string;\n\n /**\n * Words which can't be used in a workflow for this product.\n */\n profanities?: {\n id: string;\n createdAt: string;\n userId: string;\n word: string;\n }[];\n\n /**\n * The max characters that can be typed for quickprint.\n */\n quickprintMaxLength?: number;\n\n /**\n * The name of the module to use for quickprint.\n */\n quickprintModuleName?: string;\n\n /**\n * If true, the product should be displayed in the client as if it is available.\n * Should be displayed as if it is unavailable otherwise.\n */\n enabled: boolean;\n\n /**\n * Workflows which have been assigned to this product.\n */\n workflows?: ProductWorkflow[];\n\n /**\n * The base price of this product in sub units. Essentially the cost of the\n * product without any customisations applied.\n */\n basePrice?: number;\n\n /**\n * The weight of this product.\n */\n weight?: number;\n\n minimumOrderQuantity?: number;\n\n /**\n * When specified, represents a pre-rendered image of this product to be\n * displayed to customers while the 3D preview is loading.\n */\n preloadImageUrl?: string;\n\n /**\n * When set the store owner has configured this product to prompt for\n * customer details. In hosted experience, we'll offer to collect this information from the customer. In\n * bespoke UIs created using the Core SDK you will need to check this flag and request the data accordingly.\n * See attachCustomerDetails on the WorkflowExperience for how to supply us with the details you collect.\n */\n promptForCustomerDetails?: boolean;\n\n /**\n * Configuration for conversion. Optional.\n */\n conversionConfiguration?: ConversionConfiguration;\n\n integrationProducts?: IntegrationProductResource[];\n\n productTags?: ProductTag[];\n\n productImages?: ProductImage[];\n\n /**\n * The SKU of the product in the merchant's store.\n */\n sku?: string;\n\n /**\n * The Spiff SKU code for the product.\n */\n skuCode?: string;\n\n /**\n * Price breaks for this product when dealing with quantity.\n */\n priceBreaks?: ProductPriceBreak[];\n}\n\nexport interface ProductImage {\n id: string;\n precedence?: number;\n asset: Asset;\n}\n\n/**\n * A price break represents a minimum quantity of a product and the price that will be charged for that quantity.\n * This can be seen as an override for the base price of the product.\n */\nexport interface ProductPriceBreak {\n /**\n * The id of this price break.\n */\n id: string;\n /**\n * The minimum quantity of this price break. A positive integer.\n */\n minQty: number;\n /**\n * A percentage to apply to the overall price. A value between 0-1 where 1 retains 100% of the original price and 0 completely discounts it to free.\n */\n percentage: number;\n}\n\nexport interface ProductTag {\n id: string;\n name: string;\n}\n\nexport interface ColorOption {\n id?: string;\n fill?: string;\n stroke?: string;\n variant?: VariantResource;\n colorProfileAssetKey?: string;\n pmsValue?: string;\n}\n\nexport interface RegionElement {\n id: string;\n region?: Region;\n regionIndex?: number;\n}\n\nexport interface FrameMetadata {\n image: string;\n}\n\nexport interface IllustrationMetadata {\n colors: string[];\n}\n\nexport interface ModuleMetadata {\n text: string;\n}\n\nexport interface TextMetadata {\n color?: string;\n text: string;\n fillImage?: string;\n strokeColor?: string;\n}\n\nexport interface SelectionStorage {\n selectedVariants?: VariantResource[];\n}\n\nexport interface FrameStepStorage extends SelectionStorage {\n framePatternAsset?: Asset;\n currentFrameSources?: string[];\n framePatternData?: {\n originalAssetKey?: string;\n backgroundRemovedAssetKey?: string;\n useOriginalAsset?: boolean;\n };\n}\n\nexport interface TextStepStorage extends SelectionStorage {\n color?: string;\n defaultCleared?: boolean;\n inputText?: string;\n text?: string;\n customiseAllText?: boolean;\n}\n\nexport type StepSelections = {\n [key: string]: SelectionStorage;\n};\n\nexport interface FrameData {\n /**\n * The path data for a frame SVG\n */\n path: string;\n\n /**\n * The viewbox width\n */\n width: number;\n\n /**\n * The viewbox height.\n */\n height: number;\n}\n\nexport interface FrameThresholdSettings {\n // Whether to enable a black and white threshold.\n useThreshold: boolean;\n // If using threshold, whether to invert black and white.\n invertThreshold: boolean;\n // An integer from 0 to 256.\n threshold: number;\n // A number from 0 to 1.\n thresholdSaturation: number;\n}\n\n/**\n * Details relating to a model for use in the preview.\n */\nexport type ModelDetails = {\n readonly model?: string;\n readonly contextService: RenderableContextService;\n};\n\n/**\n * A renderable context represents the relationship of a texture in the 3D preview\n * with an external canvas. This context allows external clients to render to a texture\n * in the 3D preview with a simple interface.\n */\nexport type RenderableContext = {\n /**\n * A unique identifier for this renderable context.\n */\n getID(): string;\n\n /**\n * A name for this renderable.\n */\n getName(): string;\n\n /**\n * Sets the render context associated to this renderable.\n * @param ctx The context to use for rendering.\n */\n setStaticContext(ctx: CanvasRenderingContext2D): void;\n\n /**\n * Get the render context associated to this renderable.\n */\n getStaticContext(): CanvasRenderingContext2D | undefined;\n\n /**\n * Sets whether or not this renderable is dirty and will need re-rendering.\n * @param value The new value\n */\n setStaticContextDirty(value: boolean): void;\n\n /**\n * When this context has been set as dirty, returns true.\n */\n getStaticContextDirty(): boolean;\n\n /**\n * A timestamp for the last successful render of the context.\n */\n getLastCompletedStaticRender(): number | undefined;\n};\n\n/**\n * Represents a handle to a material in the 3D scene. The underlying complexity of materials is abstracted\n * away so the client doesn't need to know anything more than the ID they're given and the name.\n */\nexport type MaterialHandle = {\n /**\n * The identifier for the material.\n */\n readonly id: string;\n /**\n * The human readable name for the material.\n */\n readonly name: string;\n};\n\n/**\n * Settings related to the 3D preview.\n */\nexport type PreviewOptions = {\n /**\n * The color expected to be seen in the background of the product. Expects a hexadecimal value.\n */\n readonly backgroundColor?: string;\n /**\n * Image to be used as a background when running with transparency, the image\n * will be scaled and centered to fill the preview based on aspect ratio.\n */\n readonly backgroundImage?: string;\n /**\n * The closest zoom the camera can achieve to the product.\n */\n readonly maxZoomOverride?: number;\n /**\n * The furthest zoom the camera can achieve to the product.\n */\n readonly minZoomOverride?: number;\n /**\n * The environment file used to calculate product lighting.\n */\n readonly environmentFile?: string;\n /**\n * The intensity of the environment lighting.\n */\n readonly environmentIntensity?: number;\n /**\n * The rotation (around the y axis) of the environment lighting, in degrees.\n */\n readonly environmentRotationY?: number;\n\n /**\n * The lowest point, vertically, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n readonly lowerBetaLimitDeg?: number;\n\n /**\n * The highest point, vertically, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n readonly upperBetaLimitDeg?: number;\n\n /**\n * The leftmost point, horizontally, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n readonly lowerAlphaLimitDeg?: number;\n\n /**\n * The rightmost point, horizontally, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n readonly upperAlphaLimitDeg?: number;\n\n /**\n * When set the product while rotate slowly\n */\n readonly autoRotation?: boolean;\n /**\n * Time in milliseconds before the product starts rotating after a user input has taken control.\n */\n readonly idleTimeBeforeRotation?: number;\n /**\n * When set the 3D preview won't attempt to orient the product automatically to its front view at load.\n */\n readonly disableAutomaticOrientation?: boolean;\n /**\n * When true the action bar won't be displayed to the user.\n */\n readonly disableActionBar?: boolean;\n /**\n * When set, mousing over the model in this preview will highlight the associated mesh/material.\n * When layout contexts are provided, only the materials with matching names will highlight.\n */\n readonly highlightOnMaterialHover?: boolean;\n /**\n * Sets the color of highlights when enabled. Expects hexadecimal value.\n */\n readonly highlightColor?: string;\n /**\n * When true, the user will not be able to pan the camera.\n */\n readonly noPan?: boolean;\n};\n\n/**\n * Defines the different behaviors supported by the camera system\n * for control when viewing a product.\n */\nexport enum ProductCameraRig {\n Orbit,\n Pan,\n}\n\n/**\n * Identical to CameraAnimation typing, however the\n * target is always available and hence is not optional.\n */\nexport type CameraPose = {\n readonly lonDeg: number;\n readonly radius: number;\n readonly latDeg: number;\n readonly target: {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n };\n};\n\nexport type LoadProgressEventData = {\n /**\n * The total load value of the scene, this is an average of all\n * 'in progress' loading events. when all events are fully loaded this value will be 100.\n */\n readonly loadValue: number;\n /**\n * This value is true when the base model and scene have been initialized.\n */\n readonly sceneInitialized: boolean;\n};\n\nexport interface Design {\n id?: string;\n sku?: string;\n transaction?: Transaction;\n processExecution?: {\n id?: string;\n };\n}\n\n/**\n * Someone who has used a workflow experience and entered their contact details.\n */\nexport interface Customer {\n id?: string;\n emailAddress: string;\n firstName?: string;\n lastName?: string;\n phoneNumber?: string;\n loginToken?: string;\n partner?: Partner;\n stakeholders?: Stakeholder[];\n bundleStakeholders?: BundleStakeholder[];\n hasBundleTemplates?: boolean;\n productCollectionCustomers?: ProductCollectionCustomer[];\n}\n\nexport interface ProductCollectionCustomer {\n id: string;\n customer: Customer;\n productCollection: ProductCollectionResource;\n}\n\nexport interface CustomerDetailsInput {\n emailAddress: string;\n firstName?: string;\n lastName?: string;\n phoneNumber?: string;\n}\n\nexport enum StakeholderType {\n Owner = \"Owner\",\n Approver = \"Approver\",\n Editor = \"Editor\",\n Viewer = \"Viewer\",\n}\n\nexport interface Stakeholder {\n id: string;\n type?: StakeholderType;\n authorizationDate?: string;\n authorizationNote?: string;\n authorizationStatus?: string;\n transaction?: Transaction;\n customer?: Customer;\n}\n\n/**\n * A wrapper for a list of bundles returned from the server.\n */\nexport interface BundlesFeed {\n /** The items. The size of this array will typically be limited by the request. */\n items: Bundle[];\n /** The total number of items available on the server that matched the initial request. */\n total: number;\n}\n\nexport enum BundleTemplateStatus {\n Draft = \"Draft\",\n Active = \"Active\",\n}\n\nexport interface Bundle {\n id?: string;\n bundleOwnerId?: string;\n completed?: boolean;\n dispatchDate?: string;\n purchaseOrder?: string;\n currentBundleStakeholder?: BundleStakeholder;\n bundleStakeholders?: BundleStakeholder[];\n bundleStateData?: string;\n globalPropertyState?: GlobalPropertyState;\n metadata?: { key: string; value: string }[];\n name?: string;\n partner?: Partner;\n productCollection?: ProductCollectionResource;\n transactions?: Transaction[];\n transactionIds?: string[];\n template?: boolean;\n templateStatus?: BundleTemplateStatus;\n bundleShareActions?: ShareAction[];\n workflowViewerLink: string;\n workflowViewerAmendLink: string;\n workflowViewerReadOnlyLink: string;\n createdAt: string;\n updatedAt: string;\n transactionsCount?: number;\n productsCount?: number;\n totalPriceSubunits?: number;\n orderId?: string;\n externalOrderId?: string;\n internalOrderId?: string;\n quoteId?: string;\n}\n\nexport interface BundleStakeholder {\n id: string;\n bundle?: Bundle;\n customer?: Customer;\n type?: StakeholderType;\n authorizationDate?: string;\n authorizationNote?: string;\n authorizationStatus?: string;\n}\n\nexport interface BundleStakeholderInput {\n type: StakeholderType;\n customerDetails: CustomerDetailsInput;\n}\n\nexport type ProductCollectionResource = {\n id: string;\n globalPropertyConfiguration?: GlobalPropertyConfiguration;\n productCollectionProducts?: ProductCollectionProductResource[];\n productCollectionProductsFeed?: ProductCollectionProductsFeedResource;\n name: string;\n description?: string;\n dispatchStartDate?: string;\n dispatchEndDate?: string;\n image?: Asset;\n productCollectionCustomers?: ProductCollectionCustomer[];\n};\n\nexport type ProductCollectionProductResource = {\n id: string;\n productCollection?: ProductCollectionResource;\n productCollectionId?: string;\n product: Product;\n productId: string;\n workflowId?: string;\n};\n\nexport type ProductCollectionProductsFeedResource = {\n items: ProductCollectionProductResource[];\n total: number;\n};\n\nexport interface ProductCollectionCustomer {\n id: string;\n customer: Customer;\n productCollection: ProductCollectionResource;\n}\n\nexport type GlobalPropertyState = {\n id: string;\n aspects: GlobalPropertyStateAspect[];\n};\n\nexport type GlobalPropertyStateAspect = {\n name: string;\n value: string;\n type?: AspectType;\n storage?: GlobalPropertyStateAspectStorage;\n channel?: number;\n};\n\nexport type GlobalPropertyStateAspectStorage =\n | GlobalPropertyStateFileUploadStorage\n | GlobalPropertyStateColorOptionStorage;\n\nexport type GlobalPropertyStateFileUploadStorage = {\n originalAssetKey?: string;\n backgroundRemovedAssetKey?: string;\n useOriginalAsset?: boolean;\n colors?: GlobalPropertyStateIllustrationColor[];\n};\n\nexport type GlobalPropertyStateIllustrationColor = {\n key: string;\n browserValue: string;\n pmsValue?: string;\n};\n\nexport type GlobalPropertyStateColorOptionStorage = {\n customColor?: string;\n};\n\nexport interface BundleStateData {\n transactions: BundleStateTransaction[];\n integrationProductIds?: string[];\n}\n\nexport interface BundleStateTransaction {\n transactionId: string;\n}\n\n// Allows a type to be extended with other arbitrary fields, while still requiring the base fields.\nexport type Extendable<T> = T & { [key: string]: any };\n\nexport interface Metafield {\n id: string;\n createdAt: string;\n updatedAt: string;\n entityId: string;\n value: string;\n metafieldConfiguration: MetafieldConfiguration;\n}\n\nexport interface MetafieldConfiguration {\n id: string;\n createdAt: string;\n updatedAt: string;\n entityType: string;\n metafieldType: string;\n name: string;\n}\n\nexport enum TextAlgorithm {\n /**\n * An algorithm that finds the best size for text based\n * on a range minSize <-> maxSize\n * NOTE: Default, this is how we've calculated historically.\n */\n Autosize = \"Autosize\",\n /**\n * An algorithm that follows behavior of other popular\n * text editing applications.\n */\n Traditional = \"Traditional\",\n}\n\nexport interface FrameElement extends LayoutElement {\n // The source path for the frame. Equivalent to the d attribute of an SVG path element.\n path: string;\n\n /**\n * Assigns the 'data-frame-width' attribute to the frame element. The rasterizer we use has issues with images inside\n * patterns. This is a workaround to ensure that the pattern is correctly sized.\n */\n dataWidth?: number;\n /**\n * Assigns the 'data-frame-height' attribute to the frame element. The rasterizer we use has issues with images inside\n * patterns. This is a workaround to ensure that the pattern is correctly sized.\n */\n dataHeight?: number;\n\n // Disables the placeholder image for this frame. Instead the frame will\n // be blank before any image is UploadRounded.\n disablePlaceholder?: boolean;\n\n // FIXME: Scale was removed from all other elements however persists on frames\n // to ensure backwards compat with existing functionality. We should remove this when we can.\n scaleX: number;\n scaleY: number;\n\n // The opacity of the frame\n opacity?: number;\n // The pattern for this frame. Roughly translates to a pattern tag in SVG.\n pattern?: Pattern;\n // Properties used to control focal blur in frames.\n focalBlur?: boolean;\n focalBlurStrength?: number;\n focalBlurRadius?: number;\n forceImageCover?: boolean;\n\n // Whether to enable a black and white threshold.\n useThreshold?: boolean;\n // If using threshold, whether to invert black and white.\n invertThreshold?: boolean;\n // An integer from 0 to 256.\n threshold?: number;\n // A number from 0 to 1.\n thresholdSaturation?: number;\n}\n\n/**\n * A pattern object stores data relevant for displaying an image within a frame, including\n * the source for the image itself and also dimensions and offsets.\n */\ninterface Pattern extends Omit<LayoutElement, \"type\"> {\n /**\n * The image to use when a file is generated, this should be an original high resolution source file.\n */\n src: string;\n\n /**\n * Scaling X of image within frame.\n */\n scaleX: number;\n\n /**\n * Scaling Y of image within frame.\n */\n scaleY: number;\n\n /**\n * The SVG document that the src represents. This must be the actual content string of the document, rather than a URL.\n */\n svg?: string;\n\n /**\n * A map of ID to color code, used to store color selections in the SVG. Only applicable when `svg` is provided.\n */\n colors?: { [key: string]: ColorDefinition };\n}\n\nexport interface GroupElement extends LayoutElement {\n /**\n * A clip path applied to the group\n */\n clipPath?: string;\n /**\n * Elements renderable inside this group.\n */\n children: LayoutElement[];\n}\n\nexport interface IllustrationElement extends LayoutElement {\n /**\n * When provided a src will be used to rehyrdrate the svg field. On serialization\n * the svg field will be dropped and only src will remain.\n */\n src?: string;\n /**\n * The string representation of the SVG element. A valid SVG document.\n */\n svg?: string;\n /**\n * A cached image representation of this SVG, to be used for faster\n * rendering in performance critical code.\n */\n cachedObjectURL?: string;\n /**\n * A map of ID to color code, used to store color selections in the SVG.\n */\n colors: { [key: string]: ColorDefinition };\n}\n\n/**\n * Represents a raster image on the Papyrus canvas.\n */\nexport interface ImageElement extends LayoutElement {\n /**\n * A src for the image. This will be used in place of the data URL in server environments and should\n * be original image quality.\n */\n src: string;\n /**\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n */\n preserveAspectRatio?: string;\n}\n\nexport interface TextboxElement extends LayoutElement {\n /**\n * Horizontal alignment of text. eg. left, center, right.\n */\n align?: string;\n /**\n * An image to use as the fill instead of a color.\n */\n textFillImage?: TextFillImage;\n /**\n * Fill color of this text. Any value that can be parsed by css fill should work here.\n */\n fill: string;\n /**\n * The font size.\n */\n fontSize: number;\n /**\n * Information about the font family used to render this text.\n */\n fontData: FontData | undefined;\n /**\n * Text computed for this textbox.\n */\n text?: string;\n /**\n * Per element user input. Not used by the layout engine. Instead\n * used to store user input for textbox to preserve newlines.\n */\n input?: string;\n /**\n * Should the text layout top to bottom.\n */\n vertical?: boolean;\n /**\n * The height between text lines.\n */\n lineHeight?: number;\n /**\n * The alignment of text vertically, top center or bottom.\n */\n verticalAlign: string;\n /**\n * When true the text will be rendered using the provided curve.\n */\n curved?: boolean;\n /**\n * The curve to use when curved = true. Ignored otherwise.\n */\n paths?: string[]; // TODO: remove array and change to path from paths.\n /**\n * The algorithm to use when laying out text.\n */\n algorithm?: TextAlgorithm;\n\n fillSpotColorDefinition?: SpotColorDefinition;\n\n strokeColor?: ColorDefinition;\n strokeThickness?: string;\n}\n\nexport interface FontData {\n assetUrl: string;\n name: string;\n}\n\n/**\n * A container for data related to a specific spotcolor. toString\n * can be used to output a string expected by Filegen inside a stroke or fill.\n */\nexport interface SpotColorDefinition {\n /**\n * The name of the profile being used.\n */\n profileName: string;\n\n /**\n * The named color expected by the profile.\n */\n namedColor: string;\n}\n\n/**\n * Contains configuration for font sizing.\n *\n * When min/maxSize values are set we interpret the textbox as being\n * in \"Variable Mode\" which essentially\n * auto sizes the text based on a given region.\n *\n * When only size is set, we interpret the textbox as being in \"Fixed Mode\" where\n * text is computed at a fixed font size.\n */\nexport interface SizeRange {\n /**\n * Variable Mode: A maximum size\n */\n maxSize?: number;\n\n /**\n * Variable Mode: Minimum Size\n */\n minSize?: number;\n\n /**\n * Fixed Mode: A Fixed font size to be used at all times.\n */\n size: number;\n}\n\nexport interface CanvasRegion {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\nexport interface ColorDefinition {\n /**\n * Represents the color value in hex or any other\n * browser supported format. This will be used when rendering the canvas\n * in an environment that doesn't support spot color.\n */\n browserValue: string;\n\n /**\n * A spot color definition. This is optional and will\n * be applied to the SVG returned by toString when configured allowing\n * filegen to output spot colors.\n */\n spotColor?: SpotColorDefinition;\n\n /**\n * Represents the color value in the PMS colorspace.\n */\n pmsValue?: string;\n}\n\n/**\n * A container for data related to a specific spotcolor. toString\n * can be used to output a string expected by Filegen inside a stroke or fill.\n */\nexport interface SpotColorDefinition {\n /**\n * The name of the profile being used.\n */\n profileName: string;\n\n /**\n * The named color expected by the profile.\n */\n namedColor: string;\n}\n\nexport interface TextFillSpotColor {\n profileName: string;\n namedColor: string;\n}\n\nexport interface PatternImageData {\n /**\n * The original src of the image.\n */\n src: string;\n\n /**\n * The natural width of the image.\n */\n width: number;\n\n /**\n * The natural height of the image.\n */\n height: number;\n\n /**\n * Cached result of the calculation width/height.\n */\n aspect: number;\n\n /**\n * The SVG document that the src represents. This must be the actual content string of the document, rather than a URL.\n */\n svg?: string;\n\n /**\n * A map of ID to color code, used to store color selections in the SVG. Only applicable when `svg` is provided.\n */\n colors?: { [key: string]: ColorDefinition };\n}\n\n/**\n * Defines the direction of scaling, can be used\n * to determine the anchor point of a scale calculation.\n */\nexport enum ScaleAxis {\n North,\n Northeast,\n East,\n Southeast,\n South,\n Southwest,\n West,\n Northwest,\n}\n\n/**\n * A point in a 2D coordinate space.\n */\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface Workflow {\n defaultPreviewPanelIndex?: number;\n deletedAt?: Date;\n id: string;\n previewAssetKey?: string;\n previewImageUrl?: string;\n name: string;\n introduction: string;\n panels: WorkflowPanel[];\n showModelOnFinishStep: boolean;\n showPricing?: boolean;\n baseCurrency?: string;\n showPlusInVariantPrices?: boolean;\n allowProofDownload: boolean;\n steps: Step<AnyStepData>[];\n stepGroups: StepGroup[];\n theme?: {\n primaryColour: string;\n textColour: string;\n };\n globalPreviewConfig?: PreviewConfiguration;\n finalizeStepConfig?: FinalizeStepConfig;\n partnerId?: string;\n toggleBulkSourceView?: boolean;\n overrideTheme?: Theme;\n globalPropertyConfiguration?: GlobalPropertyConfiguration;\n}\n\nexport interface WorkflowPanel {\n height: number;\n width: number;\n name: string;\n title?: string;\n index: number;\n transparentBackground?: boolean;\n previewRegion?: PreviewRegion;\n useEditableArea?: boolean;\n editableArea?: {\n x: number;\n y: number;\n height: number;\n width: number;\n };\n}\n\nexport interface StepGroup {\n id?: string;\n name: string;\n stepNames: string[];\n}\n\nexport interface FinalizeStepConfig {\n termsMarkdown?: string;\n modelAnimation?: ModelAnimation;\n lookAtAnimation?: CameraAnimation;\n previewRegion?: { left: number; top: number; width: number; height: number };\n}\n\nexport interface PreviewRegion {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\nexport interface ModelAnimation {\n /**\n * A value it seconds along the animation timeline to begin at.\n */\n from?: number;\n /**\n * A value in seconds along the animation timeline to end at.\n */\n to?: number;\n /**\n * When true the animation will loop. The only behaviour currently is to reset\n * back to from but we could have it bounce back and forth and/or follow a curve.\n */\n loop?: boolean;\n /**\n * The name of the animation to play.\n */\n name?: string;\n}\n\n/**\n * A CameraAnimation specifies a discrete state that the camera should\n * animate to. This state represents the final position of the camera after animations have run.\n */\nexport interface CameraAnimation {\n /**\n * The longitutude in degrees the camera should animate to.\n */\n lonDeg: number;\n /**\n * The lattitude in degrees the camera should animnate to.\n */\n latDeg: number;\n /**\n * An optional target for the camera to focus on in the scene.\n */\n target?: { x: number; y: number; z: number };\n /**\n * A value in scene units specifying camera distance from the target.\n */\n radius?: number;\n}\n\n/**\n * Settings related to the 3D preview for use at either a global level or at per step level. The global\n * values can be a default if per step values aren't specified.\n */\nexport interface PreviewConfiguration {\n /**\n * @deprecated Removed in favor of backgroundColor as a simple hexadecimal color value.\n */\n clearColor?: [number, number, number];\n /**\n * The color expected to be seen in the background of the product\n */\n backgroundColor?: string;\n /**\n * The closest zoom the camera can achieve to the product.\n */\n maxZoomOverride?: number;\n /**\n * The furthest zoom the camera can achieve to the product.\n */\n minZoomOverride?: number;\n /**\n * The environment file used to calculate product lighting.\n */\n environmentFile?: string;\n\n /**\n * The lowest point, vertically, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n lowerBetaLimitDeg?: number;\n\n /**\n * The highest point, vertically, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n upperBetaLimitDeg?: number;\n\n /**\n * The leftmost point, horizontally, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n lowerAlphaLimitDeg?: number;\n\n /**\n * The rightmost point, horizontally, that the camera can rotate to.\n * https://doc.babylonjs.com/divingDeeper/cameras/camera_introduction\n */\n upperAlphaLimitDeg?: number;\n\n /**\n * When set the product while rotate slowly\n */\n autoRotation?: boolean;\n /**\n * Time in milliseconds before the product starts rotating after a user input has taken control.\n */\n idleTimeBeforeRotation?: number;\n /**\n * When set the 3D preview won't attempt to orient the product automatically to its front view at load.\n */\n disableAutomaticOrientation?: boolean;\n /**\n * When true the action bar won't be displayed to the user.\n */\n disableActionBar?: boolean;\n\n /**\n * When true the AR button will be displayed to the user.\n */\n enableAR?: boolean;\n}\n\nexport enum UnitOfMeasurement {\n Pixel = \"px\",\n Millimeter = \"mm\",\n Centimeter = \"cm\",\n}\n\nexport type PapyrusComponent<T = any> = FunctionComponent<T>;\n\nexport type PapyrusNode = ReactNode;\n\nexport interface Order {\n id: string;\n internalId: string;\n}\n\nexport interface OrderItem {\n transactionId: string;\n amountToOrder: number;\n}\n","import { AnyStepData, Asset, Region, Step, VariantResource } from \"../types\";\n\n/**\n * A generic base class for custom errors that assigns the name\n * of the error class automatically. All custom errors should extend this.\n */\nabstract class CustomError extends Error {\n constructor(message) {\n super(message);\n this.name = this.constructor.name;\n }\n}\n\n/**\n * A custom class for categorising errors related to workflow configuration.\n */\nabstract class ConfigurationError extends CustomError {\n constructor(message) {\n super(`ConfigurationError - ${message}`);\n }\n}\n\n/**\n * Thrown when an option was expected but not found in the workflow configuration or\n * the server returned a 404 for an option we expected.\n */\nclass OptionNotFoundError extends ConfigurationError {\n readonly optionId: string;\n constructor(step: Step<AnyStepData>) {\n super(`Option not Configured: ${step.stepTitle}`);\n this.optionId = step?.optionId || \"N/A\";\n }\n}\n\n/**\n * Thrown when a layout is not found for a given region entity. This\n * can occur when panels are deleted from a workflow but steps are still relying\n * on the layout being present.\n */\nclass LayoutNotFoundError extends ConfigurationError {\n readonly panelId: string;\n constructor(region: Region) {\n super(`Panel not Found: ${region.panelId}`);\n this.panelId = region?.panelId || \"N/A\";\n }\n}\n\n/**\n * Thrown when an asset is not found on a specific variant. This can occur when\n * the asset wasn't configured in hub and the variant is loaded in a workflow.\n */\nclass AssetNotFoundError extends ConfigurationError {\n readonly variant: VariantResource;\n constructor(variant: VariantResource) {\n super(`Asset not found for variant: ${variant.name}`);\n this.variant = variant;\n }\n}\n\n/**\n * Thrown when a resource is not found linked to a specific asset. This\n * can occur when generation of a resource fails or hasn't completed. Or may be\n * a sign of a misconfiguration.\n */\nclass ResourceNotFoundError extends ConfigurationError {\n readonly asset: Asset;\n constructor(asset: Asset) {\n super(`Resource not found for asset: ${asset.name}`);\n this.asset = asset;\n }\n}\n\n/**\n * Thrown when configuration is missing when it was expected. More generic\n * to cover remaining cases outside of the more specific ones such as options, variants & assets.\n */\nclass MisconfigurationError extends ConfigurationError {\n readonly step: Step<AnyStepData>;\n constructor(step: Step<AnyStepData>, message: string) {\n super(`Workflow Misconfiguration: ${step.stepName} - ${message}`);\n this.step = step;\n }\n}\n\n/**\n * A custom class for categorising errors related to implementation of core.\n */\nabstract class ImplementationError extends CustomError {\n constructor(message) {\n super(`ImplementationError - ${message}`);\n }\n}\n\n/**\n * Thrown when we hit a case that we didn't expect to happen\n */\nclass UnhandledBehaviorError extends ImplementationError {\n constructor(message: string) {\n super(`Unhandled Behavior Encountered: ${message}`);\n }\n}\n\n/**\n * Thrown when we fail to parse something that we expected to be valid\n */\nclass ParseError extends ImplementationError {\n constructor(message: string) {\n super(`Parsing Error: ${message}`);\n }\n}\n\n/**\n * Thrown when we use the client in a way that is not supported by the platform.\n */\nclass ClientError extends ImplementationError {\n constructor(message: string) {\n super(`Client Error: ${message}`);\n }\n}\n\n/**\n * Thrown when we fail to generate a resource on the client. Generally this is\n * due to poor handling of device or browser specific requirements like memory limits.\n */\nclass ResourceGenerationError extends ImplementationError {\n constructor(message: string) {\n super(`Resource Generation Failed: ${message}`);\n }\n}\n\n// Config errors\nexport { OptionNotFoundError, LayoutNotFoundError, AssetNotFoundError, ResourceNotFoundError, MisconfigurationError };\n\n// Implementation errors\nexport { UnhandledBehaviorError, ClientError, ResourceGenerationError, ParseError };\n","interface StorageService {\n /**\n * Get a value.\n * @param key The key to lookup the value with.\n */\n get(key: string): string | undefined;\n /**\n * Set a value.\n * @param key The key to set.\n * @param val The new value.\n */\n set(key: string, val: string): void;\n /**\n * Remove a value.\n * @param key The key to remove, does nothing if the key doesn't exist.\n */\n remove(key: string): void;\n /**\n * Get a map from persistence.\n * @param key The key to search by.\n */\n getMap<K = any, V = any>(key: string): Map<K, V> | undefined;\n /**\n * St a map into persistence.\n * @param key The key to set the map at.\n * @param val The map to set.\n */\n setMap<K = any, V = any>(key: string, val: Map<K, V>): void;\n}\n\n/**\n * Storage built upon browser localStorage capability.\n */\nclass LocalStorageService implements StorageService {\n get(key: string): string | undefined {\n return localStorage.getItem(key) || undefined;\n }\n set(key: string, val: string): void {\n localStorage.setItem(key, val);\n }\n remove(key: string): void {\n localStorage.removeItem(key);\n }\n getMap(key: string): Map<any, any> | undefined {\n const serialisedMap = this.get(key);\n if (!serialisedMap) {\n return;\n }\n return new Map(JSON.parse(serialisedMap));\n }\n setMap(key: string, val: Map<any, any>): void {\n const mapSerialised = JSON.stringify([...val.entries()]);\n this.set(key, mapSerialised);\n }\n}\n\n/**\n * An in-memory fallback storage when we encounter environments that don't support localStorage.\n */\nclass InMemoryStorageService implements StorageService {\n private storage: Map<string, string> = new Map();\n get(key: string): string | undefined {\n return this.storage.get(key) || undefined;\n }\n set(key: string, val: string): void {\n this.storage.set(key, val);\n }\n remove(key: string): void {\n this.storage.delete(key);\n }\n getMap(key: string): Map<any, any> | undefined {\n const serialisedMap = this.get(key);\n if (!serialisedMap) {\n return;\n }\n return new Map(JSON.parse(serialisedMap));\n }\n setMap(key: string, val: Map<any, any>): void {\n const mapSerialised = JSON.stringify([...val.entries()]);\n this.set(key, mapSerialised);\n }\n}\n\nconst buildPersistentStorage = (): StorageService => {\n try {\n if (localStorage) {\n return new LocalStorageService();\n }\n return new InMemoryStorageService();\n } catch {\n console.warn(\"Local storage was unavilable due to browser security settings. Using in-memory storage instead.\");\n return new InMemoryStorageService();\n }\n};\n\nexport const persistenceService = buildPersistentStorage();\n","class Configuration {\n private readonly defaultServerUrl = \"https://api.au.spiffcommerce.com\";\n private readonly defaultServicesApiUrl = \"https://services.au.spiffcommerce.com\";\n private readonly defaultHubUrl = \"https://hub.au.spiffcommerce.com\";\n\n private serverUrl: string;\n private servicesApiUrl: string;\n private hubUrl: string;\n\n private serverUrlCallbacks: (() => void)[];\n\n constructor() {\n this.serverUrl = this.defaultServerUrl;\n this.servicesApiUrl = this.defaultServicesApiUrl;\n this.hubUrl = this.defaultHubUrl;\n this.serverUrlCallbacks = [];\n }\n\n getServerUrl() {\n return this.serverUrl;\n }\n\n getServicesApiUrl() {\n return this.servicesApiUrl;\n }\n\n getHubUrl() {\n return this.hubUrl;\n }\n\n setServerUrl(serverUrl: string) {\n this.serverUrl = serverUrl;\n this.serverUrlCallbacks.forEach((callback) => callback());\n }\n\n setServicesApiUrl(servicesApiUrl: string) {\n this.servicesApiUrl = servicesApiUrl;\n }\n\n setHubUrl(hubUrl: string) {\n this.hubUrl = hubUrl;\n }\n\n addServerUrlCallback(callback: () => void) {\n this.serverUrlCallbacks.push(callback);\n }\n}\n\nexport const spiffCoreConfiguration = new Configuration();\n","import { Font } from \"opentype.js\";\nimport { renderToStaticMarkup } from \"preact-render-to-string\";\nimport { PapyrusNode } from \"../types\";\n\nlet domImpl: any = undefined;\nlet fetchImpl: ((input: RequestInfo | URL, init?: RequestInit) => Promise<Response>) | undefined = undefined;\n\n/**\n * We use this to register a window in environments where one wouldn't be available.\n */\nexport function registerWindowImplementation(impl: any) {\n domImpl = impl;\n}\n\nexport function registerFetchImplementation(impl: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>) {\n fetchImpl = impl;\n}\n\nfunction getWindow(): Window {\n if (!domImpl) {\n console.log(\n \"DOM constructor is not registered. Assuming browser environment. If not, please register DOM constructor before calling this function.\",\n );\n return window;\n }\n return new domImpl().window;\n}\n\nexport function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n if (!fetchImpl) {\n if (typeof window !== \"undefined\" && window.fetch) {\n return window.fetch(input, init);\n }\n if (typeof global !== \"undefined\" && global.fetch) {\n return global.fetch(input, init);\n }\n throw new Error(\"Fetch implementation is not registered. Please register it before calling this function.\");\n }\n return fetchImpl(input, init);\n}\n\nconst arrayBufferMimeTypeCache: Map<string, string> = new Map();\nconst arrayBufferFileCache: Map<string, Promise<ArrayBuffer>> = new Map();\nconst textFileCache: Map<string, Promise<string>> = new Map();\n\nconst getFromArrayBufferCache = async (url: string): Promise<ArrayBuffer> => {\n const cachedPromise = arrayBufferFileCache.get(url);\n if (cachedPromise) return cachedPromise;\n const getData = async () => {\n const resp = await fetch(url);\n arrayBufferMimeTypeCache.set(url, resp.headers?.get(\"content-type\") || \"\");\n return await resp.arrayBuffer();\n };\n const ab = getData();\n arrayBufferFileCache.set(url, ab);\n return ab;\n};\n\nconst getFromTextCache = async (url: string): Promise<string> => {\n const cachedPromise = textFileCache.get(url);\n if (cachedPromise) return cachedPromise;\n const getData = async () => {\n const resp = await fetch(url);\n return await resp.text();\n };\n const ab = getData();\n textFileCache.set(url, ab);\n return ab;\n};\n\n// Whether each capability in the list is present.\n// The Web API has all sorts of stuff that aren't present on the server.\nconst hasCapabilities = (capabilities: string[]): boolean => {\n return capabilities.every((cap) => cap !== \"undefined\");\n};\n\nexport const createElement = (tag: string): HTMLElement => {\n if (hasCapabilities([typeof document])) {\n return document.createElement(tag);\n }\n const doc = getWindow().document;\n return doc.createElement(tag);\n};\n\nexport const createElementNS = (namespace: string, tag: string) => {\n if (hasCapabilities([typeof document])) {\n return document.createElementNS(namespace, tag);\n }\n const doc = getWindow().document;\n const elem = doc.createElement(tag);\n elem.setAttribute(\"xmlns\", namespace);\n return elem;\n};\n\nexport const domParser = () => {\n if (hasCapabilities([typeof DOMParser])) {\n return new DOMParser();\n }\n const w = getWindow();\n return new (w as any).DOMParser();\n};\n\nexport const domParserConstructor = (): typeof DOMParser => {\n if (hasCapabilities([typeof DOMParser])) {\n return DOMParser;\n }\n const w = getWindow();\n return (w as any).DOMParser;\n};\n\nexport const fetchAsArrayBuffer = (externalUrl: string, allowCache?: boolean): Promise<ArrayBuffer> => {\n return new Promise((resolve, reject) => {\n if (!allowCache) {\n fetch(externalUrl)\n .then((response) => {\n response.arrayBuffer().then(resolve).catch(reject);\n })\n .catch((err) => {\n reject(err);\n });\n } else {\n getFromArrayBufferCache(externalUrl).then(resolve).catch(reject);\n }\n });\n};\n\nexport const fetchAsString = (externalUrl: string, allowCache?: boolean): Promise<string> => {\n return new Promise((resolve, reject) => {\n if (!allowCache) {\n fetch(externalUrl)\n .then((response) => {\n response.text().then(resolve).catch(reject);\n })\n .catch(reject);\n } else {\n getFromTextCache(externalUrl).then(resolve).catch(reject);\n }\n });\n};\n\nexport const renderPapyrusComponentAsString = (component: PapyrusNode) => {\n const svg = renderToStaticMarkup(component as any);\n return svg;\n};\n\n/**\n * Cache for fontfaces to prevent multiple loads of the same font.\n * This is required since the browser will still attempt to load it again every time, even if it would hit the cache.\n * Spawning off many requests for items that would hit cache still takes time, and can actually get blocked by the browser.\n */\nconst fontFaceCache: Map<string, Promise<FontFace>> = new Map();\n\n/**\n * Loads a given font as a font face set in the browser. This function has\n * no effect in a server environment, in the browser it gives the browser access to a font face for\n * use in font rendering.\n * If the font has already been loaded, this function will return the existing promise.\n * @param font An opentype font object.\n * @param externalUrl An external URL that can be used to access the original font file.\n * @returns A promise resolved when the font has been loaded. Rejected if an error occured.\n */\nexport const loadFontFaceSet = async (font: Font, externalUrl: string): Promise<FontFace | undefined> => {\n if (hasCapabilities([typeof FontFace])) {\n if (fontFaceCache.has(externalUrl)) {\n return fontFaceCache.get(externalUrl);\n }\n const familyName = font.names.fullName[\"en\"];\n const fontFace = new FontFace(familyName, `url(${externalUrl})`);\n (document.fonts as any).add(fontFace);\n const promise = fontFace.load();\n fontFaceCache.set(externalUrl, promise);\n return promise;\n }\n return undefined;\n};\n\nexport const xmlSerializer = (): XMLSerializer => {\n if (hasCapabilities([typeof XMLSerializer])) {\n return new XMLSerializer();\n }\n const w = getWindow();\n return new (w as any).XMLSerializer();\n};\n\nexport const toBase64 = (input: string): string => {\n return btoa(input);\n};\n\n// The file-type library guesses an array buffer's mime type using magic numbers.\n// It therefore only works on binary formats, not text formats like SVG.\n// SVG is currently the only text case that this function must handle.\n// If that ever changes then this function will have to become smarter.\nexport const getMimeTypeOfArrayBuffer = (arrayBuffer: ArrayBuffer): string => {\n function getMimeTypeFromArrayBuffer() {\n const uint8arr = new Uint8Array(arrayBuffer);\n const len = 4;\n if (uint8arr.length >= len) {\n const signatureArr = new Array(len);\n for (let i = 0; i < len; i++) signatureArr[i] = new Uint8Array(arrayBuffer)[i].toString(16);\n const signature = signatureArr.join(\"\").toUpperCase();\n\n switch (signature) {\n case \"89504E47\":\n return \"image/png\";\n case \"47494638\":\n return \"image/gif\";\n case \"25504446\":\n return \"application/pdf\";\n case \"504B0304\":\n return \"application/zip\";\n }\n\n // Some magic numbers are shorter.\n const sig = signature.slice(0, 4);\n switch (sig) {\n case \"FFD8\":\n return \"image/jpeg\";\n }\n }\n return null;\n }\n const mimeTypeData = getMimeTypeFromArrayBuffer();\n if (!mimeTypeData) {\n return \"image/svg+xml\";\n }\n return mimeTypeData;\n};\n\nexport const dataUrlFromExternalUrl = async (url: string): Promise<string> => {\n const blob = await getFromArrayBufferCache(url);\n const type = arrayBufferMimeTypeCache.get(url) || getMimeTypeOfArrayBuffer(blob);\n return await webBlobToDataUrl(new Blob([blob], { type }));\n};\n\nconst uint8ArrayToString = (array: Uint8Array): string => {\n let binary = \"\";\n const len = array.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(array[i]);\n }\n return binary;\n};\n\nexport const arrayBufferToDataUrl = async (arrayBuffer: ArrayBuffer): Promise<string> => {\n const mimeType = getMimeTypeOfArrayBuffer(arrayBuffer);\n\n const uint8Array = new Uint8Array(arrayBuffer);\n const binaryString = uint8ArrayToString(uint8Array);\n const b64 = btoa(binaryString);\n\n return `data:${mimeType};base64,${b64}`;\n};\n\nexport const svgToDataUrl = (svgString: string): string => {\n return `data:image/svg+xml;base64,${btoa(svgString)}`;\n};\n\nexport const dataUrlToArrayBuffer = (dataUrl: string): ArrayBuffer => {\n // strip newlines\n const uri = dataUrl.replace(/\\r?\\n/g, \"\");\n\n // split the URI up into the \"metadata\" and the \"data\" portions\n const firstComma = uri.indexOf(\",\");\n if (firstComma === -1 || firstComma <= 4) {\n throw new TypeError(\"malformed data: URI\");\n }\n\n // remove the \"data:\" scheme and parse the metadata\n const meta = uri.substring(5, firstComma).split(\";\");\n\n let base64 = false;\n for (let i = 1; i < meta.length; i++) {\n if (meta[i] === \"base64\") {\n base64 = true;\n }\n }\n // get the encoded data portion and decode URI-encoded chars\n const data = decodeURI(uri.substring(firstComma + 1));\n\n // convert the data to an array buffer.\n if (base64) {\n const buf = new Uint8Array(\n atob(data)\n .split(\"\")\n .map((c) => c.charCodeAt(0)),\n );\n return buf.buffer;\n } else {\n const buf = new Uint8Array(data.split(\"\").map((c) => c.charCodeAt(0)));\n return buf.buffer;\n }\n};\n\nconst webBlobToDataUrl = (blob: Blob): Promise<string> => {\n return new Promise((resolve, reject) => {\n const a = new FileReader();\n a.onload = function (e: any) {\n const target = e.target;\n if (!target || !target.result) {\n reject();\n } else {\n resolve(target.result.toString());\n }\n };\n a.readAsDataURL(blob);\n });\n};\n","import { ApolloClient, createHttpLink, from, InMemoryCache } from \"@apollo/client/core\";\nimport { setContext } from \"@apollo/client/link/context\";\nimport { onError } from \"@apollo/client/link/error\";\nimport { spiffCoreConfiguration } from \"../Configuration\";\nimport { fetch } from \"../util/crossplatform\";\nimport { removeTypenameFromVariables } from \"@apollo/client/link/remove-typename\";\nimport { SpiffCommerceClient } from \"../client\";\nimport { Integration } from \"..\";\n\n/**\n * The different types of authentication for server calls.\n */\ninterface AuthenticationObject {\n activeIntegration?: string;\n applicationKey?: string;\n bearer?: string;\n customerToken?: string;\n partnerId?: string;\n}\n\nlet localCustomerToken: string | undefined = undefined;\nexport const setLocalCustomerToken = (customerToken: string) => {\n localCustomerToken = customerToken;\n};\n\nlet applicationKey: string | undefined = undefined;\nexport const setApplicationKey = (key: string) => {\n applicationKey = key;\n};\n\nexport const getApplicationKey = () => {\n return applicationKey;\n};\n\nlet bearerAuthenticationToken: string | undefined = undefined;\nexport const setBearerAuthenticationToken = (token: string) => {\n bearerAuthenticationToken = token;\n};\n\n/**\n * Request authentication from the parent window.\n * @returns A promise resolving to an authentication object containing\n * the required credentials.\n */\nconst getHubAuthentication = (): Promise<AuthenticationObject> => {\n return new Promise((resolve) => {\n const hubUrl = spiffCoreConfiguration.getHubUrl();\n const onAuthenticationReceived = (event: MessageEvent<AuthenticationObject>) => {\n if (event.origin !== hubUrl) return;\n window.removeEventListener(\"message\", onAuthenticationReceived);\n resolve(event.data);\n };\n if (window.parent !== window) {\n window.addEventListener(\"message\", onAuthenticationReceived, false);\n window.parent.postMessage(\"ready\", hubUrl);\n }\n });\n};\n\n/**\n * Retrieve stored authentication values for server calls.\n */\nconst getServerAuth = async (): Promise<AuthenticationObject> => {\n const localAuthObj = {\n applicationKey: applicationKey,\n customerToken: localCustomerToken,\n bearer: bearerAuthenticationToken,\n };\n\n // When in an internal iframe, get authentication from the parent window.\n if (\n typeof window !== \"undefined\" &&\n (window.location.href.includes(\"/workflows/product/\") || window.location.href.includes(\"hub=true\"))\n ) {\n return { ...(await getHubAuthentication()), ...localAuthObj };\n } else {\n return localAuthObj;\n }\n};\n\nasync function followRedirectFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n const serverUrl = spiffCoreConfiguration.getServerUrl();\n const moonlightUrl = serverUrl.includes(\".aumelbdev.spiffcommerce.com\")\n ? \"https://moonlight.aumelbdev.spiffcommerce.com\"\n : serverUrl.includes(\".us.spiffcommerce.com\")\n ? \"https://moonlight.us.spiffcommerce.com\"\n : \"https://moonlight.au.spiffcommerce.com\";\n\n let result = await fetch(input, { ...init, redirect: \"manual\" });\n if (result.type === \"opaqueredirect\" || result.status === 307) {\n if (typeof input !== \"string\" && \"url\" in input) {\n result = await fetch({ ...input, url: `${moonlightUrl}/graphql` }, init);\n } else {\n result = await fetch(`${moonlightUrl}/graphql`, init);\n }\n }\n return result;\n}\n\nclass GraphQlManager {\n private shadowGraphqlClient: ApolloClient<any>;\n private spiffClient?: SpiffCommerceClient;\n\n constructor() {\n this.shadowGraphqlClient = this.constructShadowGraphqlClient();\n spiffCoreConfiguration.addServerUrlCallback(() => {\n this.shadowGraphqlClient = this.constructShadowGraphqlClient();\n });\n }\n\n setSpiffCommerceClient(client: SpiffCommerceClient) {\n this.spiffClient = client;\n this.shadowGraphqlClient = this.constructShadowGraphqlClient();\n }\n\n getShadowGraphqlClient() {\n return this.shadowGraphqlClient;\n }\n\n private constructShadowGraphqlClient() {\n const httpLink = createHttpLink({\n uri: `${spiffCoreConfiguration.getServerUrl()}/graphql`,\n fetch: followRedirectFetch,\n });\n const authLink = setContext(async (_request, operationContext) => {\n const { headers } = operationContext;\n const newHeaders = headers || {};\n const auth = await getServerAuth();\n\n // Request context values take precedence over stored values.\n // These are passed on the query and mutate functions.\n let bearer = operationContext.bearer ?? auth.bearer;\n let useBeta = false;\n if (this.spiffClient) {\n try {\n bearer = await this.spiffClient.loggedInBearerToken();\n } catch (_) {\n // No user logged-in through core.\n }\n try {\n // Avoids making a separate graphql request by calling the internal function\n if (!operationContext.skipIntegrationCheck) {\n useBeta = await this.spiffClient.getBetaEnabled();\n }\n } catch (_) {\n // No-op\n }\n }\n const partnerId = operationContext.partnerId ?? auth.partnerId;\n const activeIntegration = operationContext.activeIntegration ?? auth.activeIntegration;\n const transactionOwnerId = operationContext.transactionOwnerId;\n const customerToken = operationContext.customerToken ?? auth.customerToken;\n const applicationKey = operationContext.applicationKey ?? auth.applicationKey;\n const bundleOwnerId = operationContext.bundleOwnerId;\n\n /**\n * Sentry is an optional dependency. If it's available, we check if there's an\n * active trace & attach any sentry related headers to the request.\n */\n try {\n if (window && window[\"__SENTRY__\"]) {\n const hub = window[\"__SENTRY__\"].hub;\n if (hub) {\n const traceHeaders = hub.traceHeaders();\n Object.entries(traceHeaders).forEach(([key, value]) => {\n newHeaders[key] = value;\n });\n }\n }\n } catch (e) {\n // Sentry is not available\n }\n\n if (bearer) {\n newHeaders[\"Authorization\"] = `Bearer ${bearer}`;\n }\n if (partnerId) {\n newHeaders[\"partnerId\"] = partnerId;\n }\n if (activeIntegration) {\n newHeaders[\"activeIntegration\"] = activeIntegration;\n }\n if (transactionOwnerId) {\n newHeaders[\"transactionOwnerId\"] = transactionOwnerId;\n }\n if (customerToken) {\n newHeaders[\"customerToken\"] = customerToken;\n }\n if (applicationKey) {\n newHeaders[\"X-Application-Key\"] = applicationKey;\n }\n if (bundleOwnerId) {\n newHeaders[\"bundleOwnerId\"] = bundleOwnerId;\n }\n\n if (useBeta) {\n newHeaders[\"X-Spiff-Beta\"] = \"true\";\n }\n\n newHeaders[\"Allow-Moonlight-Redirect\"] = \"true\";\n\n return {\n headers: newHeaders,\n };\n });\n\n const errorLink = onError(({ operation, graphQLErrors, networkError }) => {\n const errors = graphQLErrors || [];\n const context = operation.getContext();\n // Ignore network errors for aborted requests\n if (networkError && !context?.fetchOptions?.signal?.aborted) {\n console.log(\"GraphQL Network error\");\n }\n errors.forEach(() => console.log(\"GraphQL Error: \" + operation.operationName));\n });\n\n const removeTypenameLink = removeTypenameFromVariables();\n\n return new ApolloClient({\n link: from([removeTypenameLink, errorLink, authLink, httpLink]),\n cache: new InMemoryCache(),\n name: \"Core\",\n });\n }\n}\n\nconst graphQlManager = new GraphQlManager();\nexport { graphQlManager };\n","import { domParserConstructor } from \"./util/crossplatform\";\n\ninterface CustomImage {\n height: number;\n naturalHeight: number;\n naturalWidth: number;\n src: string | ArrayBuffer;\n width: number;\n}\n\ninterface CustomContext {\n drawImage(image: CustomCanvas | CustomImage, dx: number, dy: number): void;\n drawImage(image: CustomCanvas | CustomImage, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(\n image: CustomCanvas | CustomImage,\n sx: number,\n sy: number,\n sw: number,\n sh: number,\n dx: number,\n dy: number,\n dw: number,\n dh: number,\n ): void;\n rotate(angle: number): void;\n scale(x: number, y: number): void;\n translate(x: number, y: number): void;\n}\n\ninterface CustomCanvas {\n height: number;\n getContext(type: string): CustomContext | null;\n toDataURL(): string;\n toDataURL(type?: string, quality?: number): string;\n width: number;\n}\n\nlet createCanvasInternal: ((width?: number, height?: number, type?: \"pdf\" | \"svg\") => CustomCanvas) | undefined;\nlet loadImageInternal: ((src: string | ArrayBuffer, allowCrossOrigin?: boolean) => Promise<CustomImage>) | undefined;\n\nconst createCanvas = (width?: number, height?: number, type?: \"pdf\" | \"svg\"): CustomCanvas => {\n if (createCanvasInternal !== undefined) {\n return createCanvasInternal(width, height, type);\n }\n try {\n const module = documentCanvasModule(true);\n setCanvasModule(module!);\n return module!.createCanvas(width, height, type);\n } catch (e) {\n throw new Error(\"Canvas module not set\");\n }\n};\nconst loadImage = (src: string | ArrayBuffer, allowCrossOrigin?: boolean): Promise<CustomImage> => {\n if (loadImageInternal !== undefined) {\n return loadImageInternal(src, allowCrossOrigin);\n }\n try {\n const module = documentCanvasModule(true);\n setCanvasModule(module!);\n return module!.loadImage(src, allowCrossOrigin);\n } catch (e) {\n throw new Error(\"Canvas module not set\");\n }\n};\n\ninterface CustomCanvasModule {\n createCanvas: typeof createCanvas;\n loadImage: typeof loadImage;\n}\n\nfunction setCanvasModule(module?: CustomCanvasModule) {\n createCanvasInternal = module?.createCanvas;\n loadImageInternal = module?.loadImage;\n}\n\nfunction documentCanvasModule(throwOnError: boolean): CustomCanvasModule | undefined {\n try {\n const ctx = document.createElement(\"canvas\").getContext(\"2d\");\n if (ctx) {\n return {\n createCanvas: (width?: number, height?: number, _type?: \"pdf\" | \"svg\") => {\n const canvas: HTMLCanvasElement = document.createElement(\"canvas\");\n if (width !== undefined && width !== null) {\n canvas.width = width;\n }\n if (height !== undefined && height !== null) {\n canvas.height = height;\n }\n return canvas as any;\n },\n loadImage: (src: string | ArrayBuffer, allowCrossOrigin?: boolean) => {\n return new Promise((resolve, reject) => {\n const image = document.createElement(\"img\");\n if (allowCrossOrigin !== false) {\n image.crossOrigin = \"Anonymous\";\n }\n image.onload = () => {\n resolve(image);\n };\n image.onerror = reject;\n image.src = src as string;\n });\n },\n };\n }\n } catch (e) {\n if (throwOnError) {\n throw e;\n }\n }\n return undefined;\n}\n\n// DOMParser constructor to be used by Pith.from().\nlet domParser: typeof DOMParser | undefined;\nfunction getDomParser(): typeof DOMParser {\n if (domParser === undefined) {\n domParser = domParserConstructor();\n }\n return domParser;\n}\nfunction setDomParser(parser: typeof DOMParser) {\n domParser = parser;\n}\n\nexport { createCanvas, documentCanvasModule, getDomParser, loadImage, setCanvasModule, setDomParser };\nexport type { CustomCanvas, CustomContext, CustomImage, CustomCanvasModule };\n","import { createCanvas, loadImage, CustomCanvas as Canvas, CustomImage as Image } from \"../customCanvas\";\nimport { arrayBufferToDataUrl, getMimeTypeOfArrayBuffer } from \"./crossplatform\";\n// Use cross-platform version of \"mini\" file. Also the default export doesn't work for some reason.\nimport { orientation as exifOrientation } from \"exifr/dist/mini.umd.cjs\";\n\n/**\n * Logic for scaling and orienting images.\n * Much of this file is taken literally or spiritually from\n * the Blueimp image load library.\n */\n\nlet supportsAutoOrientation: boolean | null = null;\n\n/*\nGet EXIF orientation value.\nExif orientation values to correctly display the letter F:\n\n 1 2\n ██████ ██████\n ██ ██\n ████ ████\n ██ ██\n ██ ██\n\n 3 4\n ██ ██\n ██ ██\n ████ ████\n ██ ██\n ██████ ██████\n\n 5 6\n██████████ ██\n██ ██ ██ ██\n██ ██████████\n\n 7 8\n ██ ██████████\n ██ ██ ██ ██\n██████████ ██\n\n*/\n\nexport const getExifOrientation = (arrayBuffer: ArrayBuffer): Promise<number> => {\n return new Promise((resolve) => {\n const mimeType = getMimeTypeOfArrayBuffer(arrayBuffer);\n if (mimeType !== \"image/jpeg\") {\n return resolve(1);\n }\n exifOrientation(arrayBuffer)\n .then((orientation: number | undefined) => {\n if (!orientation) return resolve(1); // No EXIF data.\n return resolve(orientation);\n })\n .catch(() => {\n return resolve(1);\n });\n });\n};\n\n// Whether the execution environment lacks automatic image orientation.\n// Checks whether the test URL with EXIF orientation gets oriented correctly.\nconst requiresCanvasOrientation = async (): Promise<boolean> => {\n if (supportsAutoOrientation !== null) {\n return !supportsAutoOrientation;\n }\n // black+white 3x2 JPEG, with the following meta information set:\n // - EXIF Orientation: 6 (Rotated 90° CCW)\n // Image data layout (B=black, F=white):\n // BFF\n // BBB\n const testImageUrl =\n \"data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA\" +\n \"AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA\" +\n \"QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE\" +\n \"BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAIAAwMBEQACEQEDEQH/x\" +\n \"ABRAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQADAQEAAAAAAAAAAAAGBQQDCAkCBwEBAAAAAAA\" +\n \"AAAAAAAAAAAAAABEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AG8T9NfSMEVMhQ\" +\n \"voP3fFiRZ+MTHDifa/95OFSZU5OzRzxkyejv8ciEfhSceSXGjS8eSdLnZc2HDm4M3BxcXw\" +\n \"H/9k=\";\n const img = await loadImage(testImageUrl);\n supportsAutoOrientation = img.width === 2 && img.height === 3;\n return !supportsAutoOrientation;\n};\n\n// Width and height to use for the canvas.\nexport const canvasDims = (img: Image): [number, number] => {\n const maxDimension = 8192;\n const aspectRatio = img.naturalWidth / img.naturalHeight;\n if (img.naturalHeight <= maxDimension && img.naturalWidth <= maxDimension) {\n return [img.naturalWidth, img.naturalHeight];\n }\n if (img.naturalHeight > img.naturalWidth) {\n return [aspectRatio * maxDimension, maxDimension];\n }\n return [maxDimension, maxDimension / aspectRatio];\n};\n\nconst getScaledAndOrientedCanvas = async (arrayBuffer: ArrayBuffer): Promise<Canvas> => {\n const dataUrl = await arrayBufferToDataUrl(arrayBuffer);\n const img = await loadImage(dataUrl);\n const [canvasWidth, canvasHeight] = canvasDims(img);\n const needToOrient = await requiresCanvasOrientation();\n if (!needToOrient) {\n const canvas = createCanvas(canvasWidth, canvasHeight);\n canvas.getContext(\"2d\")?.drawImage(img, 0, 0, canvasWidth, canvasHeight);\n return canvas;\n }\n const orientation = await getExifOrientation(arrayBuffer);\n const [orientedWidth, orientedHeight] = orientation > 4 ? [canvasHeight, canvasWidth] : [canvasWidth, canvasHeight];\n const canvas = createCanvas(orientedWidth, orientedHeight);\n const ctx = canvas.getContext(\"2d\")!;\n\n // Orient the canvas.\n switch (orientation) {\n case 2:\n ctx.translate(orientedWidth, 0);\n ctx.scale(-1, 1);\n break;\n case 3:\n ctx.translate(orientedWidth, orientedHeight);\n ctx.rotate(Math.PI);\n break;\n case 4:\n ctx.translate(0, orientedHeight);\n ctx.scale(1, -1);\n break;\n case 5:\n ctx.rotate(-0.5 * Math.PI);\n ctx.scale(-1, 1);\n break;\n case 6:\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-orientedWidth, 0);\n break;\n case 7:\n ctx.rotate(-0.5 * Math.PI);\n ctx.translate(-orientedWidth, orientedHeight);\n ctx.scale(1, -1);\n break;\n case 8:\n ctx.rotate(0.5 * Math.PI);\n ctx.translate(0, -orientedHeight);\n break;\n default:\n break;\n }\n\n ctx.drawImage(img, 0, 0, orientedWidth, orientedHeight);\n return canvas;\n};\n\nexport const getAttributesFromArrayBuffer = async (arrayBuffer: ArrayBuffer) => {\n const canvas = await getScaledAndOrientedCanvas(arrayBuffer);\n const mimeTypeData = getMimeTypeOfArrayBuffer(arrayBuffer);\n if (mimeTypeData === \"image/jpeg\") {\n return {\n dataUrl: canvas.toDataURL(\"image/jpeg\", 1.0),\n height: canvas.height,\n width: canvas.width,\n };\n }\n return {\n dataUrl: canvas.toDataURL(),\n height: canvas.height,\n width: canvas.width,\n };\n};\n","import Fuse, { FuseResult } from \"fuse.js\";\nimport { ColorDefinition, SpotColorDefinition } from \"../types\";\n\n// TODO: Should we move these lists onto a spreadsheet in the cloud and then process them when required?\nconst pmsValues = [\n \"Yellow C\",\n \"Yellow 012 C\",\n \"Orange 021 C\",\n \"Warm Red C\",\n \"Red 032 C\",\n \"Rubine Red C\",\n \"Rhodamine Red C\",\n \"Purple C\",\n \"Violet C\",\n \"Blue 072 C\",\n \"Reflex Blue C\",\n \"Process Blue C\",\n \"Green C\",\n \"Black C\",\n \"Yellow 0131 C\",\n \"Red 0331 C\",\n \"Magenta 0521 C\",\n \"Violet 0631 C\",\n \"Blue 0821 C\",\n \"Green 0921 C\",\n \"Black 0961 C\",\n \"801 C\",\n \"802 C\",\n \"803 C\",\n \"804 C\",\n \"805 C\",\n \"806 C\",\n \"807 C\",\n \"871 C\",\n \"872 C\",\n \"873 C\",\n \"874 C\",\n \"875 C\",\n \"876 C\",\n \"877 C\",\n \"Medium Yellow C\",\n \"Bright Orange C\",\n \"Bright Red C\",\n \"Strong Red C\",\n \"Pink C\",\n \"Medium Purple C\",\n \"Dark Blue C\",\n \"Medium Blue C\",\n \"Bright Green C\",\n \"Neutral Black C\",\n \"100 C\",\n \"101 C\",\n \"102 C\",\n \"103 C\",\n \"104 C\",\n \"105 C\",\n \"7401 C\",\n \"7402 C\",\n \"7403 C\",\n \"7404 C\",\n \"7405 C\",\n \"7406 C\",\n \"7407 C\",\n \"106 C\",\n \"107 C\",\n \"108 C\",\n \"109 C\",\n \"110 C\",\n \"111 C\",\n \"112 C\",\n \"113 C\",\n \"114 C\",\n \"115 C\",\n \"116 C\",\n \"117 C\",\n \"118 C\",\n \"119 C\",\n \"127 C\",\n \"128 C\",\n \"129 C\",\n \"130 C\",\n \"131 C\",\n \"132 C\",\n \"133 C\",\n \"1205 C\",\n \"1215 C\",\n \"1225 C\",\n \"1235 C\",\n \"1245 C\",\n \"1255 C\",\n \"1265 C\",\n \"120 C\",\n \"121 C\",\n \"122 C\",\n \"123 C\",\n \"124 C\",\n \"125 C\",\n \"126 C\",\n \"7548 C\",\n \"7549 C\",\n \"7550 C\",\n \"7551 C\",\n \"7552 C\",\n \"7553 C\",\n \"7554 C\",\n \"7555 C\",\n \"7556 C\",\n \"7557 C\",\n \"7558 C\",\n \"7559 C\",\n \"7560 C\",\n \"7561 C\",\n \"134 C\",\n \"135 C\",\n \"136 C\",\n \"137 C\",\n \"138 C\",\n \"139 C\",\n \"140 C\",\n \"1345 C\",\n \"1355 C\",\n \"1365 C\",\n \"1375 C\",\n \"1385 C\",\n \"1395 C\",\n \"1405 C\",\n \"141 C\",\n \"142 C\",\n \"143 C\",\n \"144 C\",\n \"145 C\",\n \"146 C\",\n \"147 C\",\n \"7408 C\",\n \"7409 C\",\n \"7410 C\",\n \"7411 C\",\n \"7412 C\",\n \"7413 C\",\n \"7414 C\",\n \"7562 C\",\n \"7563 C\",\n \"7564 C\",\n \"7565 C\",\n \"7566 C\",\n \"7567 C\",\n \"7568 C\",\n \"7569 C\",\n \"7570 C\",\n \"7571 C\",\n \"7572 C\",\n \"7573 C\",\n \"7574 C\",\n \"7575 C\",\n \"712 C\",\n \"713 C\",\n \"714 C\",\n \"715 C\",\n \"716 C\",\n \"717 C\",\n \"718 C\",\n \"148 C\",\n \"149 C\",\n \"150 C\",\n \"151 C\",\n \"152 C\",\n \"153 C\",\n \"154 C\",\n \"155 C\",\n \"156 C\",\n \"157 C\",\n \"158 C\",\n \"159 C\",\n \"160 C\",\n \"161 C\",\n \"1485 C\",\n \"1495 C\",\n \"1505 C\",\n \"1525 C\",\n \"1535 C\",\n \"1545 C\",\n \"1555 C\",\n \"1565 C\",\n \"1575 C\",\n \"1585 C\",\n \"1595 C\",\n \"1605 C\",\n \"1615 C\",\n \"162 C\",\n \"163 C\",\n \"164 C\",\n \"165 C\",\n \"166 C\",\n \"167 C\",\n \"168 C\",\n \"7576 C\",\n \"7577 C\",\n \"7578 C\",\n \"7579 C\",\n \"7580 C\",\n \"7581 C\",\n \"7582 C\",\n \"1625 C\",\n \"1635 C\",\n \"1645 C\",\n \"1655 C\",\n \"1665 C\",\n \"1675 C\",\n \"1685 C\",\n \"169 C\",\n \"170 C\",\n \"171 C\",\n \"172 C\",\n \"173 C\",\n \"174 C\",\n \"175 C\",\n \"7583 C\",\n \"7584 C\",\n \"7585 C\",\n \"7586 C\",\n \"7587 C\",\n \"7588 C\",\n \"7589 C\",\n \"7590 C\",\n \"7591 C\",\n \"7592 C\",\n \"7593 C\",\n \"7594 C\",\n \"7595 C\",\n \"7596 C\",\n \"7597 C\",\n \"7598 C\",\n \"7599 C\",\n \"7600 C\",\n \"7601 C\",\n \"7602 C\",\n \"7603 C\",\n \"7604 C\",\n \"7605 C\",\n \"7606 C\",\n \"7607 C\",\n \"7608 C\",\n \"7609 C\",\n \"7610 C\",\n \"7611 C\",\n \"7612 C\",\n \"7613 C\",\n \"7614 C\",\n \"7615 C\",\n \"7616 C\",\n \"7617 C\",\n \"7520 C\",\n \"7521 C\",\n \"7522 C\",\n \"7523 C\",\n \"7524 C\",\n \"7525 C\",\n \"7526 C\",\n \"489 C\",\n \"488 C\",\n \"487 C\",\n \"486 C\",\n \"485 C\",\n \"484 C\",\n \"483 C\",\n \"176 C\",\n \"177 C\",\n \"178 C\",\n \"179 C\",\n \"180 C\",\n \"181 C\",\n \"1765 C\",\n \"1775 C\",\n \"1785 C\",\n \"1788 C\",\n \"1795 C\",\n \"1805 C\",\n \"1815 C\",\n \"1767 C\",\n \"1777 C\",\n \"1787 C\",\n \"1797 C\",\n \"1807 C\",\n \"1817 C\",\n \"7618 C\",\n \"7619 C\",\n \"7620 C\",\n \"7621 C\",\n \"7622 C\",\n \"7623 C\",\n \"7624 C\",\n \"7625 C\",\n \"7626 C\",\n \"7627 C\",\n \"7628 C\",\n \"7629 C\",\n \"7630 C\",\n \"7631 C\",\n \"7415 C\",\n \"7416 C\",\n \"7417 C\",\n \"7418 C\",\n \"7419 C\",\n \"7420 C\",\n \"7421 C\",\n \"182 C\",\n \"183 C\",\n \"184 C\",\n \"185 C\",\n \"186 C\",\n \"187 C\",\n \"188 C\",\n \"196 C\",\n \"197 C\",\n \"198 C\",\n \"199 C\",\n \"200 C\",\n \"201 C\",\n \"202 C\",\n \"189 C\",\n \"190 C\",\n \"191 C\",\n \"192 C\",\n \"193 C\",\n \"194 C\",\n \"195 C\",\n \"1895 C\",\n \"1905 C\",\n \"1915 C\",\n \"1925 C\",\n \"1935 C\",\n \"1945 C\",\n \"1955 C\",\n \"705 C\",\n \"706 C\",\n \"707 C\",\n \"708 C\",\n \"709 C\",\n \"710 C\",\n \"711 C\",\n \"698 C\",\n \"699 C\",\n \"700 C\",\n \"701 C\",\n \"702 C\",\n \"703 C\",\n \"704 C\",\n \"203 C\",\n \"204 C\",\n \"205 C\",\n \"206 C\",\n \"207 C\",\n \"208 C\",\n \"209 C\",\n \"210 C\",\n \"211 C\",\n \"212 C\",\n \"213 C\",\n \"214 C\",\n \"215 C\",\n \"216 C\",\n \"7422 C\",\n \"7423 C\",\n \"7424 C\",\n \"7425 C\",\n \"7426 C\",\n \"7427 C\",\n \"7428 C\",\n \"7632 C\",\n \"7633 C\",\n \"7634 C\",\n \"7635 C\",\n \"7636 C\",\n \"7637 C\",\n \"7638 C\",\n \"217 C\",\n \"218 C\",\n \"219 C\",\n \"220 C\",\n \"221 C\",\n \"222 C\",\n \"7639 C\",\n \"7640 C\",\n \"7641 C\",\n \"7642 C\",\n \"7643 C\",\n \"7644 C\",\n \"7645 C\",\n \"223 C\",\n \"224 C\",\n \"225 C\",\n \"226 C\",\n \"227 C\",\n \"228 C\",\n \"229 C\",\n \"230 C\",\n \"231 C\",\n \"232 C\",\n \"233 C\",\n \"234 C\",\n \"235 C\",\n \"670 C\",\n \"671 C\",\n \"672 C\",\n \"673 C\",\n \"674 C\",\n \"675 C\",\n \"676 C\",\n \"677 C\",\n \"678 C\",\n \"679 C\",\n \"680 C\",\n \"681 C\",\n \"682 C\",\n \"683 C\",\n \"684 C\",\n \"685 C\",\n \"686 C\",\n \"687 C\",\n \"688 C\",\n \"689 C\",\n \"690 C\",\n \"510 C\",\n \"509 C\",\n \"508 C\",\n \"507 C\",\n \"506 C\",\n \"505 C\",\n \"504 C\",\n \"7429 C\",\n \"7430 C\",\n \"7431 C\",\n \"7432 C\",\n \"7433 C\",\n \"7434 C\",\n \"7435 C\",\n \"691 C\",\n \"692 C\",\n \"693 C\",\n \"694 C\",\n \"695 C\",\n \"696 C\",\n \"697 C\",\n \"496 C\",\n \"495 C\",\n \"494 C\",\n \"493 C\",\n \"492 C\",\n \"491 C\",\n \"490 C\",\n \"503 C\",\n \"502 C\",\n \"501 C\",\n \"500 C\",\n \"499 C\",\n \"498 C\",\n \"497 C\",\n \"5035 C\",\n \"5025 C\",\n \"5015 C\",\n \"5005 C\",\n \"4995 C\",\n \"4985 C\",\n \"4975 C\",\n \"236 C\",\n \"237 C\",\n \"238 C\",\n \"239 C\",\n \"240 C\",\n \"241 C\",\n \"242 C\",\n \"2365 C\",\n \"2375 C\",\n \"2385 C\",\n \"2395 C\",\n \"2405 C\",\n \"2415 C\",\n \"2425 C\",\n \"243 C\",\n \"244 C\",\n \"245 C\",\n \"246 C\",\n \"247 C\",\n \"248 C\",\n \"249 C\",\n \"7646 C\",\n \"7647 C\",\n \"7648 C\",\n \"7649 C\",\n \"7650 C\",\n \"7651 C\",\n \"7652 C\",\n \"250 C\",\n \"251 C\",\n \"252 C\",\n \"253 C\",\n \"254 C\",\n \"255 C\",\n \"517 C\",\n \"516 C\",\n \"515 C\",\n \"514 C\",\n \"513 C\",\n \"512 C\",\n \"511 C\",\n \"7436 C\",\n \"7437 C\",\n \"7438 C\",\n \"7439 C\",\n \"7440 C\",\n \"7441 C\",\n \"7442 C\",\n \"2562 C\",\n \"2572 C\",\n \"2582 C\",\n \"2592 C\",\n \"2602 C\",\n \"2612 C\",\n \"2622 C\",\n \"7653 C\",\n \"7654 C\",\n \"7655 C\",\n \"7656 C\",\n \"7657 C\",\n \"7658 C\",\n \"7659 C\",\n \"524 C\",\n \"523 C\",\n \"522 C\",\n \"521 C\",\n \"520 C\",\n \"519 C\",\n \"518 C\",\n \"5245 C\",\n \"5235 C\",\n \"5225 C\",\n \"5215 C\",\n \"5205 C\",\n \"5195 C\",\n \"5185 C\",\n \"5175 C\",\n \"5165 C\",\n \"5155 C\",\n \"5145 C\",\n \"5135 C\",\n \"5125 C\",\n \"5115 C\",\n \"531 C\",\n \"530 C\",\n \"529 C\",\n \"528 C\",\n \"527 C\",\n \"526 C\",\n \"525 C\",\n \"256 C\",\n \"257 C\",\n \"258 C\",\n \"259 C\",\n \"260 C\",\n \"261 C\",\n \"262 C\",\n \"2563 C\",\n \"2573 C\",\n \"2583 C\",\n \"2593 C\",\n \"2603 C\",\n \"2613 C\",\n \"2623 C\",\n \"7660 C\",\n \"7661 C\",\n \"7662 C\",\n \"7663 C\",\n \"7664 C\",\n \"7665 C\",\n \"7666 C\",\n \"2567 C\",\n \"2577 C\",\n \"2587 C\",\n \"2597 C\",\n \"2607 C\",\n \"2617 C\",\n \"2627 C\",\n \"263 C\",\n \"264 C\",\n \"265 C\",\n \"266 C\",\n \"267 C\",\n \"268 C\",\n \"269 C\",\n \"2635 C\",\n \"2645 C\",\n \"2655 C\",\n \"2665 C\",\n \"2685 C\",\n \"2695 C\",\n \"270 C\",\n \"271 C\",\n \"272 C\",\n \"273 C\",\n \"274 C\",\n \"275 C\",\n \"276 C\",\n \"2705 C\",\n \"2715 C\",\n \"2725 C\",\n \"2735 C\",\n \"2745 C\",\n \"2755 C\",\n \"2765 C\",\n \"7667 C\",\n \"7668 C\",\n \"7669 C\",\n \"7670 C\",\n \"7671 C\",\n \"7672 C\",\n \"7673 C\",\n \"7443 C\",\n \"7444 C\",\n \"7445 C\",\n \"7446 C\",\n \"7447 C\",\n \"7448 C\",\n \"7449 C\",\n \"7674 C\",\n \"7675 C\",\n \"7676 C\",\n \"7677 C\",\n \"7678 C\",\n \"7679 C\",\n \"7680 C\",\n \"663 C\",\n \"664 C\",\n \"665 C\",\n \"666 C\",\n \"667 C\",\n \"668 C\",\n \"669 C\",\n \"5315 C\",\n \"5305 C\",\n \"5295 C\",\n \"5285 C\",\n \"5275 C\",\n \"5265 C\",\n \"5255 C\",\n \"538 C\",\n \"537 C\",\n \"536 C\",\n \"535 C\",\n \"534 C\",\n \"533 C\",\n \"532 C\",\n \"7541 C\",\n \"7542 C\",\n \"7543 C\",\n \"7544 C\",\n \"7545 C\",\n \"7546 C\",\n \"7547 C\",\n \"552 C\",\n \"551 C\",\n \"550 C\",\n \"549 C\",\n \"548 C\",\n \"547 C\",\n \"546 C\",\n \"5455 C\",\n \"5445 C\",\n \"5435 C\",\n \"5425 C\",\n \"5415 C\",\n \"5405 C\",\n \"5395 C\",\n \"642 C\",\n \"643 C\",\n \"644 C\",\n \"645 C\",\n \"646 C\",\n \"647 C\",\n \"648 C\",\n \"649 C\",\n \"650 C\",\n \"651 C\",\n \"652 C\",\n \"653 C\",\n \"654 C\",\n \"655 C\",\n \"656 C\",\n \"657 C\",\n \"658 C\",\n \"659 C\",\n \"660 C\",\n \"661 C\",\n \"662 C\",\n \"7450 C\",\n \"7451 C\",\n \"7452 C\",\n \"7453 C\",\n \"7454 C\",\n \"7455 C\",\n \"7456 C\",\n \"2706 C\",\n \"2716 C\",\n \"2726 C\",\n \"2736 C\",\n \"2746 C\",\n \"2756 C\",\n \"2766 C\",\n \"2708 C\",\n \"2718 C\",\n \"2728 C\",\n \"2738 C\",\n \"2748 C\",\n \"2758 C\",\n \"2768 C\",\n \"2707 C\",\n \"2717 C\",\n \"2727 C\",\n \"2747 C\",\n \"2757 C\",\n \"2767 C\",\n \"277 C\",\n \"278 C\",\n \"279 C\",\n \"280 C\",\n \"281 C\",\n \"282 C\",\n \"283 C\",\n \"284 C\",\n \"285 C\",\n \"286 C\",\n \"287 C\",\n \"288 C\",\n \"289 C\",\n \"7681 C\",\n \"7682 C\",\n \"7683 C\",\n \"7684 C\",\n \"7685 C\",\n \"7686 C\",\n \"7687 C\",\n \"545 C\",\n \"544 C\",\n \"543 C\",\n \"542 C\",\n \"541 C\",\n \"540 C\",\n \"539 C\",\n \"290 C\",\n \"291 C\",\n \"292 C\",\n \"293 C\",\n \"294 C\",\n \"295 C\",\n \"296 C\",\n \"2905 C\",\n \"2915 C\",\n \"2925 C\",\n \"2935 C\",\n \"2945 C\",\n \"2955 C\",\n \"2965 C\",\n \"297 C\",\n \"298 C\",\n \"299 C\",\n \"300 C\",\n \"301 C\",\n \"302 C\",\n \"303 C\",\n \"7688 C\",\n \"7689 C\",\n \"7690 C\",\n \"7691 C\",\n \"7692 C\",\n \"7693 C\",\n \"7694 C\",\n \"2975 C\",\n \"2985 C\",\n \"2995 C\",\n \"3005 C\",\n \"3015 C\",\n \"3025 C\",\n \"3035 C\",\n \"7695 C\",\n \"7696 C\",\n \"7697 C\",\n \"7698 C\",\n \"7699 C\",\n \"7700 C\",\n \"7701 C\",\n \"7457 C\",\n \"7458 C\",\n \"7459 C\",\n \"7460 C\",\n \"7461 C\",\n \"7462 C\",\n \"7463 C\",\n \"304 C\",\n \"305 C\",\n \"306 C\",\n \"307 C\",\n \"308 C\",\n \"309 C\",\n \"635 C\",\n \"636 C\",\n \"637 C\",\n \"638 C\",\n \"639 C\",\n \"640 C\",\n \"641 C\",\n \"7702 C\",\n \"7703 C\",\n \"7704 C\",\n \"7705 C\",\n \"7706 C\",\n \"7707 C\",\n \"7708 C\",\n \"628 C\",\n \"629 C\",\n \"630 C\",\n \"631 C\",\n \"632 C\",\n \"633 C\",\n \"634 C\",\n \"310 C\",\n \"311 C\",\n \"312 C\",\n \"313 C\",\n \"314 C\",\n \"315 C\",\n \"316 C\",\n \"3105 C\",\n \"3115 C\",\n \"3125 C\",\n \"3135 C\",\n \"3145 C\",\n \"3155 C\",\n \"3165 C\",\n \"7709 C\",\n \"7710 C\",\n \"7711 C\",\n \"7712 C\",\n \"7713 C\",\n \"7714 C\",\n \"7715 C\",\n \"317 C\",\n \"318 C\",\n \"319 C\",\n \"320 C\",\n \"321 C\",\n \"322 C\",\n \"323 C\",\n \"7464 C\",\n \"7465 C\",\n \"7466 C\",\n \"7467 C\",\n \"7468 C\",\n \"7469 C\",\n \"7470 C\",\n \"7471 C\",\n \"7472 C\",\n \"7473 C\",\n \"7474 C\",\n \"7475 C\",\n \"7476 C\",\n \"7477 C\",\n \"5523 C\",\n \"5513 C\",\n \"5503 C\",\n \"5493 C\",\n \"5483 C\",\n \"5473 C\",\n \"5463 C\",\n \"7716 C\",\n \"7717 C\",\n \"7718 C\",\n \"7719 C\",\n \"7720 C\",\n \"7721 C\",\n \"7722 C\",\n \"324 C\",\n \"325 C\",\n \"326 C\",\n \"327 C\",\n \"328 C\",\n \"329 C\",\n \"330 C\",\n \"3242 C\",\n \"3252 C\",\n \"3262 C\",\n \"3272 C\",\n \"3282 C\",\n \"3292 C\",\n \"3302 C\",\n \"3245 C\",\n \"3255 C\",\n \"3265 C\",\n \"3275 C\",\n \"3285 C\",\n \"3295 C\",\n \"3305 C\",\n \"3248 C\",\n \"3258 C\",\n \"3268 C\",\n \"3278 C\",\n \"3288 C\",\n \"3298 C\",\n \"3308 C\",\n \"566 C\",\n \"565 C\",\n \"564 C\",\n \"563 C\",\n \"562 C\",\n \"561 C\",\n \"560 C\",\n \"573 C\",\n \"572 C\",\n \"571 C\",\n \"570 C\",\n \"569 C\",\n \"568 C\",\n \"567 C\",\n \"559 C\",\n \"558 C\",\n \"557 C\",\n \"556 C\",\n \"555 C\",\n \"554 C\",\n \"553 C\",\n \"5595 C\",\n \"5585 C\",\n \"5575 C\",\n \"5565 C\",\n \"5555 C\",\n \"5545 C\",\n \"5535 C\",\n \"5665 C\",\n \"5655 C\",\n \"5645 C\",\n \"5635 C\",\n \"5625 C\",\n \"5615 C\",\n \"5605 C\",\n \"5527 C\",\n \"5517 C\",\n \"5507 C\",\n \"5497 C\",\n \"5487 C\",\n \"5477 C\",\n \"5467 C\",\n \"621 C\",\n \"622 C\",\n \"623 C\",\n \"624 C\",\n \"625 C\",\n \"626 C\",\n \"627 C\",\n \"331 C\",\n \"332 C\",\n \"333 C\",\n \"334 C\",\n \"335 C\",\n \"336 C\",\n \"337 C\",\n \"338 C\",\n \"339 C\",\n \"340 C\",\n \"341 C\",\n \"342 C\",\n \"343 C\",\n \"7723 C\",\n \"7724 C\",\n \"7725 C\",\n \"7726 C\",\n \"7727 C\",\n \"7728 C\",\n \"7729 C\",\n \"3375 C\",\n \"3385 C\",\n \"3395 C\",\n \"3405 C\",\n \"3415 C\",\n \"3425 C\",\n \"3435 C\",\n \"344 C\",\n \"345 C\",\n \"346 C\",\n \"347 C\",\n \"348 C\",\n \"349 C\",\n \"350 C\",\n \"351 C\",\n \"352 C\",\n \"353 C\",\n \"354 C\",\n \"355 C\",\n \"356 C\",\n \"357 C\",\n \"7478 C\",\n \"7479 C\",\n \"7480 C\",\n \"7481 C\",\n \"7482 C\",\n \"7483 C\",\n \"7484 C\",\n \"7730 C\",\n \"7731 C\",\n \"7732 C\",\n \"7733 C\",\n \"7734 C\",\n \"7735 C\",\n \"7736 C\",\n \"7737 C\",\n \"7738 C\",\n \"7739 C\",\n \"7740 C\",\n \"7741 C\",\n \"7742 C\",\n \"7743 C\",\n \"358 C\",\n \"359 C\",\n \"360 C\",\n \"361 C\",\n \"362 C\",\n \"363 C\",\n \"364 C\",\n \"7485 C\",\n \"7486 C\",\n \"7487 C\",\n \"7488 C\",\n \"7489 C\",\n \"7490 C\",\n \"7491 C\",\n \"365 C\",\n \"366 C\",\n \"367 C\",\n \"368 C\",\n \"369 C\",\n \"370 C\",\n \"371 C\",\n \"372 C\",\n \"373 C\",\n \"374 C\",\n \"375 C\",\n \"376 C\",\n \"377 C\",\n \"378 C\",\n \"580 C\",\n \"579 C\",\n \"578 C\",\n \"577 C\",\n \"576 C\",\n \"575 C\",\n \"574 C\",\n \"5807 C\",\n \"5797 C\",\n \"5787 C\",\n \"5777 C\",\n \"5767 C\",\n \"5757 C\",\n \"5747 C\",\n \"5875 C\",\n \"5865 C\",\n \"5855 C\",\n \"5845 C\",\n \"5835 C\",\n \"5825 C\",\n \"5815 C\",\n \"5803 C\",\n \"5793 C\",\n \"5783 C\",\n \"5773 C\",\n \"5763 C\",\n \"5753 C\",\n \"5743 C\",\n \"7492 C\",\n \"7493 C\",\n \"7494 C\",\n \"7495 C\",\n \"7496 C\",\n \"7497 C\",\n \"7498 C\",\n \"7744 C\",\n \"7745 C\",\n \"7746 C\",\n \"7747 C\",\n \"7748 C\",\n \"7749 C\",\n \"7750 C\",\n \"379 C\",\n \"380 C\",\n \"381 C\",\n \"382 C\",\n \"383 C\",\n \"384 C\",\n \"385 C\",\n \"386 C\",\n \"387 C\",\n \"388 C\",\n \"389 C\",\n \"390 C\",\n \"391 C\",\n \"392 C\",\n \"587 C\",\n \"586 C\",\n \"585 C\",\n \"584 C\",\n \"583 C\",\n \"582 C\",\n \"581 C\",\n \"393 C\",\n \"394 C\",\n \"395 C\",\n \"396 C\",\n \"397 C\",\n \"398 C\",\n \"399 C\",\n \"3935 C\",\n \"3945 C\",\n \"3955 C\",\n \"3965 C\",\n \"3975 C\",\n \"3985 C\",\n \"3995 C\",\n \"600 C\",\n \"601 C\",\n \"602 C\",\n \"603 C\",\n \"604 C\",\n \"605 C\",\n \"606 C\",\n \"607 C\",\n \"608 C\",\n \"609 C\",\n \"610 C\",\n \"611 C\",\n \"612 C\",\n \"613 C\",\n \"461 C\",\n \"460 C\",\n \"459 C\",\n \"458 C\",\n \"457 C\",\n \"456 C\",\n \"455 C\",\n \"614 C\",\n \"615 C\",\n \"616 C\",\n \"617 C\",\n \"618 C\",\n \"619 C\",\n \"620 C\",\n \"7751 C\",\n \"7752 C\",\n \"7753 C\",\n \"7754 C\",\n \"7755 C\",\n \"7756 C\",\n \"7757 C\",\n \"7758 C\",\n \"7759 C\",\n \"7760 C\",\n \"7761 C\",\n \"7762 C\",\n \"7763 C\",\n \"7764 C\",\n \"7765 C\",\n \"7766 C\",\n \"7767 C\",\n \"7768 C\",\n \"7769 C\",\n \"7770 C\",\n \"7771 C\",\n \"4545 C\",\n \"4535 C\",\n \"4525 C\",\n \"4515 C\",\n \"4505 C\",\n \"4495 C\",\n \"4485 C\",\n \"454 C\",\n \"453 C\",\n \"452 C\",\n \"451 C\",\n \"450 C\",\n \"449 C\",\n \"448 C\",\n \"7499 C\",\n \"7500 C\",\n \"7501 C\",\n \"7502 C\",\n \"7503 C\",\n \"7504 C\",\n \"7505 C\",\n \"468 C\",\n \"467 C\",\n \"466 C\",\n \"465 C\",\n \"464 C\",\n \"463 C\",\n \"462 C\",\n \"7506 C\",\n \"7507 C\",\n \"7508 C\",\n \"7509 C\",\n \"7510 C\",\n \"7511 C\",\n \"7512 C\",\n \"719 C\",\n \"720 C\",\n \"721 C\",\n \"722 C\",\n \"723 C\",\n \"724 C\",\n \"725 C\",\n \"475 C\",\n \"474 C\",\n \"473 C\",\n \"472 C\",\n \"471 C\",\n \"470 C\",\n \"469 C\",\n \"726 C\",\n \"727 C\",\n \"728 C\",\n \"729 C\",\n \"730 C\",\n \"731 C\",\n \"732 C\",\n \"4685 C\",\n \"4675 C\",\n \"4665 C\",\n \"4655 C\",\n \"4645 C\",\n \"4635 C\",\n \"4625 C\",\n \"7513 C\",\n \"7514 C\",\n \"7515 C\",\n \"7516 C\",\n \"7517 C\",\n \"7518 C\",\n \"7519 C\",\n \"4755 C\",\n \"4745 C\",\n \"4735 C\",\n \"4725 C\",\n \"4715 C\",\n \"4705 C\",\n \"4695 C\",\n \"482 C\",\n \"481 C\",\n \"480 C\",\n \"479 C\",\n \"478 C\",\n \"477 C\",\n \"476 C\",\n \"7527 C\",\n \"7528 C\",\n \"7529 C\",\n \"7530 C\",\n \"7531 C\",\n \"7532 C\",\n \"7533 C\",\n \"7534 C\",\n \"7535 C\",\n \"7536 C\",\n \"7537 C\",\n \"7538 C\",\n \"7539 C\",\n \"7540 C\",\n \"427 C\",\n \"428 C\",\n \"429 C\",\n \"430 C\",\n \"431 C\",\n \"432 C\",\n \"433 C\",\n \"420 C\",\n \"421 C\",\n \"422 C\",\n \"423 C\",\n \"424 C\",\n \"425 C\",\n \"426 C\",\n \"441 C\",\n \"442 C\",\n \"443 C\",\n \"444 C\",\n \"445 C\",\n \"446 C\",\n \"447 C\",\n \"413 C\",\n \"414 C\",\n \"415 C\",\n \"416 C\",\n \"417 C\",\n \"418 C\",\n \"419 C\",\n \"400 C\",\n \"401 C\",\n \"402 C\",\n \"403 C\",\n \"404 C\",\n \"405 C\",\n \"406 C\",\n \"407 C\",\n \"408 C\",\n \"409 C\",\n \"410 C\",\n \"411 C\",\n \"412 C\",\n \"434 C\",\n \"435 C\",\n \"436 C\",\n \"437 C\",\n \"438 C\",\n \"439 C\",\n \"440 C\",\n \"Warm Gray 1 C\",\n \"Warm Gray 2 C\",\n \"Warm Gray 3 C\",\n \"Warm Gray 4 C\",\n \"Warm Gray 5 C\",\n \"Warm Gray 6 C\",\n \"Warm Gray 7 C\",\n \"Warm Gray 8 C\",\n \"Warm Gray 9 C\",\n \"Warm Gray 10 C\",\n \"Warm Gray 11 C\",\n \"Cool Gray 1 C\",\n \"Cool Gray 2 C\",\n \"Cool Gray 3 C\",\n \"Cool Gray 4 C\",\n \"Cool Gray 5 C\",\n \"Cool Gray 6 C\",\n \"Cool Gray 7 C\",\n \"Cool Gray 8 C\",\n \"Cool Gray 9 C\",\n \"Cool Gray 10 C\",\n \"Cool Gray 11 C\",\n \"Black 2 C\",\n \"Black 3 C\",\n \"Black 4 C\",\n \"Black 5 C\",\n \"Black 6 C\",\n \"Black 7 C\",\n];\n\nconst hexValues = [\n \"FEDD00\",\n \"FFD700\",\n \"FE5000\",\n \"F9423A\",\n \"EF3340\",\n \"CE0058\",\n \"E10098\",\n \"BB29BB\",\n \"440099\",\n \"10069F\",\n \"001489\",\n \"0085CA\",\n \"00AB84\",\n \"2D2926\",\n \"F2F0A1\",\n \"FCAEBB\",\n \"F1B2DC\",\n \"BF9BDE\",\n \"74D1EA\",\n \"9DE7D7\",\n \"9E978E\",\n \"009ACE\",\n \"44D62C\",\n \"FFE900\",\n \"FFAA4D\",\n \"FF7276\",\n \"FF3EB5\",\n \"EA27C2\",\n \"84754E\",\n \"85714D\",\n \"866D4B\",\n \"8B6F4E\",\n \"87674F\",\n \"8B634B\",\n \"8A8D8F\",\n \"FFD900\",\n \"FF5E00\",\n \"F93822\",\n \"CE0056\",\n \"D62598\",\n \"4E008E\",\n \"00239C\",\n \"0084CA\",\n \"00B08B\",\n \"222223\",\n \"F6EB61\",\n \"F7EA48\",\n \"FCE300\",\n \"C5A900\",\n \"AF9800\",\n \"897A27\",\n \"F5E1A4\",\n \"ECD898\",\n \"EED484\",\n \"F4DA40\",\n \"F2CD00\",\n \"F1C400\",\n \"CBA052\",\n \"F9E547\",\n \"FBE122\",\n \"FEDB00\",\n \"FFD100\",\n \"DAAA00\",\n \"AA8A00\",\n \"9C8412\",\n \"FAE053\",\n \"FBDD40\",\n \"FDDA24\",\n \"FFCD00\",\n \"C99700\",\n \"AC8400\",\n \"897322\",\n \"F3DD6D\",\n \"F3D54E\",\n \"F3D03E\",\n \"F2A900\",\n \"CC8A00\",\n \"A07400\",\n \"6C571B\",\n \"F8E08E\",\n \"FBD872\",\n \"FFC845\",\n \"FFB81C\",\n \"C69214\",\n \"AD841F\",\n \"886B25\",\n \"FBDB65\",\n \"FDD757\",\n \"FED141\",\n \"FFC72C\",\n \"EAAA00\",\n \"B58500\",\n \"9A7611\",\n \"FFC600\",\n \"FFB500\",\n \"D19000\",\n \"B47E00\",\n \"73531D\",\n \"5A4522\",\n \"4B3D2A\",\n \"D29F13\",\n \"B78B20\",\n \"9F7D23\",\n \"967126\",\n \"8F6A2A\",\n \"7D622E\",\n \"6C5D34\",\n \"FDD26E\",\n \"FFC658\",\n \"FFBF3F\",\n \"FFA300\",\n \"DE7C00\",\n \"AF6D04\",\n \"74531C\",\n \"FDD086\",\n \"FFC56E\",\n \"FFB549\",\n \"FF9E1B\",\n \"D57800\",\n \"996017\",\n \"6E4C1E\",\n \"F2C75C\",\n \"F1BE48\",\n \"F1B434\",\n \"ED8B00\",\n \"CF7F00\",\n \"A76D11\",\n \"715C2A\",\n \"F6BE00\",\n \"F0B323\",\n \"FEAD77\",\n \"E6A65D\",\n \"D38235\",\n \"DC8633\",\n \"C16C18\",\n \"BD9B60\",\n \"D69A2D\",\n \"DB8A06\",\n \"CD7925\",\n \"AD6433\",\n \"89532F\",\n \"775135\",\n \"D78825\",\n \"D3832B\",\n \"C67D30\",\n \"B67233\",\n \"A7662B\",\n \"9E6A38\",\n \"835D32\",\n \"FCC89B\",\n \"FDBE87\",\n \"FDAA63\",\n \"F68D2E\",\n \"EA7600\",\n \"D45D00\",\n \"BE4D00\",\n \"FECB8B\",\n \"FFC27B\",\n \"FFB25B\",\n \"FF8200\",\n \"E57200\",\n \"BE6A14\",\n \"9B5A1A\",\n \"EFD19F\",\n \"EFBE7D\",\n \"ECA154\",\n \"E87722\",\n \"CB6015\",\n \"A1561C\",\n \"603D20\",\n \"FFAE62\",\n \"FF8F1C\",\n \"FF6900\",\n \"B94700\",\n \"94450B\",\n \"653819\",\n \"FFB990\",\n \"FFA06A\",\n \"FF7F32\",\n \"FF6A13\",\n \"D86018\",\n \"A65523\",\n \"8B4720\",\n \"FFBE9F\",\n \"FF9D6E\",\n \"FF7F41\",\n \"FF671F\",\n \"E35205\",\n \"BE531C\",\n \"73381D\",\n \"DB864E\",\n \"E07E3C\",\n \"DC6B2F\",\n \"DC582A\",\n \"C05131\",\n \"864A33\",\n \"674736\",\n \"FFA38B\",\n \"FF8D6D\",\n \"FF6A39\",\n \"FC4C02\",\n \"DC4405\",\n \"A9431E\",\n \"833921\",\n \"FFB3AB\",\n \"FF8674\",\n \"FF5C39\",\n \"FA4616\",\n \"CF4520\",\n \"963821\",\n \"6B3529\",\n \"C4622D\",\n \"BA5826\",\n \"AF5C37\",\n \"9E5330\",\n \"924C2E\",\n \"7B4D35\",\n \"5C4738\",\n \"D4B59E\",\n \"C07D59\",\n \"B15533\",\n \"9D432C\",\n \"7C3A2D\",\n \"6B3D2E\",\n \"5C3D31\",\n \"D14124\",\n \"BD472A\",\n \"B33D26\",\n \"8D3F2B\",\n \"83412C\",\n \"7B4931\",\n \"674230\",\n \"E4D5D3\",\n \"E1BBB4\",\n \"D6938A\",\n \"C26E60\",\n \"A4493D\",\n \"823B34\",\n \"683431\",\n \"DDBCB0\",\n \"CA9A8E\",\n \"BC8A7E\",\n \"A37F74\",\n \"866761\",\n \"6B4C4C\",\n \"583D3E\",\n \"EABEB0\",\n \"C09C83\",\n \"B46A55\",\n \"AB5C57\",\n \"A45248\",\n \"9A6A4F\",\n \"8A391B\",\n \"ECC3B2\",\n \"ECBAA8\",\n \"EAA794\",\n \"E8927C\",\n \"DA291C\",\n \"9A3324\",\n \"653024\",\n \"FFB1BB\",\n \"FF808B\",\n \"FF585D\",\n \"E03C31\",\n \"BE3A34\",\n \"81312F\",\n \"FFA3B5\",\n \"FF8DA1\",\n \"F8485E\",\n \"EE2737\",\n \"D22630\",\n \"AF272F\",\n \"7C2529\",\n \"FCAFC0\",\n \"FB637E\",\n \"F4364C\",\n \"CB333B\",\n \"A4343A\",\n \"643335\",\n \"C66E4E\",\n \"C04C36\",\n \"B7312C\",\n \"AB2328\",\n \"93272C\",\n \"8A2A2B\",\n \"802F2D\",\n \"E1523D\",\n \"C63527\",\n \"A72B2A\",\n \"9E2A2B\",\n \"6D3332\",\n \"633231\",\n \"572D2D\",\n \"E6BAA8\",\n \"E56A54\",\n \"E04E39\",\n \"CD545B\",\n \"B04A5A\",\n \"9B2242\",\n \"651D32\",\n \"FABBCB\",\n \"FC9BB3\",\n \"F65275\",\n \"E4002B\",\n \"C8102E\",\n \"A6192E\",\n \"76232F\",\n \"ECC7CD\",\n \"E89CAE\",\n \"DF4661\",\n \"D50032\",\n \"BA0C2F\",\n \"9D2235\",\n \"862633\",\n \"F8A3BC\",\n \"F67599\",\n \"EF426F\",\n \"E40046\",\n \"BF0D3E\",\n \"9B2743\",\n \"782F40\",\n \"F5B6CD\",\n \"F59BBB\",\n \"EF4A81\",\n \"E0004D\",\n \"C5003E\",\n \"A6093D\",\n \"8A1538\",\n \"F5DADF\",\n \"F7CED7\",\n \"F9B5C4\",\n \"F890A5\",\n \"EF6079\",\n \"E03E52\",\n \"CB2C30\",\n \"F2D4D7\",\n \"F4C3CC\",\n \"F2ACB9\",\n \"E68699\",\n \"D25B73\",\n \"B83A4B\",\n \"9E2A2F\",\n \"ECB3CB\",\n \"E782A9\",\n \"E0457B\",\n \"CE0037\",\n \"A50034\",\n \"861F41\",\n \"6F263D\",\n \"F99FC9\",\n \"F57EB6\",\n \"F04E98\",\n \"E31C79\",\n \"CE0F69\",\n \"AC145A\",\n \"7D2248\",\n \"F4CDD4\",\n \"E06287\",\n \"E24585\",\n \"B52555\",\n \"A4123F\",\n \"971B2F\",\n \"6A2C3E\",\n \"D6C9CA\",\n \"C4A4A7\",\n \"C16784\",\n \"C63663\",\n \"BC204B\",\n \"912F46\",\n \"7E2D40\",\n \"EABEDB\",\n \"E56DB1\",\n \"DA1884\",\n \"A50050\",\n \"910048\",\n \"6C1D45\",\n \"936D73\",\n \"934054\",\n \"8E2C48\",\n \"732E4A\",\n \"672E45\",\n \"582D40\",\n \"502B3A\",\n \"EF95CF\",\n \"EB6FBD\",\n \"DF1995\",\n \"D0006F\",\n \"AA0061\",\n \"890C58\",\n \"672146\",\n \"F4A6D7\",\n \"F277C6\",\n \"E93CAC\",\n \"C6007E\",\n \"A20067\",\n \"840B55\",\n \"EAD3E2\",\n \"E6BCD8\",\n \"DFA0C9\",\n \"D986BA\",\n \"C6579A\",\n \"AE2573\",\n \"960051\",\n \"E5CEDB\",\n \"E3C8D8\",\n \"DEBED2\",\n \"C996B6\",\n \"B06C96\",\n \"994878\",\n \"7C2855\",\n \"E4C6D4\",\n \"DCB6C9\",\n \"D0A1BA\",\n \"BE84A3\",\n \"A76389\",\n \"893B67\",\n \"612141\",\n \"EBBECB\",\n \"E8B3C3\",\n \"E4A9BB\",\n \"D592AA\",\n \"84344E\",\n \"6F2C3F\",\n \"572932\",\n \"E2BCCB\",\n \"DCA9BF\",\n \"C9809E\",\n \"B55C80\",\n \"A73A64\",\n \"9B3259\",\n \"872651\",\n \"E9CDD0\",\n \"E4BEC3\",\n \"D7A3AB\",\n \"C48490\",\n \"B46B7A\",\n \"984856\",\n \"893C47\",\n \"F2C6CF\",\n \"F1BDC8\",\n \"E9A2B2\",\n \"DC8699\",\n \"8F3237\",\n \"7F3035\",\n \"5D2A2C\",\n \"E9C4C7\",\n \"E5BAC1\",\n \"DAA5AD\",\n \"C6858F\",\n \"7A3E3A\",\n \"6A3735\",\n \"512F2E\",\n \"DFC2C3\",\n \"DBB7BB\",\n \"CCA1A6\",\n \"B07C83\",\n \"9C6169\",\n \"874B52\",\n \"3F2021\",\n \"F1A7DC\",\n \"EC86D0\",\n \"E45DBF\",\n \"DB3EB1\",\n \"C5299B\",\n \"AF1685\",\n \"80225F\",\n \"EFBAE1\",\n \"E277CD\",\n \"D539B5\",\n \"C800A1\",\n \"B0008E\",\n \"9E007E\",\n \"830065\",\n \"EAB8E4\",\n \"E59BDC\",\n \"DD7FD3\",\n \"C724B1\",\n \"BB16A3\",\n \"A51890\",\n \"80276C\",\n \"A56E87\",\n \"A83D72\",\n \"991E66\",\n \"8A1B61\",\n \"722257\",\n \"6A2A5B\",\n \"5E2751\",\n \"E7BAE4\",\n \"DD9CDF\",\n \"C964CF\",\n \"AD1AAC\",\n \"981D97\",\n \"72246C\",\n \"EBC6DF\",\n \"E6BEDD\",\n \"E2ACD7\",\n \"D48BC8\",\n \"93328E\",\n \"833177\",\n \"612C51\",\n \"EEDAEA\",\n \"CCAED0\",\n \"D59ED7\",\n \"B288B9\",\n \"A277A6\",\n \"9F5CC0\",\n \"963CBD\",\n \"D7A9E3\",\n \"C98BDB\",\n \"AC4FC6\",\n \"9B26B6\",\n \"87189D\",\n \"772583\",\n \"653165\",\n \"948794\",\n \"A2789C\",\n \"A15A95\",\n \"8E3A80\",\n \"6E2B62\",\n \"6A3460\",\n \"5D3754\",\n \"D5C2D8\",\n \"C9B1D0\",\n \"BA9CC5\",\n \"A57FB2\",\n \"642F6C\",\n \"59315F\",\n \"4B3048\",\n \"DBCDD3\",\n \"D0BEC7\",\n \"C6B0BC\",\n \"AF95A6\",\n \"86647A\",\n \"66435A\",\n \"4A3041\",\n \"D8C8D1\",\n \"D3C0CD\",\n \"BFA5B8\",\n \"9B7793\",\n \"7E5475\",\n \"693C5E\",\n \"512A44\",\n \"DFC8E7\",\n \"D7B9E4\",\n \"CAA2DD\",\n \"B580D1\",\n \"8031A7\",\n \"702F8A\",\n \"572C5F\",\n \"D6BFDD\",\n \"C6A1CF\",\n \"8C4799\",\n \"6D2077\",\n \"642667\",\n \"5D285F\",\n \"51284F\",\n \"CBA3D8\",\n \"B884CB\",\n \"A05EB5\",\n \"84329B\",\n \"702082\",\n \"671E75\",\n \"5F2167\",\n \"9991A4\",\n \"8D6E97\",\n \"7A4183\",\n \"6B3077\",\n \"653279\",\n \"5E366E\",\n \"5C4E63\",\n \"C1A0DA\",\n \"A77BCA\",\n \"8246AF\",\n \"5C068C\",\n \"500778\",\n \"470A68\",\n \"3C1053\",\n \"D7C6E6\",\n \"C1A7E2\",\n \"9063CD\",\n \"753BBD\",\n \"5F259F\",\n \"582C83\",\n \"512D6D\",\n \"C5B4E3\",\n \"AD96DC\",\n \"9678D3\",\n \"7D55C7\",\n \"330072\",\n \"2E1A47\",\n \"B4B5DF\",\n \"9595D2\",\n \"7474C1\",\n \"24135F\",\n \"211551\",\n \"201747\",\n \"221C35\",\n \"A7A4E0\",\n \"8B84D7\",\n \"685BC7\",\n \"2E008B\",\n \"280071\",\n \"250E62\",\n \"201547\",\n \"6E7CA0\",\n \"686E9F\",\n \"615E9B\",\n \"565294\",\n \"514689\",\n \"4C4184\",\n \"535486\",\n \"DDDAE8\",\n \"B6B8DC\",\n \"A7A2C3\",\n \"8986CA\",\n \"5D4777\",\n \"4B384C\",\n \"41273B\",\n \"878CB4\",\n \"7C7FAB\",\n \"7566A0\",\n \"6F5091\",\n \"68478D\",\n \"563D82\",\n \"523178\",\n \"E5E1E6\",\n \"E0DBE3\",\n \"C6BCD0\",\n \"A192B2\",\n \"7C6992\",\n \"614B79\",\n \"3F2A56\",\n \"D8D7DF\",\n \"C6C4D2\",\n \"B3B0C4\",\n \"8D89A5\",\n \"595478\",\n \"403A60\",\n \"1E1A34\",\n \"C5CFDA\",\n \"BBC7D6\",\n \"A2B2C8\",\n \"8E9FBC\",\n \"1B365D\",\n \"1F2A44\",\n \"1C1F2A\",\n \"D9E1E2\",\n \"A4BCC2\",\n \"98A4AE\",\n \"768692\",\n \"425563\",\n \"253746\",\n \"131E29\",\n \"B9D3DC\",\n \"A3C7D2\",\n \"8DB9CA\",\n \"6BA4B8\",\n \"003D4C\",\n \"00313C\",\n \"072B31\",\n \"BFCED6\",\n \"B7C9D3\",\n \"A6BBC8\",\n \"7A99AC\",\n \"5B7F95\",\n \"4F758B\",\n \"081F2C\",\n \"D1DDE6\",\n \"C6D6E3\",\n \"9BB8D3\",\n \"7DA1C4\",\n \"5E8AB4\",\n \"236192\",\n \"002E5D\",\n \"DBE2E9\",\n \"CED9E5\",\n \"A7BCD6\",\n \"7D9BC1\",\n \"326295\",\n \"003A70\",\n \"002554\",\n \"DDE5ED\",\n \"C8D8EB\",\n \"B1C9E8\",\n \"7BA4DB\",\n \"407EC9\",\n \"003594\",\n \"001A70\",\n \"BDC5DB\",\n \"89ABE3\",\n \"8094DD\",\n \"7BA6DE\",\n \"5F8FB4\",\n \"3A5DAE\",\n \"606EB2\",\n \"CBD3EB\",\n \"9FAEE5\",\n \"485CC7\",\n \"1E22AA\",\n \"171C8F\",\n \"151F6D\",\n \"141B4D\",\n \"B8CCEA\",\n \"5C88DA\",\n \"0047BB\",\n \"06038D\",\n \"001871\",\n \"001E62\",\n \"071D49\",\n \"C3D7EE\",\n \"A7C6ED\",\n \"307FE2\",\n \"001A72\",\n \"001E60\",\n \"13294B\",\n \"ABCAE9\",\n \"8BB8E8\",\n \"418FDE\",\n \"012169\",\n \"00205B\",\n \"041E42\",\n \"92C1E9\",\n \"6CACE4\",\n \"0072CE\",\n \"0033A0\",\n \"003087\",\n \"002D72\",\n \"0C2340\",\n \"94A9CB\",\n \"6787B7\",\n \"426DA9\",\n \"385E9D\",\n \"2C5697\",\n \"1D4F91\",\n \"1D428A\",\n \"C6DAE7\",\n \"BDD6E6\",\n \"A4C8E1\",\n \"7BAFD4\",\n \"003C71\",\n \"003057\",\n \"00263A\",\n \"B9D9EB\",\n \"9BCBEB\",\n \"69B3E7\",\n \"003DA5\",\n \"002F6C\",\n \"002855\",\n \"041C2C\",\n \"8DC8E8\",\n \"62B5E5\",\n \"009CDE\",\n \"0057B8\",\n \"004C97\",\n \"003865\",\n \"00263E\",\n \"71C5E8\",\n \"41B6E6\",\n \"00A3E0\",\n \"005EB8\",\n \"004B87\",\n \"003B5C\",\n \"002A3A\",\n \"4698CB\",\n \"298FC2\",\n \"0076A8\",\n \"006298\",\n \"005587\",\n \"004976\",\n \"01426A\",\n \"99D6EA\",\n \"5BC2E7\",\n \"00A9E0\",\n \"0077C8\",\n \"00629B\",\n \"004F71\",\n \"003E51\",\n \"7BA7BC\",\n \"6399AE\",\n \"4E87A0\",\n \"41748D\",\n \"34657F\",\n \"165C7D\",\n \"005776\",\n \"BBDDE6\",\n \"71B2C9\",\n \"4298B5\",\n \"0086BF\",\n \"007DBA\",\n \"00558C\",\n \"002B49\",\n \"9ADBE8\",\n \"59CBE8\",\n \"00B5E2\",\n \"006BA6\",\n \"00587C\",\n \"003B49\",\n \"A4DBE8\",\n \"8BD3E6\",\n \"4EC3E0\",\n \"00AFD7\",\n \"0095C8\",\n \"0082BA\",\n \"0067A0\",\n \"48A9C5\",\n \"009CBD\",\n \"0085AD\",\n \"007096\",\n \"006A8E\",\n \"00617F\",\n \"005670\",\n \"B8DDE1\",\n \"9BD3DD\",\n \"77C5D5\",\n \"3EB1C8\",\n \"0093B2\",\n \"007396\",\n \"005F83\",\n \"6AD1E3\",\n \"05C3DE\",\n \"00A9CE\",\n \"0092BC\",\n \"007FA3\",\n \"00677F\",\n \"004851\",\n \"68D2DF\",\n \"00C1D5\",\n \"00AEC7\",\n \"008EAA\",\n \"00778B\",\n \"006272\",\n \"004F59\",\n \"63B1BC\",\n \"00A7B5\",\n \"0097A9\",\n \"00859B\",\n \"007D8A\",\n \"007680\",\n \"006269\",\n \"B1E4E3\",\n \"88DBDF\",\n \"2DCCD3\",\n \"009CA6\",\n \"008C95\",\n \"007377\",\n \"005F61\",\n \"A0D1CA\",\n \"40C1AC\",\n \"00B0B9\",\n \"00A3AD\",\n \"007398\",\n \"005F86\",\n \"005A70\",\n \"7EDDD3\",\n \"5CB8B2\",\n \"279989\",\n \"007681\",\n \"487A7B\",\n \"0D5257\",\n \"244C5A\",\n \"B6CFD0\",\n \"ABC7CA\",\n \"94B7BB\",\n \"7FA9AE\",\n \"4F868E\",\n \"115E67\",\n \"07272D\",\n \"00968F\",\n \"00857D\",\n \"007672\",\n \"006D68\",\n \"00635B\",\n \"005E5D\",\n \"005151\",\n \"9CDBD9\",\n \"64CCC9\",\n \"00B2A9\",\n \"008675\",\n \"007367\",\n \"00685E\",\n \"00534C\",\n \"71DBD4\",\n \"2AD2C9\",\n \"00BFB3\",\n \"00A499\",\n \"008578\",\n \"00594F\",\n \"004C45\",\n \"7CE0D3\",\n \"2CD5C4\",\n \"00C7B1\",\n \"00B398\",\n \"009681\",\n \"007864\",\n \"004E42\",\n \"6DCDB8\",\n \"49C5B1\",\n \"00AB8E\",\n \"009B77\",\n \"008264\",\n \"006A52\",\n \"034638\",\n \"B9DCD2\",\n \"A1D6CA\",\n \"86C8BC\",\n \"6BBBAE\",\n \"006F62\",\n \"00594C\",\n \"1D3C34\",\n \"B5E3D8\",\n \"A5DFD3\",\n \"98DBCE\",\n \"6BCABA\",\n \"00816D\",\n \"006C5B\",\n \"173F35\",\n \"ADCAB8\",\n \"9ABEAA\",\n \"85B09A\",\n \"6FA287\",\n \"28724F\",\n \"205C40\",\n \"284734\",\n \"BFCEC2\",\n \"A7BDB1\",\n \"92ACA0\",\n \"7F9C90\",\n \"5C7F71\",\n \"43695B\",\n \"183028\",\n \"BAC5B9\",\n \"B0BDB0\",\n \"A3B2A4\",\n \"94A596\",\n \"708573\",\n \"5E7461\",\n \"22372B\",\n \"BCC9C5\",\n \"B1C0BC\",\n \"9DB0AC\",\n \"829995\",\n \"5D7975\",\n \"3E5D58\",\n \"18332F\",\n \"D1E0D7\",\n \"B7CDC2\",\n \"9AB9AD\",\n \"789F90\",\n \"507F70\",\n \"285C4D\",\n \"13322B\",\n \"A7E6D7\",\n \"8CE2D0\",\n \"3CDBC0\",\n \"009775\",\n \"007B5F\",\n \"00664F\",\n \"8FD6BD\",\n \"6ECEB2\",\n \"00B388\",\n \"00965E\",\n \"007A53\",\n \"006747\",\n \"115740\",\n \"50A684\",\n \"00966C\",\n \"008755\",\n \"007B4B\",\n \"006F44\",\n \"006845\",\n \"005844\",\n \"7AE1BF\",\n \"47D7AC\",\n \"00C389\",\n \"00AF66\",\n \"007749\",\n \"006341\",\n \"154734\",\n \"A0DAB3\",\n \"91D6AC\",\n \"71CC98\",\n \"009A44\",\n \"00843D\",\n \"046A38\",\n \"2C5234\",\n \"A2E4B8\",\n \"8FE2B0\",\n \"80E0A7\",\n \"00B140\",\n \"009639\",\n \"007A33\",\n \"215732\",\n \"9BE3BF\",\n \"26D07C\",\n \"00BF6F\",\n \"00B74F\",\n \"009F4D\",\n \"275D38\",\n \"00573F\",\n \"4B9560\",\n \"228848\",\n \"007A3E\",\n \"007041\",\n \"286140\",\n \"36573B\",\n \"395542\",\n \"6BA539\",\n \"48A23F\",\n \"319B42\",\n \"3A913F\",\n \"44883E\",\n \"4A773C\",\n \"44693D\",\n \"ADDC91\",\n \"A1D884\",\n \"6CC24A\",\n \"43B02A\",\n \"509E2F\",\n \"4C8C2B\",\n \"4A7729\",\n \"D0DEBB\",\n \"BCE194\",\n \"8EDD65\",\n \"78D64B\",\n \"74AA50\",\n \"719949\",\n \"79863C\",\n \"C2E189\",\n \"B7DD79\",\n \"A4D65E\",\n \"78BE20\",\n \"64A70B\",\n \"658D1B\",\n \"546223\",\n \"D4EB8E\",\n \"CDEA80\",\n \"C5E86C\",\n \"97D700\",\n \"84BD00\",\n \"7A9A01\",\n \"59621D\",\n \"C4D6A4\",\n \"BCD19B\",\n \"B7CE95\",\n \"A9C47F\",\n \"789D4A\",\n \"67823A\",\n \"4E5B31\",\n \"D0D1AB\",\n \"C6C89B\",\n \"BABD8B\",\n \"A2A569\",\n \"8A8D4A\",\n \"6D712E\",\n \"3D441E\",\n \"D2CE9E\",\n \"CBC793\",\n \"C0BB87\",\n \"AFA96E\",\n \"A09958\",\n \"89813D\",\n \"555025\",\n \"C3C6A8\",\n \"B3B995\",\n \"A3AA83\",\n \"899064\",\n \"737B4C\",\n \"5E6738\",\n \"3E4827\",\n \"BFCC80\",\n \"BBC592\",\n \"9CAF88\",\n \"8F993E\",\n \"76881D\",\n \"7A7256\",\n \"5B6236\",\n \"BABC16\",\n \"ABAD23\",\n \"999B30\",\n \"888D30\",\n \"7C8034\",\n \"727337\",\n \"656635\",\n \"E2E868\",\n \"DBE442\",\n \"CEDC00\",\n \"C4D600\",\n \"A8AD00\",\n \"949300\",\n \"787121\",\n \"E9EC6B\",\n \"E3E935\",\n \"E0E721\",\n \"D0DF00\",\n \"B5BD00\",\n \"9A9500\",\n \"827A04\",\n \"E3E48D\",\n \"E0E27C\",\n \"DBDE70\",\n \"D2D755\",\n \"B7BF10\",\n \"8E8C13\",\n \"625D20\",\n \"F0EC74\",\n \"EDE939\",\n \"ECE81A\",\n \"E1E000\",\n \"BFB800\",\n \"ADA400\",\n \"A09200\",\n \"F3EA5D\",\n \"F3E500\",\n \"EFDF00\",\n \"EEDC00\",\n \"BBA600\",\n \"9A8700\",\n \"685C20\",\n \"F1EB9C\",\n \"F0E991\",\n \"F0E87B\",\n \"EDE04B\",\n \"EADA24\",\n \"E1CD00\",\n \"CFB500\",\n \"EBE49A\",\n \"E9E186\",\n \"E6DE77\",\n \"E1D555\",\n \"D7C826\",\n \"C4B000\",\n \"B39B00\",\n \"E9DF97\",\n \"E4D77E\",\n \"DECD63\",\n \"D9C756\",\n \"B89D18\",\n \"A28E2A\",\n \"695B24\",\n \"DCD59A\",\n \"D6CF8D\",\n \"D0C883\",\n \"C0B561\",\n \"AC9F3C\",\n \"9F912A\",\n \"8A7B19\",\n \"CAB64B\",\n \"CFB023\",\n \"C1A01E\",\n \"A08629\",\n \"897630\",\n \"736635\",\n \"675E33\",\n \"D4C304\",\n \"C4B200\",\n \"91852C\",\n \"747136\",\n \"5D6439\",\n \"585C3B\",\n \"535435\",\n \"BBB323\",\n \"B4A91F\",\n \"AA9D2E\",\n \"8F7E35\",\n \"716135\",\n \"635939\",\n \"4E4934\",\n \"D5CB9F\",\n \"CFC493\",\n \"C5B783\",\n \"B3A369\",\n \"998542\",\n \"8C7732\",\n \"614F25\",\n \"CAC7A7\",\n \"BFBB98\",\n \"B0AA7E\",\n \"9B945F\",\n \"594A25\",\n \"524727\",\n \"4A412A\",\n \"F1E6B2\",\n \"DFD1A7\",\n \"D9C89E\",\n \"CEB888\",\n \"A89968\",\n \"94795D\",\n \"816040\",\n \"DDCBA4\",\n \"D3BC8D\",\n \"C6AA76\",\n \"B9975B\",\n \"8B5B29\",\n \"744F28\",\n \"5C462B\",\n \"EFDBB2\",\n \"FCD299\",\n \"E1B87F\",\n \"D6A461\",\n \"C6893F\",\n \"B77729\",\n \"A6631B\",\n \"EDC8A3\",\n \"E7B78A\",\n \"DDA46F\",\n \"C88242\",\n \"B36924\",\n \"934D11\",\n \"7D3F16\",\n \"F3CFB3\",\n \"F1C6A7\",\n \"F0BF9B\",\n \"E59E6D\",\n \"B86125\",\n \"A45A2A\",\n \"693F23\",\n \"E0C09F\",\n \"D9B48F\",\n \"CDA077\",\n \"B58150\",\n \"9E652E\",\n \"774212\",\n \"623412\",\n \"E0C6AD\",\n \"DCBFA6\",\n \"CDA788\",\n \"BF9474\",\n \"AD7C59\",\n \"946037\",\n \"4F2C1D\",\n \"E1B7A7\",\n \"D5A286\",\n \"C58B68\",\n \"99552B\",\n \"85431E\",\n \"6D4F47\",\n \"5E4B3C\",\n \"D7C4B7\",\n \"CDB5A7\",\n \"C0A392\",\n \"AE8A79\",\n \"956C58\",\n \"7C4D3A\",\n \"5B3427\",\n \"DBC8B6\",\n \"D3BBA8\",\n \"C6A992\",\n \"AA8066\",\n \"703F2A\",\n \"623B2A\",\n \"4E3629\",\n \"D6D2C4\",\n \"C5B9AC\",\n \"B7A99A\",\n \"A39382\",\n \"7A6855\",\n \"63513D\",\n \"473729\",\n \"D1CCBD\",\n \"B7B09C\",\n \"A69F88\",\n \"A7ACA2\",\n \"949A90\",\n \"8E9089\",\n \"4B4F54\",\n \"D0D3D4\",\n \"C1C6C8\",\n \"A2AAAD\",\n \"7C878E\",\n \"5B6770\",\n \"333F48\",\n \"1D252D\",\n \"C7C9C7\",\n \"B2B4B2\",\n \"9EA2A2\",\n \"898D8D\",\n \"707372\",\n \"54585A\",\n \"25282A\",\n \"BEC6C4\",\n \"A2ACAB\",\n \"919D9D\",\n \"717C7D\",\n \"505759\",\n \"3F4444\",\n \"373A36\",\n \"BABBB1\",\n \"A8A99E\",\n \"919388\",\n \"7E7F74\",\n \"65665C\",\n \"51534A\",\n \"212322\",\n \"C4BFB6\",\n \"AFA9A0\",\n \"9D968D\",\n \"8C857B\",\n \"776E64\",\n \"696158\",\n \"C4BCB7\",\n \"B2A8A2\",\n \"978C87\",\n \"857874\",\n \"746661\",\n \"5E514D\",\n \"382F2D\",\n \"D0C4C5\",\n \"C1B2B6\",\n \"AB989D\",\n \"7B6469\",\n \"584446\",\n \"453536\",\n \"382E2C\",\n \"D7D2CB\",\n \"CBC4BC\",\n \"BFB8AF\",\n \"B6ADA5\",\n \"ACA39A\",\n \"A59C94\",\n \"968C83\",\n \"8C8279\",\n \"83786F\",\n \"796E65\",\n \"6E6259\",\n \"D9D9D6\",\n \"D0D0CE\",\n \"C8C9C7\",\n \"BBBCBC\",\n \"B1B3B3\",\n \"A7A8AA\",\n \"97999B\",\n \"888B8D\",\n \"75787B\",\n \"63666A\",\n \"53565A\",\n \"332F21\",\n \"212721\",\n \"31261D\",\n \"3E2B2E\",\n \"101820\",\n \"3D3935\",\n];\n\nconst rgbValues = hexValues.map((h) => [\n parseInt(h.substring(0, 2), 16),\n parseInt(h.substring(2, 4), 16),\n parseInt(h.substring(4, 6), 16),\n]);\n\nfunction pmsToRgb(color: string) {\n const idx = pmsValues.indexOf(color);\n return idx >= 0 ? hexValues[idx] : \"\";\n}\n\nfunction rgbToPms(color: string) {\n const idx = hexValues.indexOf(color);\n return idx >= 0 ? pmsValues[idx] : \"\";\n}\n\n/**\n * Matches an input hex code (RRGGBB) to a number of PMS values. If an exact match is found, it will always be the first value in the resulting array.\n * @param hex A string containing the hexadecimal representation of a color, presented as RRGGBB (case sensitive).\n * @param maxDistance The maximum distance the input can be from a PMS color to be considered a match.\n * @returns An array of PMS color strings.\n */\nfunction matchHexToPms(hex: string, maxDistance = 64): { pms: string; hex: string }[] {\n const pmsColors: { pms: string; hex: string; distance: number }[] = [];\n const distances: number[] = [];\n const match = rgbToPms(hex);\n if (match) {\n pmsColors.push({\n pms: match,\n hex,\n distance: 0,\n });\n }\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n let r1: number, g1: number, b1: number;\n for (let idx = 0; idx < hexValues.length; idx++) {\n r1 = rgbValues[idx][0];\n g1 = rgbValues[idx][1];\n b1 = rgbValues[idx][2];\n const dist = Math.sqrt(Math.pow(r - r1, 2) + Math.pow(g - g1, 2) + Math.pow(b - b1, 2));\n distances.push(dist);\n }\n for (let idx = 0; idx < distances.length; idx++) {\n if (distances[idx] <= maxDistance && !pmsColors.some((it) => it.pms === pmsValues[idx])) {\n pmsColors.push({ pms: pmsValues[idx], hex: hexValues[idx], distance: distances[idx] });\n }\n }\n return pmsColors.sort((a, b) => a.distance - b.distance);\n}\n\n// TODO: add extra keywords\nconst pmsHexData = pmsValues.map((pms, idx) => ({ pms, hex: hexValues[idx] }));\nconst fuse = new Fuse(pmsHexData, { keys: [\"pms\"] });\ntype PmsSearchResult = FuseResult<{ pms: string; hex: string }>;\n/**\n * Searches for the input string across all of the known PMS values.\n * @param input The string to find.\n * @returns An array of objects that contain information on the matched PMS values.\n */\nfunction findPmsColors(input: string, limit?: number): PmsSearchResult[] {\n return fuse.search(input, !limit ? undefined : { limit });\n}\n\nlet colorContext: CanvasRenderingContext2D | null = null;\n/**\n * Converts an arbitrary browser color value into a hexadecimal string (RRGGBB).\n * If the provided color string is anything other than a hex code, it will use a canvas to determine the hex value.\n * @returns\n */\nfunction browserColorToHex(color: string): string {\n if (color.startsWith(\"#\")) {\n // Browser hex code\n return sanitizeHexCode(color);\n }\n if (!document) {\n throw new Error(\"browserColorToHex is only supported on browsers\");\n }\n if (!colorContext) {\n colorContext = document.createElement(\"canvas\").getContext(\"2d\");\n }\n if (!colorContext) {\n throw new Error(\"Failed to create canvas context required to convert colors\");\n }\n colorContext.fillStyle = color;\n // Setting fillStyle to the colorContext is expected to immediately convert it. Not tested ony anything except browsers, so marked as unsupported.\n const sanitized = sanitizeHexCode(colorContext.fillStyle);\n if (!sanitized) {\n console.error(`Unknown browser color ${color}`);\n }\n return sanitized;\n}\n\nfunction sanitizeHexCode(hexCode: string): string {\n const hex = hexCode.substring(1).toUpperCase();\n if (hex.length === 6) {\n return hex;\n }\n if (hex.length === 3) {\n // hex code ABC is the same as AABBCC\n return `${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;\n }\n return \"\";\n}\n\nexport const colorDefinitionPrintValue = (colorDefinition: ColorDefinition): string => {\n const spot = spotColorDefinitionString(colorDefinition.spotColor);\n if (spot) {\n return `${colorDefinition.browserValue} ${spot}`;\n }\n return colorDefinition.browserValue;\n};\n\nexport const spotColorDefinitionString = (spotColorDefinition?: SpotColorDefinition): string => {\n if (!spotColorDefinition) {\n return \"\";\n }\n\n if (spotColorDefinition.profileName.includes(\"/\") && spotColorDefinition.profileName.includes(\".icc\")) {\n const profileNameStrWithoutSpaces = spotColorDefinition.profileName.replace(/\\s/g, \"-\");\n const amountToSlice = profileNameStrWithoutSpaces.lastIndexOf(\"/\");\n const profileNameFiltered = profileNameStrWithoutSpaces.slice(amountToSlice + 1); // Removes all characters before the last instance of /\n const finalFilteredName = profileNameFiltered.slice(0, -4); // Removes last 4 characters in the string which is the file extension (eg .icc)\n\n return `icc-named-color(${finalFilteredName}, ${spotColorDefinition.namedColor})`;\n }\n\n return `icc-named-color(${spotColorDefinition.profileName}, ${spotColorDefinition.namedColor})`;\n};\n\n/**\n * Converts a color value found in an SVG file into a color definition. This\n * logic will split out the browser value eg. \"#ffffff\" and the spot color value if available eg.\n * icc-named-color(cub, PANTONE_AAA_100_C)\n * @param value A color definition based on the data provided in the value.\n */\nexport const svgColorValueToDefinition = (value: string): ColorDefinition => {\n const parts = value.split(/[ ](?=[^)]*?(?:\\(|$))/);\n // When no parts exists we have an invalid value,\n // default to black in the same way browsers would.\n if (parts.length === 0) {\n return { browserValue: \"#000000\" };\n }\n // When only one part exists, we should have been given just a browser value.\n if (parts.length === 1) {\n return { browserValue: parts[0] };\n }\n // If multiple parts exist then we have a browser value and a spot color.\n const matchedFunctionArgs = parts[1].match(/\\(([^)]+)\\)/gm);\n if (!matchedFunctionArgs) {\n throw new Error(\"Unhandled state of color value in SVG\");\n }\n const params = matchedFunctionArgs[0].replace(/[() ]/g, \"\").split(\",\");\n return {\n browserValue: parts[0],\n spotColor: { profileName: params[0], namedColor: params[1] },\n };\n};\n\nexport { matchHexToPms, rgbToPms, pmsToRgb, browserColorToHex, findPmsColors };\nexport type { PmsSearchResult };\n","import { Declaration, parse, Rule } from \"css\";\nimport { colorDefinitionPrintValue, svgColorValueToDefinition } from \"./color\";\nimport { domParser, xmlSerializer } from \"./crossplatform\";\nimport { ColorDefinition } from \"../types\";\n\nconst fillableTagNames = [\n \"altGlyph\",\n \"circle\",\n \"ellipse\",\n \"path\",\n \"polygon\",\n \"polyline\",\n \"rect\",\n \"text\",\n \"textPath\",\n \"tref\",\n \"tspan\",\n];\n\n/** These fields in an inline style should be moved to an attribute */\nconst replaceableStyleNames = [\"fill\", \"stroke\"];\n\n/*\n * Apply a function to a DOM node and all its children.\n */\nconst traverse = (node: Element, f: (node: Element) => void) => {\n f(node);\n if (node.children.length > 0) {\n Array.from(node.children).forEach((child) => traverse(child, f));\n }\n};\n\n/*\n * Succesively check a node's parents for a value, stopping when one is found or when we pass the root.\n */\nconst checkAncestors = <T>(node: Element, f: (node: Element) => (undefined | T)): (undefined | T) => {\n const candidate = f(node);\n if (candidate) {\n return candidate;\n }\n const parent = node.parentElement;\n if (!parent) {\n return undefined;\n }\n return checkAncestors(parent, f);\n};\n\n/**\n * Whether an SVG element matches a CSS selector.\n */\nconst matchingSelector = (node: Element, selector: string): boolean => {\n try {\n return node.matches(selector);\n } catch (e) {\n // Currently the only known type of failure is if a\n // class name contains a backtick.\n return node.classList.contains(selector.substring(1));\n }\n};\n\n/*\n * Prepare SVG to be embedded.\n */\nconst sanitizeSvgTree = (root: Element, preserveAspectRatio = false) => {\n // Set this so region height and width are respected.\n !preserveAspectRatio && root.setAttribute(\"preserveAspectRatio\", \"none\");\n\n // Discard script tags.\n // Convert style tags to per-element styles.\n const rules: Rule[] = [];\n traverse(root, (node) => {\n if (node.tagName === \"script\") {\n node.remove();\n return;\n }\n if (node.tagName === \"style\") {\n try {\n const tree = parse(node.innerHTML);\n tree.stylesheet?.rules.forEach((rule: Rule) => {\n rules.push(rule);\n });\n node.remove();\n } catch (e) {\n console.error(e);\n }\n return;\n }\n const nodeStyle = node.attributes.getNamedItem(\"style\")?.value?.trim();\n if (nodeStyle) {\n const styles: string[] = [];\n const styleStrings = nodeStyle.split(\";\");\n styleStrings.forEach((style) => {\n const trimmed = style.trim();\n if (trimmed) {\n const [field, value] = trimmed.split(\":\");\n const fieldDowncased = field.toLowerCase();\n const idx = replaceableStyleNames.indexOf(fieldDowncased);\n if (idx > -1) {\n node.setAttribute(fieldDowncased, value.trim());\n } else {\n styles.push(trimmed);\n }\n }\n });\n if (styles.length > 0) {\n node.setAttribute(\"style\", styles.join(\";\"));\n } else {\n node.removeAttribute(\"style\");\n }\n }\n });\n traverse(root, (node) => {\n rules.forEach((rule) => {\n rule.selectors?.forEach((selector) => {\n if (matchingSelector(node, selector)) {\n rule.declarations?.forEach((decl: Declaration) => {\n if (decl.property && decl.value) {\n node.setAttribute(decl.property, decl.value);\n }\n });\n }\n });\n });\n });\n};\n\n/*\n * SVG files shouldn't contain a width and height. Only a viewbox.\n * The platform handles width and height independant.\n */\nconst sanitizeSVGDimensions = (root: Element) => {\n const nonPixelUnitsRegex = /pt|pc|mm|cm|in/gm;\n const viewBox = root.getAttribute(\"viewBox\");\n const width = root.getAttribute(\"width\");\n const height = root.getAttribute(\"height\");\n if (!viewBox) throw new Error(\"viewBox not specified on SVG!\");\n if (width) root.setAttribute(\"width\", width.replace(nonPixelUnitsRegex, \"\"));\n if (height) root.setAttribute(\"height\", height.replace(nonPixelUnitsRegex, \"\"));\n};\n\nconst svgStringToElement = (svg: string): Element | null => {\n const parser = domParser();\n const parsedSvg = parser.parseFromString(svg, \"image/svg+xml\");\n return parsedSvg.firstElementChild;\n};\n\nconst setSvgDimensions = (svgRoot: Element, width: number, height: number) => {\n svgRoot.setAttribute(\"height\", `${height}px`);\n svgRoot.setAttribute(\"width\", `${width}px`);\n};\n\nconst setSvgColors = (svgRoot: Element, colors: { [key: string]: ColorDefinition }, includeSpotColors?: boolean) => {\n traverse(svgRoot, (node) => {\n // Handle fills set directly on elements.\n const fill = node.attributes.getNamedItem(\"fill\");\n if (fill && fill.value !== \"none\") {\n node.classList.forEach((className) => {\n if (className.startsWith(\"spiff-fill\")) {\n const color = colors[className.replace(\"spiff-fill-\", \"\")];\n if (color) {\n node.setAttribute(\n \"fill\",\n includeSpotColors ? colorDefinitionPrintValue(color) : color.browserValue,\n );\n } else {\n // legacy\n const color = colors[className];\n if (color) {\n node.setAttribute(\n \"fill\",\n includeSpotColors ? colorDefinitionPrintValue(color) : color.browserValue,\n );\n }\n }\n }\n });\n }\n const stroke = node.attributes.getNamedItem(\"stroke\");\n if (stroke && stroke.value !== \"none\") {\n node.classList.forEach((className) => {\n if (className.startsWith(\"spiff-stroke\")) {\n const color = colors[className.replace(\"spiff-stroke-\", \"\")];\n if (color) {\n node.setAttribute(\n \"stroke\",\n includeSpotColors ? colorDefinitionPrintValue(color) : color.browserValue,\n );\n } else {\n // legacy\n const color = colors[className];\n if (color) {\n node.setAttribute(\n \"fill\", // Should this be \"stroke\"? Is this code still relevant anyway?\n includeSpotColors ? colorDefinitionPrintValue(color) : color.browserValue,\n );\n }\n }\n }\n });\n }\n });\n};\n\nconst svgElementToString = (svgRoot: Element): string => {\n const serialiser = xmlSerializer();\n return serialiser.serializeToString(svgRoot);\n};\n\nconst modifySVGWithElementProperties = (\n svg: string,\n width: number,\n height: number,\n colors: { [key: string]: ColorDefinition },\n includeSpotColors?: boolean,\n): string => {\n const svgRoot = svgStringToElement(svg);\n if (!svgRoot) {\n throw new Error(\"Failed to read SVG.\");\n }\n setSvgDimensions(svgRoot, width, height);\n setSvgColors(svgRoot, colors, includeSpotColors);\n return svgElementToString(svgRoot);\n};\n\nconst modifySVGColors = (\n svg: string,\n colors: { [key: string]: ColorDefinition },\n includeSpotColors?: boolean,\n): string => {\n const svgRoot = svgStringToElement(svg);\n if (!svgRoot) {\n throw new Error(\"Failed to read SVG.\");\n }\n setSvgColors(svgRoot, colors, includeSpotColors);\n return svgElementToString(svgRoot);\n};\n\nconst parseSvg = (svgBody: string): any => {\n // Get the raw SVG without a doctype.\n const svgRegex = /<svg.*<\\/svg>/s;\n const svgMatches = svgBody.match(svgRegex) || [];\n const svg = svgMatches?.length > 0 ? svgMatches[0] : \"\";\n\n // Parse the SVG into a tree.\n const parser = domParser();\n return parser.parseFromString(svg, \"image/svg+xml\");\n};\n\nconst generateSVGWithUnknownColors = async (\n svgBody: string,\n): Promise<{ svg: string; colors: { [key: string]: ColorDefinition } }> => {\n const parsedSvg = parseSvg(svgBody);\n const root = parsedSvg.firstElementChild;\n if (!root) {\n throw new Error(\"Failed to read SVG.\");\n }\n\n sanitizeSvgTree(root);\n\n // Annotate elements which have fills with a new class name.\n const colors: { [key: string]: ColorDefinition } = {};\n traverse(root, (node) => {\n // A fillable element's fill is:\n // * The fill in its style; otherwise\n // * The fill in its fill attribute; otherwise\n // * The fill of its closest ancestor (style takes priority over attribute); otherwise\n // * Black (none of its ancestors have an explicit fill).\n // Historically we have not cared about the first case, but for the third case the\n // code for attaching explicit fills to elements without explicit fills needs to\n // successively check its ancestors.\n\n if (fillableTagNames.includes(node.tagName) && !node.attributes.getNamedItem(\"fill\")) {\n let fill = \"black\";\n const parent = node.parentElement;\n if (parent) {\n const ancestorFill = checkAncestors(parent, (node: Element) => {\n const inlineStyles = (node as SVGElement).style;\n const inlineFill = inlineStyles.fill;\n if (inlineFill) {\n return inlineFill;\n }\n const attribute = node.getAttribute(\"fill\");\n if (attribute) {\n return attribute;\n }\n return undefined;\n });\n if (ancestorFill) {\n fill = ancestorFill;\n }\n }\n node.setAttribute(\"fill\", fill);\n }\n\n const fill = node.attributes.getNamedItem(\"fill\");\n if (fill && fill.value !== \"none\" && !fill.value.startsWith(\"url(\")) {\n const fillValue = svgColorValueToDefinition(fill.value);\n const alphanumericFill = fillValue.browserValue.replace(/\\W/g, \"\");\n const className = `spiff-fill-${alphanumericFill}`;\n node.setAttribute(\"fill\", fillValue.browserValue);\n node.classList.add(className);\n colors[alphanumericFill] = fillValue;\n }\n const stroke = node.attributes.getNamedItem(\"stroke\");\n if (stroke && stroke.value !== \"none\" && !stroke.value.startsWith(\"url(\")) {\n const strokeValue = svgColorValueToDefinition(stroke.value);\n const alphanumericFill = strokeValue.browserValue.replace(/\\W/g, \"\");\n const className = `spiff-stroke-${alphanumericFill}`;\n node.classList.add(className);\n node.setAttribute(\"stroke\", strokeValue.browserValue);\n colors[alphanumericFill] = strokeValue;\n }\n });\n\n const serialiser = xmlSerializer();\n const rebuiltSvg = serialiser.serializeToString(root);\n\n return {\n colors,\n svg: rebuiltSvg,\n };\n};\n\nexport {\n sanitizeSvgTree,\n sanitizeSVGDimensions,\n traverse,\n modifySVGWithElementProperties,\n modifySVGColors,\n generateSVGWithUnknownColors,\n};\n","import { gql } from \"@apollo/client/core\";\nimport { Asset, AssetType, FileInfo, MaterialResource } from \"../types\";\nimport { ParseError, UnhandledBehaviorError } from \"../util/exception\";\nimport { persistenceService } from \"./persistence\";\nimport { graphQlManager } from \"./server\";\nimport { getAttributesFromArrayBuffer } from \"../util/image\";\nimport { sanitizeSVGDimensions } from \"../util/illustration\";\nimport { xmlSerializer } from \"../util/crossplatform\";\n\ninterface AssetCreation {\n asset: Asset;\n uploadUrl: string;\n}\n\ninterface AssetCreationInfo {\n assetResponse: AssetCreation;\n mimeType: string;\n}\n\nconst assetMetadataFragment = gql`\n fragment AssetMetadataFields on Asset {\n metadata {\n key\n value\n }\n }\n`;\n\nexport const assetFragment = (includeMetadata: boolean) => {\n return gql`\n ${(includeMetadata && assetMetadataFragment) || \"\"}\n fragment AssetFields on Asset {\n name\n key\n type\n createdAt\n mimeType\n fileLink\n assetConfiguration {\n assetKey\n colorOption {\n id\n name\n variants {\n id\n name\n enabled\n namedColor\n color\n }\n }\n channelNumbers {\n id\n number\n }\n defaultColorVariants {\n channelNumber\n variant {\n id\n name\n enabled\n namedColor\n color\n }\n }\n }\n versions {\n name\n link\n }\n ${(includeMetadata && \"...AssetMetadataFields\") || \"\"}\n }\n `;\n};\n\nconst getAssetsQuery = gql`\n ${assetFragment(false)}\n query GetAssets($keys: [String]!) {\n assets(keys: $keys) {\n ...AssetFields\n }\n }\n`;\n\nexport const materialFragment = gql`\n fragment MaterialFields on Material {\n id\n name\n createdAt\n clearCoat\n clearCoatIor\n refractionIntensity\n reflectionIntensity\n reflectionRotation\n albedoMap {\n key\n fileLink\n }\n alphaMap {\n key\n fileLink\n }\n ambientMap {\n key\n fileLink\n }\n emissionMap {\n key\n fileLink\n }\n metallicMap {\n key\n fileLink\n }\n normalMap {\n key\n fileLink\n }\n refractionMap {\n key\n fileLink\n }\n reflectionMap {\n key\n fileLink\n }\n roughnessMap {\n key\n fileLink\n }\n }\n`;\n\nconst getMaterialsQuery = gql`\n ${materialFragment}\n query GetMaterials($ids: [String]) {\n materials(id: $ids) {\n ...MaterialFields\n }\n }\n`;\n\nconst createAssetMutation = gql`\n mutation CreateAsset($name: String!, $type: String!, $mimeType: String!, $anonymous: Boolean, $temporary: Boolean) {\n assetCreate(name: $name, type: $type, mimeType: $mimeType, anonymous: $anonymous, temporary: $temporary) {\n uploadUrl\n asset {\n name\n key\n type\n createdAt\n mimeType\n fileLink\n }\n }\n }\n`;\n\nconst removeBackgroundFromAssetMutation = gql`\n ${assetFragment(false)}\n mutation RemoveBackgroundFromAsset($key: String!) {\n assetRemoveBackground(key: $key) {\n ...AssetFields\n }\n }\n`;\n\nexport const getAssets = async (assetKeys: string[]): Promise<Asset[]> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ assets: Asset[] }>({\n query: getAssetsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n keys: assetKeys,\n },\n });\n return response.data.assets;\n};\n\nconst getMaterials = async (ids: string[]): Promise<MaterialResource[]> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ materials: MaterialResource[] }>({\n query: getMaterialsQuery,\n errorPolicy: \"all\",\n variables: {\n ids,\n },\n });\n return response.data.materials;\n};\n\nconst createAsset = async (\n name: string,\n type: string,\n mimeType: string,\n anonymous?: boolean,\n temporary?: boolean,\n): Promise<undefined | AssetCreation> => {\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{ assetCreate: AssetCreation }>({\n mutation: createAssetMutation,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n name,\n type,\n mimeType,\n anonymous,\n temporary,\n },\n });\n return response.data?.assetCreate;\n};\n\n/**\n * An asset manager provides a way to create and\n * manage assets on the Spiff Commerce Platform.\n */\nexport interface AssetManager {\n /**\n * Uploads a file to the Spiff Commerce Platform.\n */\n uploadFile: (file: File, onProgress: (val: number) => void) => Promise<Asset>;\n\n /**\n * From an existing asset, generates a new asset that has the background replaced with transparency.\n * This process is idempotent, i.e. it will only run once for a given asset.\n * @param asset The existing asset to remove the background from.\n * @returns A promise that resolves with a new asset.\n */\n removeBackgroundFromAsset(asset: Asset): Promise<Asset>;\n}\n\nclass AssetService implements AssetManager {\n private cache = new Map<string, Promise<Asset>>();\n /**\n * Promise cache for BG removal processes. Values only present while process is active.\n * Use BGRMStorage and the regular asset promise cache to cache the actual objects.\n */\n private bgrmProcessCache = new Map<string, Promise<Asset>>();\n private materialCache = new Map<string, Promise<MaterialResource>>();\n\n /**\n * Allows for retrieving an asset, returns the option from a cache if possible.\n */\n async getLocalOrFromServer(assetKey: string): Promise<Asset> {\n if (this.cache.has(assetKey)) {\n const asset = this.cache.get(assetKey);\n if (!asset) throw new UnhandledBehaviorError(\"Failed to get asset from cache!\");\n return asset;\n }\n const assetResolver = async () => {\n const asset = (await getAssets([assetKey]))[0];\n return asset;\n };\n const resolver = assetResolver();\n this.cache.set(assetKey, resolver);\n return resolver;\n }\n\n /**\n * Retrieves the asset from the server, bypassing cache (but still writing the result to cache)\n */\n async getFromServer(assetKey: string): Promise<Asset> {\n const assetResolver = async () => {\n const asset = (await getAssets([assetKey]))[0];\n return asset;\n };\n const resolver = assetResolver();\n this.cache.set(assetKey, resolver);\n return resolver;\n }\n\n keyFromURL(url: string): string | undefined {\n let key: string | undefined = undefined;\n try {\n key = new URL(url).pathname;\n } catch (e) {\n key = undefined;\n }\n if (key !== undefined && key.startsWith(\"/\")) {\n key = key.replace(\"/\", \"\");\n }\n return key?.split(\"?\")[0];\n }\n\n /**\n * Caches an asset if it doesn't already exist.\n */\n cacheAsset(asset: Asset) {\n if (!asset.key) throw new UnhandledBehaviorError(\"Asset has no key!\");\n if (this.cache.has(asset.key)) {\n return;\n }\n this.cache.set(asset.key, Promise.resolve(asset));\n }\n\n /**\n * Caches a material if it doesn't already exist.\n */\n cacheMaterial(material: MaterialResource) {\n if (!material.id) throw new UnhandledBehaviorError(\"Material has no id!\");\n if (this.materialCache.has(material.id)) {\n return;\n }\n this.materialCache.set(material.id, Promise.resolve(material));\n }\n\n /**\n * Allows for retrieving a material, returns the option from a cache if possible.\n * @param id The option ID to be retrieved.\n */\n async getMaterialLocalOrFromServer(id: string): Promise<MaterialResource> {\n if (this.materialCache.has(id)) {\n return this.materialCache.get(id)!;\n }\n const materialResolver = async () => {\n const material = (await getMaterials([id]))[0];\n return material;\n };\n const resolver = materialResolver();\n this.materialCache.set(id, resolver);\n return resolver;\n }\n\n /**\n * Upload a user asset to the server. Using callbacks to notify important events.\n * The asset will be stored via the persistence service for future access, if available.\n */\n async uploadAssetWithProgress(\n file: FileInfo,\n assetType: AssetType,\n onProgress: (val: number) => void,\n anonymous?: boolean,\n temporary?: boolean,\n ): Promise<Asset> {\n // We request the server to create a new asset entity.\n const creationResponse = await this.dispatchCreateAssetRequest(file, assetType, anonymous, temporary);\n if (!creationResponse) {\n throw new Error(\"Failed to create asset.\");\n }\n\n // Organise a request & set up header and associated authentication. We use the provided\n // presigned URL to upload the users asset data to the server. The asset isn't valid until this is done.\n await new Promise<Asset>((resolve, reject) => {\n const req = new XMLHttpRequest();\n req.open(\"PUT\", creationResponse.assetResponse.uploadUrl, true);\n req.setRequestHeader(\"Content-Type\", creationResponse.mimeType);\n req.setRequestHeader(\"Cache-Control\", \"public,max-age=31536000,immutable\");\n req.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n onProgress((event.loaded * 100) / event.total);\n }\n };\n req.onload = () => {\n const responseData = creationResponse.assetResponse.asset;\n AssetStorage.add(creationResponse.assetResponse.asset);\n resolve(responseData);\n };\n req.onerror = reject;\n this.postProcessFileUpload(file, creationResponse.mimeType)\n .then((processedInfo) => req.send(processedInfo.blob))\n .catch(reject);\n });\n this.cacheAsset(creationResponse.assetResponse.asset);\n return creationResponse.assetResponse.asset;\n }\n\n async uploadAsset(file: FileInfo, assetType: AssetType, anonymous?: boolean, temporary?: boolean): Promise<Asset> {\n return this.uploadAssetWithProgress(file, assetType, () => {}, anonymous, temporary);\n }\n\n async uploadFile(file: File, onProgress: (val: number) => void): Promise<Asset> {\n const isRaster = this.isRaster(file);\n const assetType = !isRaster ? AssetType.Illustration : AssetType.Image;\n const fileInfo = await this.loadImageAsFileInfo(file);\n return await this.uploadAssetWithProgress(fileInfo, assetType, onProgress, true);\n }\n\n async removeBackgroundFromAsset(asset: Asset): Promise<Asset> {\n const originalKey = asset.key!;\n if (this.bgrmProcessCache.has(originalKey)) {\n return this.bgrmProcessCache.get(originalKey)!;\n }\n if (BGRMStorage.has(originalKey)) {\n const promise = this.getLocalOrFromServer(BGRMStorage.get(originalKey)!);\n this.bgrmProcessCache.set(originalKey, promise);\n return promise;\n }\n const processFunc = async (): Promise<Asset> => {\n const removeResponse = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ assetRemoveBackground: Asset }>({\n mutation: removeBackgroundFromAssetMutation,\n fetchPolicy: \"no-cache\",\n errorPolicy: \"all\",\n variables: {\n key: originalKey,\n },\n });\n this.bgrmProcessCache.delete(originalKey);\n if (!removeResponse.data?.assetRemoveBackground?.key) {\n throw new Error(\"Failed to remove background from image\");\n }\n AssetStorage.add(removeResponse.data.assetRemoveBackground);\n BGRMStorage.add(originalKey, removeResponse.data.assetRemoveBackground.key!);\n this.cache.set(\n removeResponse.data.assetRemoveBackground.key!,\n Promise.resolve(removeResponse.data.assetRemoveBackground),\n );\n return removeResponse.data.assetRemoveBackground;\n };\n const promise = processFunc();\n this.bgrmProcessCache.set(originalKey, promise);\n return promise;\n }\n\n removePersistedAsset(assetKey: string) {\n AssetStorage.remove(assetKey);\n BGRMStorage.delete(assetKey);\n BGRMStorage.deleteForBgRemovedKey(assetKey);\n }\n\n getPersistedAssets(): PersistedAsset[] {\n return AssetStorage.list();\n }\n\n registerPersistedAssetListener(callback: () => void) {\n AssetStorage.addCallback(callback);\n }\n\n unRegisterPersistedAssetListener(callback: () => void) {\n AssetStorage.removeCallback(callback);\n }\n\n /**\n * Convert a File object for an image into a FileInfo.\n */\n loadImageAsFileInfo = async (file: File): Promise<FileInfo> => {\n // Rasters are slightly more involved.\n const arrayBuffer = await file.arrayBuffer();\n const attributes = await getAttributesFromArrayBuffer(arrayBuffer);\n const dataUrlToBlob = (dataUrl: string, type: string) => {\n const binary = atob(dataUrl.split(\",\")[1]);\n const array: number[] = [];\n for (let i = 0; i < binary.length; i++) {\n array.push(binary.charCodeAt(i));\n }\n return new Blob([new Uint8Array(array)], { type });\n };\n return {\n name: file.name.substring(file.name.lastIndexOf(\"/\") + 1),\n blob: dataUrlToBlob(attributes.dataUrl, file.type),\n };\n };\n\n private isRaster(file: File): boolean {\n return !(\n file.type === \"image/svg+xml\" ||\n file.type === \"application/pdf\" ||\n file.type === \"application/postscript\"\n );\n }\n\n private async postProcessFileUpload(file: FileInfo, type: string) {\n if (type === \"image/svg+xml\") {\n const text = await file.blob.text();\n const parser = new window.DOMParser();\n const svgDom = parser.parseFromString(text, \"image/svg+xml\");\n const root = svgDom.documentElement;\n if (!root) throw new ParseError(\"Failed to read SVG.\");\n sanitizeSVGDimensions(root);\n const serialiser = xmlSerializer();\n const rebuiltSvg = serialiser.serializeToString(root);\n return {\n name: file.name,\n blob: new Blob([rebuiltSvg], { type: \"image/svg+xml\" }),\n };\n }\n return file;\n }\n\n /**\n * Handles mimeType resolution & asset creation request\n * @param file A file info object containing data about the file and its name\n * @param assetType The type of asset we're expecting to upload\n */\n private async dispatchCreateAssetRequest(\n file: FileInfo,\n assetType: AssetType,\n anonymous?: boolean,\n temporary?: boolean,\n ): Promise<undefined | AssetCreationInfo> {\n // Send a request for asset creation to server\n // We get a presigned upload URL back\n const mimeType = file.blob.type ? file.blob.type : this.guessMIME(file.name);\n const assetResponse = await createAsset(file.name, assetType, mimeType, anonymous, temporary);\n if (!assetResponse) {\n return undefined;\n }\n\n return {\n assetResponse,\n mimeType,\n };\n }\n\n private guessMIME(ext: string): string {\n const extension = ext.split(\".\").pop();\n switch (extension) {\n case \"glb\":\n return \"model/gltf-binary\";\n case \"ttf\":\n return \"font/ttf\";\n case \"mkv\":\n return \"video/x-matroska\";\n default:\n throw new UnhandledBehaviorError(\"Unexpected mimetype: \" + extension);\n }\n }\n}\n\ninterface PersistedAsset {\n assetKey: string;\n src: string;\n}\n\nconst ASSET_PERSISTENCE_KEY = \"persistentAssets\";\n/**\n * Some bundled functionality for dealing with assets in persistence.\n */\nclass AssetStorage {\n private static callbacks: (() => void)[] = [];\n\n /**\n * Add a new asset to persistence\n * @param asset The asset to add.\n */\n static add(asset: Asset) {\n if (!asset.fileLink) {\n console.error(\"Failed to find cdn link on asset, cannot persist!\");\n return;\n }\n // Create a new map to store data\n const newPersistentAssetsMap = new Map<string, string>();\n newPersistentAssetsMap.set(asset.key || \"\", asset.fileLink);\n // Merge existing keys if available, into the new map.\n const oldPersistentAssets = persistenceService.getMap(ASSET_PERSISTENCE_KEY);\n if (oldPersistentAssets) {\n oldPersistentAssets.forEach((value, key) => {\n newPersistentAssetsMap.set(key, value);\n });\n }\n // Save the new map with all keys.\n persistenceService.setMap(ASSET_PERSISTENCE_KEY, newPersistentAssetsMap);\n AssetStorage.executeCallbacks();\n }\n /**\n * Remove an existing asset from persistence. Noop if the asset doesn't exist.\n * @param assetKey The key to remove.\n */\n static remove(assetKey: string) {\n const uploadedAssetsMap = persistenceService.getMap(ASSET_PERSISTENCE_KEY);\n if (!uploadedAssetsMap) return;\n const entryToRemove = Array.from(uploadedAssetsMap.entries()).find((m) => m[0] === assetKey);\n if (!entryToRemove) return;\n uploadedAssetsMap.delete(entryToRemove[0]);\n persistenceService.setMap(ASSET_PERSISTENCE_KEY, uploadedAssetsMap);\n AssetStorage.executeCallbacks();\n }\n /**\n * Get a list of all persisted assets.\n */\n static list(): PersistedAsset[] {\n const uploadedAssetsMap = persistenceService.getMap(ASSET_PERSISTENCE_KEY);\n if (!uploadedAssetsMap) return [];\n return Array.from(uploadedAssetsMap.entries()).map((m) => ({ assetKey: m[0], src: m[1] }));\n }\n /**\n * Adds a callback that will be called whenever assets are added/removed from persistence.\n */\n static addCallback(callback: () => void) {\n AssetStorage.callbacks.push(callback);\n }\n /**\n * Removes an existing callback.\n */\n static removeCallback(callback: () => void) {\n AssetStorage.callbacks = AssetStorage.callbacks.filter((cb) => cb !== callback);\n }\n\n private static executeCallbacks() {\n AssetStorage.callbacks.forEach((cb) => cb());\n }\n}\n\nconst BGRM_ASSET_PERSISTENCE_KEY = \"bgrmPersistentAssets\";\nclass BGRMStorage {\n static has(originalKey: string): boolean {\n return BGRMStorage.getMap().has(originalKey);\n }\n static get(originalKey: string): string | undefined {\n return BGRMStorage.getMap().get(originalKey);\n }\n static keys(): IterableIterator<string> {\n return BGRMStorage.getMap().keys();\n }\n static values(): IterableIterator<string> {\n return BGRMStorage.getMap().values();\n }\n static add(originalKey: string, bgRemovedKey: string) {\n const cache = BGRMStorage.getMap();\n cache.set(originalKey, bgRemovedKey);\n BGRMStorage.setMap(cache);\n }\n static delete(originalKey: string) {\n const cache = BGRMStorage.getMap();\n cache.delete(originalKey);\n BGRMStorage.setMap(cache);\n }\n static deleteForBgRemovedKey(bgRemovedKey: string) {\n const cache = BGRMStorage.getMap();\n const originalKey = Array.from(cache.keys()).find((key) => cache.get(key) === bgRemovedKey);\n if (originalKey) {\n cache.delete(originalKey);\n BGRMStorage.setMap(cache);\n }\n }\n\n private static getMap(): Map<string, string> {\n return persistenceService.getMap(BGRM_ASSET_PERSISTENCE_KEY) || new Map();\n }\n private static setMap(map: Map<string, string>) {\n persistenceService.setMap(BGRM_ASSET_PERSISTENCE_KEY, map);\n }\n}\n\nexport const assetService = new AssetService();\n","/**\n * A simple cache for promises. Helpful to avoid making multiple requests for the same data.\n */\nclass PromiseCache {\n private cache: Record<string, Promise<any>> = {};\n private disabled = false;\n\n /**\n * Gets a promise from the cache, or undefined if it doesn't exist.\n */\n public get(key: object): Promise<any> | undefined {\n if (this.disabled) return undefined;\n const keyString = JSON.stringify(key);\n return this.cache[keyString];\n }\n\n /**\n * Sets a promise in the cache and returns it.\n */\n public set(key: object, promise: Promise<any>): Promise<any> {\n if (this.disabled) return promise;\n const keyString = JSON.stringify(key);\n this.cache[keyString] = promise;\n return promise;\n }\n\n /**\n * Some environments don't want workflows to be cached. An example is a server\n * that doesn't launch a fresh instance per request. This method allows disabling\n * caching in a transparent way.\n */\n public disable(value: boolean): void {\n this.disabled = value;\n }\n}\n\nconst promiseCache = new PromiseCache();\nexport default promiseCache;\n","import { gql } from \"@apollo/client/core\";\nimport { assetFragment, assetService, materialFragment } from \"./asset\";\nimport promiseCache from \"./promiseCache\";\nimport { graphQlManager } from \"./server\";\nimport { AnyStepData, OptionResource, Step, VariantResource } from \"../types\";\n\nexport const optionMinimalFragment = gql`\n fragment OptionMinimalFields on Option {\n id\n defaultVariant {\n id\n }\n }\n`;\n\nexport const optionFragment = gql`\n fragment OptionFields on Option {\n id\n name\n public\n currencyCode\n type\n workflowId\n displayType\n integrationOptions {\n id\n integrationId\n }\n variants {\n id\n name\n enabled\n color\n namedColor\n priceModifier\n asset {\n ...AssetFields\n }\n thumbnail {\n ...AssetFields\n }\n material {\n ...MaterialFields\n }\n }\n defaultVariant {\n id\n }\n colorProfile {\n ...AssetFields\n }\n }\n`;\n\nconst getOptionsQuery = gql`\n ${assetFragment(false)}\n ${materialFragment}\n ${optionFragment}\n query GetOptions($ids: [String]!) {\n options(ids: $ids) {\n ...OptionFields\n }\n }\n`;\n\nconst getTagsQuery = gql`\n query GetTagsMany($ids: [String!]!) {\n tagsMany(entityIds: $ids) {\n id\n entityId\n name\n }\n }\n`;\n\nconst getOptionsInternal = async (ids: string[]): Promise<OptionResource[]> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ options: OptionResource[] }>({\n query: getOptionsQuery,\n errorPolicy: \"all\",\n variables: {\n ids,\n },\n });\n response.data.options.forEach((option) => {\n option.colorProfile && assetService.cacheAsset(option.colorProfile);\n option.variants?.forEach((variant) => {\n variant.asset && assetService.cacheAsset(variant.asset);\n variant.thumbnail && assetService.cacheAsset(variant.thumbnail);\n variant.material && assetService.cacheMaterial(variant.material);\n });\n });\n return response.data.options;\n};\n\nconst findOptionFromPromise = async (\n id: string,\n promise: Promise<OptionResource[]>,\n): Promise<OptionResource | undefined> => {\n const options = await promise;\n return options.find((option) => option.id === id);\n};\n\nconst getOptions = async (ids: string[]): Promise<OptionResource[]> => {\n const promises = new Map(ids.map((id) => [id, promiseCache.get({ id })]));\n const uncachedIds = ids.filter((id) => promises.get(id) === undefined);\n if (uncachedIds.length > 0) {\n const batchPromise = getOptionsInternal(uncachedIds);\n uncachedIds.forEach((id) =>\n promises.set(id, promiseCache.set({ id }, findOptionFromPromise(id, batchPromise))),\n );\n }\n const results = await Promise.all(ids.map((id) => promises.get(id)!));\n return results.filter((option): option is OptionResource => option !== undefined);\n};\n\nconst getAssetImageUrl = (asset: VariantResource[\"asset\"]): string | undefined => {\n if (!asset) {\n return;\n }\n const thumbnail = asset.versions?.find((v) => v.name === \"thumbnail\");\n return thumbnail?.link || asset.fileLink!;\n};\n\nconst findDefaultVariant = (\n variants: VariantResource[],\n option: OptionResource,\n overrideDefaultVariantId?: string,\n): VariantResource | undefined => {\n if (variants.length === 1) {\n return variants[0];\n }\n if (overrideDefaultVariantId) {\n const v = variants.find((v) => v.id === overrideDefaultVariantId);\n if (v) {\n return v;\n }\n }\n if (option.defaultVariant === undefined) {\n return;\n }\n return variants.find((variant) => variant.id === option.defaultVariant?.id);\n};\n\nclass OptionService {\n /**\n * Allows for retrieving an option, returns the option from a cache if possible.\n * @param id The option ID to be retrieved.\n */\n async getOption(id: string): Promise<OptionResource | undefined> {\n if (!id) {\n return undefined;\n }\n const options = await getOptions([id]);\n return options[0];\n }\n\n async getOptions(ids: string[]): Promise<OptionResource[]> {\n return getOptions(ids);\n }\n\n async getOptionForStep(stepData: Step<AnyStepData>): Promise<OptionResource | undefined> {\n return this.ensureFullOption(stepData.option);\n }\n\n /**\n * Utility function to get the full option from either the network or return the existing option if it can be considered to have the \"full\" state.\n *\n * @returns The full option resource, or `undefined` if invalid.\n */\n async ensureFullOption(option: OptionResource | undefined): Promise<OptionResource | undefined> {\n if (option?.variants) {\n return option;\n }\n if (!option?.id) {\n return undefined;\n }\n const options = await getOptions([option.id]);\n return options[0];\n }\n\n /**\n * Returns the URL of the image to be used for a given variant. The priority is:\n * 1. The variant's thumbnail (if it exists)\n * 2. The variant's asset (if it exists)\n * 3. The variant's material ID (if it exists) // TODO: Does this really make sense?\n * 4. An empty string if none of the above exist\n * @param variant The variant for which to retrieve the image URL.\n * @returns A promise that resolves to the URL of the image to be used for the given variant, or an empty string if no image is available.\n */\n async getAssetTileImageForVariant(variant: VariantResource): Promise<string> {\n const thumbnailUrl = getAssetImageUrl(variant.thumbnail) ?? getAssetImageUrl(variant.asset);\n if (thumbnailUrl) {\n return thumbnailUrl;\n }\n\n if (variant.material) {\n return variant.material.id;\n }\n\n return \"\";\n }\n\n /**\n * Returns the default variant for a given option. If there is only one variant, that variant is returned. If there are multiple variants, the variant with the ID matching overrideDefaultVariantId is returned (if provided). If overrideDefaultVariantId is not provided or does not match any variant, the variant marked as defaultVariant on the option is returned.\n * @param option The option for which to retrieve the default variant.\n * @param overrideDefaultVariantId An optional variant ID to override the default variant selection. This is used in certain cases where we want to specify a default variant that is different from the one marked as defaultVariant on the option.\n * @returns The default variant for the given option, or undefined if no default variant can be determined.\n */\n getDefaultVariant = async (\n option: OptionResource,\n overrideDefaultVariantId?: string,\n ): Promise<VariantResource | undefined> => {\n // Check passed object first to avoid unnecessary cache lookups and network requests.\n const existingVariants = option?.variants;\n if (existingVariants) {\n return findDefaultVariant(existingVariants, option, overrideDefaultVariantId);\n }\n // If variants are not present on the passed object, attempt to retrieve them via cache/network.\n const loadedOption = await this.getOption(option.id!);\n const variants = loadedOption?.variants;\n if (!variants) {\n return;\n }\n return findDefaultVariant(variants, option, overrideDefaultVariantId);\n };\n\n getTagsForAssets = async (variants: VariantResource[]): Promise<{ id: string, entityId: string, name: string }[][]> => {\n const assetIds = variants?.map(v => v.asset?.key) || [];\n const materialIds = variants?.map(v => v.material?.id) || [];\n const ids = [...assetIds, ...materialIds].filter(id => !!id);\n if (ids.length === 0) {\n return [];\n }\n const response = await graphQlManager.getShadowGraphqlClient().query<{ tagsMany: { id: string, entityId: string, name: string }[][] }>({\n query: getTagsQuery,\n errorPolicy: \"all\",\n variables: {\n ids,\n },\n });\n return response.data.tagsMany;\n };\n}\n\nconst optionService = new OptionService();\nexport { optionService };\n","import { gql } from \"@apollo/client/core\";\nimport { assetFragment } from \"./services/asset\";\nimport { optionMinimalFragment, optionFragment } from \"./services/option\";\n\nexport const activeIntegrationFragment = gql`\n fragment ActiveIntegrationFields on Integration {\n id\n logo\n name\n theme {\n id\n configuration\n primaryColor\n secondaryColor\n textColor\n }\n partner {\n id\n name\n activeAddons\n currencyCode\n beta\n }\n }\n`;\n\nexport const additionalProductFragment = gql`\n fragment AdditionalIntegrationProductFields on IntegrationProduct {\n id\n product {\n id\n basePrice\n enabled\n name\n description\n sku\n skuCode\n weight\n imageUrl\n modelUrl\n overlayImageUrl\n preloadImageUrl\n }\n }\n`;\n\nexport const recipientFragment = gql`\n fragment RecipientFields on Recipient {\n id\n firstName\n lastName\n address\n suburb\n state\n email\n postalCode\n country\n mobile\n company\n apartment\n customField1\n customField2\n customField3\n customField4\n customField5\n conversionConfigurationId\n }\n`;\n\nexport const conversionConfigurationFragment = gql`\n fragment ConversionConfigurationFields on ConversionConfiguration {\n id\n partnerId\n name\n locations\n mandatory\n requestedData\n requestedDataItems {\n type\n mandatory\n title\n uniqueIdentifier\n customFieldIndex\n optionId\n option {\n id\n name\n variants {\n id\n name\n enabled\n }\n defaultVariant {\n id\n }\n }\n }\n }\n`;\n\nexport const createManyTransactionsMutation = gql`\n ${recipientFragment}\n mutation CreateTransactions(\n $inputs: [TransactionCreateInput]!\n $marketplaceThemeInstallId: String\n $marketplaceThemeInstallConfigurationId: String\n ) {\n transactionCreateMany(\n inputs: $inputs\n marketplaceThemeInstallId: $marketplaceThemeInstallId\n marketplaceThemeInstallConfigurationId: $marketplaceThemeInstallConfigurationId\n ) {\n id\n designName\n transactionOwnerId\n workflowId\n customLogoLink\n quantity\n workflowFooterLogoLink\n restApiIntegrationLink\n workflowState\n workflowViewerLink\n workflowViewerReadOnlyLink\n recipient {\n ...RecipientFields\n }\n integrationProductId\n }\n }\n`;\n\nexport const stakeholderFragment = gql`\n fragment StakeholderFields on Stakeholder {\n id\n type\n authorizationDate\n authorizationNote\n authorizationStatus\n }\n`;\n\nexport const transactionShareActionFragment = gql`\n fragment TransactionShareActionFields on TransactionShareAction {\n id\n title\n type\n stakeholderType\n precedence\n url\n }\n`;\n\nexport const readIntegrationProductsQuery = gql`\n ${additionalProductFragment}\n ${conversionConfigurationFragment}\n ${activeIntegrationFragment}\n query ReadIntegrationProducts($ids: [String!]!) {\n integrationProducts(ids: $ids) {\n id\n externalProductId\n externalVariantId\n additionalExternalProductId\n additionalExternalVariantId\n additionalIntegrationProduct {\n ...AdditionalIntegrationProductFields\n }\n product {\n id\n basePrice\n enabled\n minimumOrderQuantity\n name\n description\n partner {\n id\n name\n currencyCode\n customerDetailsPromptMarkdown\n }\n productImages {\n id\n precedence\n asset {\n key\n fileLink\n name\n type\n versions {\n name\n link\n }\n }\n }\n integrationProducts {\n id\n integration {\n id\n type\n }\n externalProductId\n externalVariantId\n additionalExternalProductId\n additionalExternalVariantId\n additionalIntegrationProduct {\n ...AdditionalIntegrationProductFields\n }\n }\n profanities {\n id\n word\n }\n sku\n skuCode\n weight\n workflows {\n id\n friendlyName\n isPresent\n workflowName\n imageUrl\n }\n imageUrl\n modelUrl\n overlayImageUrl\n preloadImageUrl\n promptForCustomerDetails\n conversionConfiguration {\n ...ConversionConfigurationFields\n }\n productTags {\n id\n name\n }\n priceBreaks {\n id\n minQty\n percentage\n }\n }\n integration {\n ...ActiveIntegrationFields\n }\n }\n }\n`;\n\nexport const readTransactionsQuery = gql`\n ${stakeholderFragment}\n ${transactionShareActionFragment}\n ${recipientFragment}\n query ReadTransactions($ids: [String]!) {\n transactions(ids: $ids) {\n customLogoLink\n designName\n externalDesignProductId\n externalDesignProductVariantId\n externalCartProductId\n externalCartProductVariantId\n id\n completed\n lastSyncedAt\n priceModifierTotal\n restApiIntegrationLink\n workflowFooterLogoLink\n workflowId\n workflowState\n workflowViewerLink\n workflowViewerReadOnlyLink\n previewImageLink\n isOrdered\n quantity\n printFileUrl1\n printFileUrl2\n printFileUrl3\n printFileUrl4\n printFileUrl5\n printFileName1\n printFileName2\n printFileName3\n printFileName4\n printFileName5\n stakeholders {\n ...StakeholderFields\n }\n currentStakeholder {\n ...StakeholderFields\n }\n hasAuthenticatedActions\n transactionShareActions {\n ...TransactionShareActionFields\n }\n addressValidationStatus\n recipient {\n ...RecipientFields\n }\n integrationProductId\n }\n }\n`;\n\nexport const updateTransactionWorkflowStateQuery = gql`\n mutation UpdateTransactionWorkflowState($id: String!, $workflowState: String!) {\n transactionUpdate(id: $id, workflowState: $workflowState) {\n id\n }\n }\n`;\n\nexport const updateTransactionQuantityQuery = gql`\n mutation UpdateTransactionQuantity($id: String!, $quantity: Int) {\n transactionUpdate(id: $id, quantity: $quantity) {\n id\n }\n }\n`;\n\nexport const updateTransactionWorkflowQuery = gql`\n mutation UpdateTransactionWorkflow($id: String!, $workflowId: String!) {\n transactionUpdate(id: $id, workflowId: $workflowId) {\n id\n }\n }\n`;\n\nexport const getConversionConfigurationQuery = gql`\n ${conversionConfigurationFragment}\n query ReadConversionConfigurationQuery($id: String!) {\n conversionConfiguration(id: $id) {\n ...ConversionConfigurationFields\n }\n }\n`;\n\nexport const getTransactionQuery = gql`\n ${conversionConfigurationFragment}\n query ReadTransactionForDesignCreation($id: String!) {\n transactions(ids: [$id]) {\n id\n completed\n createdAt\n designName\n product {\n name\n sku\n basePrice\n minimumOrderQuantity\n promptForCustomerDetails\n partner {\n id\n name\n customerDetailsPromptMarkdown\n }\n conversionConfiguration {\n ...ConversionConfigurationFields\n }\n productTags {\n id\n name\n }\n priceBreaks {\n id\n minQty\n percentage\n }\n }\n bundle {\n id\n metadata {\n key\n value\n }\n bundleStakeholders {\n type\n customer {\n emailAddress\n }\n }\n }\n externalCartProductId\n externalCartProductVariantId\n externalDesignProductId\n externalDesignProductVariantId\n lastSyncedAt\n previewImageLink\n priceModifierTotal\n quantity\n workflowId\n workflowState\n workflowViewerLink\n workflowViewerReadOnlyLink\n }\n }\n`;\n\nexport const getTransactionShareActionsQuery = gql`\n ${transactionShareActionFragment}\n query ReadTransactionForShareActions($id: String!) {\n transactions(ids: [$id]) {\n id\n hasAuthenticatedActions\n transactionShareActions {\n ...TransactionShareActionFields\n }\n }\n }\n`;\n\nexport const confirmWorkflowStates = gql`\n query ConfirmWorkflowStates($transactions: [TransactionConfirmInput!]!) {\n transactionConfirmWorkflowStates(transactions: $transactions)\n }\n`;\n\nconst getIntegrationProductFragment = (fetchIntegrationProducts?: boolean) => gql`\n ${additionalProductFragment}\n fragment IntegrationProductFields on IntegrationProduct {\n id\n externalProductId\n externalVariantId\n additionalExternalProductId\n additionalExternalVariantId\n additionalIntegrationProduct {\n ...AdditionalIntegrationProductFields\n }\n integration {\n id\n enabled\n externalIntegrationId\n type\n isCurrent\n }\n product {\n id\n basePrice\n enabled\n minimumOrderQuantity\n imageUrl\n modelUrl\n name\n description\n overlayImageUrl\n preloadImageUrl\n sku\n skuCode\n workflows {\n id\n index\n friendlyName\n isPresent\n workflowName\n imageUrl\n }\n productTags {\n id\n name\n }\n productImages {\n id\n precedence\n asset {\n key\n fileLink\n name\n type\n versions {\n name\n link\n }\n }\n }\n priceBreaks {\n id\n minQty\n percentage\n }\n ${\n fetchIntegrationProducts\n ? `\n integrationProducts {\n id\n externalProductId\n externalVariantId\n additionalExternalProductId\n additionalExternalVariantId\n additionalIntegrationProduct {\n ...AdditionalIntegrationProductFields\n }\n integration {\n id\n enabled\n externalIntegrationId\n type\n isCurrent\n }\n }\n `\n : \"\"\n }\n }\n }\n`;\n\nexport const getIntegrationProductsQuery = (includeIntegrations?: boolean) => gql`\n ${getIntegrationProductFragment(includeIntegrations)}\n query GetIntegrationProducts($ids: [String!]!) {\n integrationProducts(ids: $ids) {\n ...IntegrationProductFields\n }\n }\n`;\n\nexport const getIntegrationProductFromExternalIdsQuery = (includeIntegrations?: boolean) => gql`\n ${getIntegrationProductFragment(includeIntegrations)}\n query GetIntegrationProductFromExternalIds($externalIntegrationId: String!, $externalProductId: String!) {\n integrationProductFromExternalIds(\n externalIntegrationId: $externalIntegrationId\n externalProductId: $externalProductId\n ) {\n ...IntegrationProductFields\n }\n }\n`;\n\nexport const getTransactionStakeholdersQuery = gql`\n ${stakeholderFragment}\n query ReadTransactionForStakeholders($id: String!) {\n transactions(ids: [$id]) {\n stakeholders {\n ...StakeholderFields\n }\n currentStakeholder {\n ...StakeholderFields\n }\n }\n }\n`;\n\nexport const finalizeUpdateTransactionMutation = gql`\n mutation FinalizeUpdateTransaction($transactionId: String!) {\n transactionFinalizeUpdate(transactionId: $transactionId)\n }\n`;\n\nexport const regionFragment = gql`\n fragment RegionFields on Region {\n width\n top\n left\n height\n layer\n layerIndex\n rotation\n panelId\n immutable\n adjustmentBoundary {\n width\n x\n y\n height\n }\n }\n`;\n\nexport const lookAtAnimationFragment = gql`\n fragment LookAtAnimationFields on LookAtAnimation {\n latDeg\n lonDeg\n radius\n target {\n x\n y\n z\n }\n }\n`;\n\nexport const renderingPipelineConfigurationFragment = gql`\n fragment RenderingPipelineConfigurationFields on RenderingPipelineConfiguration {\n antiAliasing {\n samples\n fxaaEnabled\n }\n bloom {\n enabled\n kernel\n scale\n threshold\n weight\n }\n chromaticAberration {\n enabled\n aberrationAmount\n direction {\n x\n y\n }\n radialIntensity\n }\n colorCurves {\n enabled\n globalDensity\n globalExposure\n globalHue\n globalSaturation\n highlightsDensity\n highlightsExposure\n highlightsHue\n highlightsSaturation\n midtonesDensity\n midtonesExposure\n midtonesHue\n midtonesSaturation\n shadowsDensity\n shadowsExposure\n shadowsHue\n shadowsSaturation\n }\n depthOfField {\n enabled\n blurLevel\n focusDistance\n focalLength\n fStop\n lensSize\n }\n grain {\n enabled\n animated\n intensity\n }\n misc {\n contrast\n exposure\n toneMappingEnabled\n toneMappingType\n }\n sharpen {\n enabled\n colorAmount\n edgeAmount\n }\n vignette {\n enabled\n blendMode\n cameraFov\n center {\n x\n y\n }\n colorRgba {\n r\n g\n b\n a\n }\n colorHex\n stretch\n weight\n }\n }\n`;\n\nexport const modelAnimationFragment = gql`\n fragment ModelAnimationFields on ModelAnimation {\n from\n to\n loop\n name\n }\n`;\n\nexport const getWorkflowsQuery = (includeAssetMetadata: boolean) => {\n return gql`\n ${assetFragment(includeAssetMetadata)}\n ${optionMinimalFragment}\n ${regionFragment}\n ${lookAtAnimationFragment}\n ${renderingPipelineConfigurationFragment}\n ${modelAnimationFragment}\n query GetWorkflows($ids: [String!]!) {\n workflows(ids: $ids) {\n partner {\n termsMarkdown\n }\n allowProofDownload\n defaultPreviewPanelIndex\n finalizeStepConfig {\n termsMarkdown\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n }\n globalPreviewConfig {\n autoRotation\n backgroundColor\n backgroundImage\n clearColor\n disableActionBar\n disableAutomaticOrientation\n emissiveGlowIntensity\n enableAR\n environmentFile\n environmentIntensity\n environmentRotationY\n idleTimeBeforeRotation\n lowerAlphaLimitDeg\n lowerBetaLimitDeg\n maxZoomOverride\n minZoomOverride\n noPan\n upperAlphaLimitDeg\n upperBetaLimitDeg\n renderingPipelineConfiguration {\n ...RenderingPipelineConfigurationFields\n }\n }\n id\n name\n panels {\n editableArea {\n height\n width\n x\n y\n }\n height\n width\n index\n name\n title\n useEditableArea\n transparentBackground\n previewRegion {\n ...RegionFields\n }\n }\n previewAsset {\n ...AssetFields\n }\n showModelOnFinishStep\n showPlusInVariantPrices\n showPricing\n skuCode\n stepGroups {\n name\n stepNames\n }\n steps {\n stepName\n type\n tags\n globalPropertyAspectConfigurations {\n aspectName\n globalPropertyConfigurationId\n }\n conversionConfigurationFieldLinks {\n identifier\n conversionConfigurationId\n }\n overrideDefaultVariantId\n option {\n ...OptionMinimalFields\n }\n stepTitle\n helpText\n mandatory\n relevantPanelName\n silent\n conditions {\n requiredVariantSelections\n targetStepName\n action\n }\n data {\n __typename\n ... on InformationStepData {\n content\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n }\n ... on DigitalContentStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n baseUrl\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n regions {\n ...RegionFields\n }\n }\n ... on FrameStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n colorOption {\n ...OptionMinimalFields\n }\n colorPickerEnabled\n initialZoomLevel\n disablePlaceholder\n displayImageOnFinishStep\n displaySelectionOnFinishStep\n forceImageCover\n hideImageInCart\n hideSelectionInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n maxColors\n modelAnimation {\n ...ModelAnimationFields\n }\n overlayImageKey\n overlayImageUrl\n placeholderImageKey\n placeholderImageUrl\n regions {\n ...RegionFields\n }\n whitelistedExtensions\n }\n ... on IllustrationStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n colorOption {\n ...OptionMinimalFields\n }\n colorPickerEnabled\n pmsPickerEnabled\n displayColorsOnFinishStep\n displaySelectionOnFinishStep\n enableVariantSearch\n hideColorsInCart\n hideSelectionInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n regions {\n ...RegionFields\n }\n }\n ... on MaterialStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n displaySelectionOnFinishStep\n hideSelectionInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n targetMaterials\n }\n ... on ModelStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n displaySelectionOnFinishStep\n hideSelectionInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n replaceProductModel\n }\n ... on ModuleStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n displayTextOnFinishStep\n hideTextInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n maxLength\n modelAnimation {\n ...ModelAnimationFields\n }\n module\n regions {\n ...RegionFields\n }\n }\n ... on PictureStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n displaySelectionOnFinishStep\n enableVariantSearch\n hideSelectionInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n regions {\n ...RegionFields\n }\n }\n ... on ProductOverlayStepData {\n regions {\n ...RegionFields\n }\n overlayType\n }\n ... on QuestionStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n allowMultipleSelections\n displaySelectionsOnFinishStep\n displayType\n hideSelectionsInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n }\n ... on ShapeStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n displaySelectionOnFinishStep\n excludeFromPrint\n hideSelectionInCart\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n regions {\n ...RegionFields\n }\n }\n ... on SilentIllustrationStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n asset {\n ...AssetFields\n }\n excludeFromPrint\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n modelAnimation {\n ...ModelAnimationFields\n }\n regions {\n ...RegionFields\n }\n }\n ... on TextStepData {\n advancedEditorAnimation {\n x\n y\n zoom\n layoutName\n }\n allowNewlines\n colorOption {\n ...OptionMinimalFields\n }\n colorPickerEnabled\n curved\n defaultText\n deleteDefaultOnFocus\n displayColorOnFinishStep\n displayImageFillOnFinishStep\n displayStrokeOnFinishStep\n displayTextOnFinishStep\n hideColorInCart\n hideImageFillInCart\n hideSelectionInCart\n hideStrokeInCart\n hideTextInCart\n imageFillOption {\n ...OptionMinimalFields\n }\n imageFillScale\n lookAtAnimation {\n ...LookAtAnimationFields\n }\n maxLength\n maxSize\n minSize\n modelAnimation {\n ...ModelAnimationFields\n }\n paths\n regions {\n ...RegionFields\n }\n replaceableText\n size\n strokeEnabled\n strokeOption {\n ...OptionMinimalFields\n }\n strokeThickness\n textAlign\n uppercase\n userCanReplaceText\n vertical\n verticalAlign\n }\n }\n }\n }\n }\n `;\n};\n\nconst marketplaceThemeInstallConfigurationFragment = gql`\n ${conversionConfigurationFragment}\n fragment MarketplaceThemeInstallConfigurationFields on MarketplaceThemeInstallConfiguration {\n id\n themeInstallId\n fields {\n type\n key\n value\n asset {\n key\n name\n fileLink\n type\n }\n conversionConfiguration {\n ...ConversionConfigurationFields\n }\n listValues\n objectValues\n schema\n root\n }\n themeVersion {\n id\n version\n status\n createdAt\n updatedAt\n launchData {\n targetFiles {\n filename\n type\n mimeType\n fileLink\n preload\n }\n }\n configurationSchema {\n customSchemas {\n name\n type\n title\n fields\n extends\n schemas\n }\n fields {\n key\n type\n title\n required\n defaultValue\n options {\n key\n value\n }\n assetType\n multiLine\n limit\n items\n fields\n schema\n root\n }\n }\n }\n }\n`;\n\nexport const getMarketplaceThemeInstallConfigurationQuery = gql`\n ${marketplaceThemeInstallConfigurationFragment}\n query GetMarketplaceThemeInstallConfiguration($themeConfigurationId: String!, $themeInstallId: String!) {\n marketplaceThemeInstallConfiguration(id: $themeConfigurationId, themeInstallId: $themeInstallId, raw: false) {\n ...MarketplaceThemeInstallConfigurationFields\n }\n }\n`;\n\nexport const currentIntegrationQuery = gql`\n ${activeIntegrationFragment}\n ${marketplaceThemeInstallConfigurationFragment}\n query GetCurrentIntegration($themeConfigurationId: String) {\n currentIntegration {\n id\n type\n marketplaceThemeInstallConfiguration(id: $themeConfigurationId, raw: false) {\n ...MarketplaceThemeInstallConfigurationFields\n }\n ...ActiveIntegrationFields\n }\n }\n`;\n\nexport const getTransactionForMarketplaceThemeQuery = gql`\n ${marketplaceThemeInstallConfigurationFragment}\n query ReadTransactionForMarketplaceTheme($id: String!) {\n transactions(ids: [$id]) {\n marketplaceThemeInstallConfiguration(raw: false) {\n ...MarketplaceThemeInstallConfigurationFields\n }\n }\n }\n`;\n\nexport const getBundleForMarketplaceThemeQuery = gql`\n ${marketplaceThemeInstallConfigurationFragment}\n query ReadBundleForMarketplaceTheme($id: String!) {\n bundles(ids: [$id]) {\n marketplaceThemeInstallConfiguration(raw: false) {\n ...MarketplaceThemeInstallConfigurationFields\n }\n }\n }\n`;\n\nexport const createOrderMutation = gql`\n mutation CreateOrder($orderItems: [OrderItemInput]!) {\n orderCreate(orderItems: $orderItems, paid: false, generateInternalId: true) {\n id\n internalId\n }\n }\n`;\n\nexport const currencyConversionQuery = gql`\n query CurrencyConversion($from: String!, $to: String!) {\n currencyConversion(from: $from, to: $to) {\n rateFrom\n rateTo\n timestamp\n }\n }\n`;\n","import { OptionResource, optionService } from \"../..\";\nimport { AnyStepData, Step, StepGroup, StepSelections, StepType, Workflow } from \"../../types\";\n\n/**\n * A renderable scene is a scene that can be displayed to the user. This is based on the workflow state.\n */\nexport interface RenderableScene {\n /**\n * The id of the scene.\n */\n id: string;\n /**\n * The title of the scene.\n */\n title: string;\n /**\n * The id of each step inside the scene that can be rendered. This is based on the workflow state.\n */\n renderableSteps: string[];\n /**\n * The WorkflowScene representation of this object. Provided for backwards compatibility.\n * @deprecated\n */\n workflowScene: WorkflowScene;\n}\n\n/**\n * Information parsed froma workflow structure that is relevant\n * to a given scene.\n */\nexport interface WorkflowScene {\n /**\n * A unique identifier for the scene.\n */\n name: string;\n /**\n * A human-readable title for the scene.\n */\n title: string;\n /**\n * Steps which can display to the user.\n * But may be conditionally hidden based on workflow logic\n */\n renderableSteps: Step<AnyStepData>[];\n /**\n * Steps which don't display to the user.\n * Their behavior is always silent & executed in the background.\n * @deprecated Silent steps are no longer handled seperately from normal steps.\n */\n silentSteps: Step<AnyStepData>[];\n}\n\n/**\n * @deprecated All steps can now be silent. It will take a long time to transition away from this approach though. Including potentially more dev work.\n */\nexport const silentStepTypes = [StepType.SilentIllustration, StepType.ProductOverlay];\n\n/**\n * Gets all scenes in the workflow structured in a way that makes it easier for us to track current state.\n * FIXME: renderableSteps in the response from this function have a different meaning to renderableSteps in getRenderableRelevantScenes and others.\n * FIXME: silentSteps will be removed in the future. They will be treating like other steps & not a special case moving forwards.\n * @param workflow The workflow to get scenes for.\n * @returns A list of scenes containing\n */\nconst getAllScenes = (workflow: Workflow): WorkflowScene[] => {\n const scenes: WorkflowScene[] = [];\n\n // For each step in the workflow,\n // check if it belongs to a group.\n // If not then stick it in its own scene.\n // If it does then look for a scene with the group's name.\n // Stick it in that scene if you find it, otherwise make a new scene.\n for (const step of workflow.steps) {\n const group = findGroupForStep(step.stepName, workflow.stepGroups);\n if (!group)\n throw new Error(\n \"Workflow step does not belong to a group, all steps must belong to a group. Step: \" + step.stepName,\n );\n const existingScene = scenes.find((scene) => scene.name === group.name);\n if (existingScene) {\n if (silentStepTypes.includes(step.type)) {\n existingScene.silentSteps.push(step);\n } else {\n existingScene.renderableSteps.push(step);\n }\n } else {\n scenes.push({\n name: group.name,\n title: group.name,\n renderableSteps: silentStepTypes.includes(step.type) ? [] : [step],\n silentSteps: silentStepTypes.includes(step.type) ? [step] : [],\n });\n }\n }\n\n // Add the finish step.\n const finishSceneTitle = \"workflow.steps.finish.confirmDesign\";\n scenes.push({\n name: \"Finish\",\n title: finishSceneTitle,\n renderableSteps: [\n {\n type: StepType.Finish,\n stepName: \"Finish\",\n stepTitle: finishSceneTitle,\n helpText: \"\",\n data: {\n modelAnimation: workflow.finalizeStepConfig\n ? workflow.finalizeStepConfig.modelAnimation\n : undefined,\n lookAtAnimation: workflow.finalizeStepConfig\n ? workflow.finalizeStepConfig.lookAtAnimation\n : undefined,\n },\n conditions: [],\n },\n ],\n silentSteps: [],\n });\n\n return scenes;\n};\n\n/**\n * Find the scene relating to a step\n * @param stepName The step ID.\n * @param stepGroups The list of scenes.\n * @returns Scene if found or undefined.\n */\nconst findGroupForStep = (stepName: string, stepGroups: StepGroup[]): StepGroup | undefined => {\n return stepGroups.find((group) => group.stepNames.includes(stepName));\n};\n\n/**\n * Determines whether a step is conditionally active.\n * @param step A step to check.\n * @param stepSelections The current customer selections.\n * @returns Returns true when the step is conditionally active. False otherwise.\n */\nconst stepConditionsAreSatisfied = (step: Step<AnyStepData>, stepSelections: StepSelections): boolean => {\n // Currently all conditions must be met (AND), we should allow for OR of conditions as well.\n return (step.conditions || []).every((condition) => {\n const originatingStepData = stepSelections[condition.targetStepName];\n if (originatingStepData && originatingStepData.selectedVariants) {\n const selectedVariants = originatingStepData.selectedVariants;\n return condition.requiredVariantSelections.some(\n (reqVariant) => selectedVariants.find((selVariant) => selVariant.id === reqVariant) !== undefined,\n );\n }\n return false;\n });\n};\n\n/**\n * Filters out steps that are not conditionally active.\n * @param scene The scene to filter.\n * @param stepSelections The current customer selections.\n * @returns A scene with only conditionally active steps. If all steps have been filtered out we return null.\n */\nconst filterSceneByConditions = (scene: WorkflowScene, stepSelections: StepSelections): WorkflowScene | null => {\n const filteredScene: WorkflowScene = {\n name: scene.name,\n title: scene.title,\n renderableSteps: scene.renderableSteps.filter((step) => stepConditionsAreSatisfied(step, stepSelections)),\n silentSteps: scene.silentSteps.filter((step) => stepConditionsAreSatisfied(step, stepSelections)),\n };\n if (filteredScene.silentSteps.length === 0 && filteredScene.renderableSteps.length === 0) {\n return null;\n }\n return filteredScene;\n};\n\n/**\n * Used to understand what scenes contain active steps.\n * @param allScenes All scenes in the workflow.\n * @param stepSelections The current customer selections.\n * @returns A list of scenes that contain at least one conditionally active step.\n */\nconst getActiveScenes = (allScenes: WorkflowScene[], stepSelections: StepSelections): WorkflowScene[] => {\n return allScenes\n .map((scene) => filterSceneByConditions(scene, stepSelections))\n .filter((scene) => scene !== null) as WorkflowScene[];\n};\n\n/**\n * This function is only used to drive what steps are visible for the user.\n * NOTE: Do not use this function to apply internal workflow logic like loading/unloading steps. As a renderable step may still need to be loaded/unloaded.\n * @param allScenes All scenes in the workflow.\n * @param stepSelections The current customer selections.\n * @param singleVariantsRenderable When true the function will return steps that have a single variant.\n * @returns A list of scenes & steps inside them that are renderable to the customer.\n */\nconst getRenderableRelevantScenes = async (\n allScenes: WorkflowScene[],\n stepSelections: StepSelections,\n singleVariantsRenderable: boolean = false,\n): Promise<WorkflowScene[]> => {\n const activeScenes = getActiveScenes(allScenes, stepSelections);\n\n // Evaluate each step\n const stepsWithRenderableConfiguration: string[] = [];\n for (const scene of activeScenes) {\n for (const step of scene.renderableSteps) {\n let variantAmount = 0;\n if (step.type !== \"Finish\" && step.type !== \"Module\") {\n let option: OptionResource | undefined = undefined;\n if (step.option?.variants) {\n option = step.option;\n variantAmount = option?.variants?.length || 0;\n } else {\n option = await optionService.getOption(step.option?.id!);\n variantAmount = option?.variants?.length || 0;\n }\n }\n\n if (step.silent) {\n continue;\n }\n /**\n * Silent steps are now possible on any step in the system.\n * Let's move towards removing this code.\n * FIXME: Once ops are happy we have marked required steps silent. Remove.\n */\n if (\n step.type === StepType.Model ||\n step.type === StepType.Material ||\n step.type === StepType.Picture ||\n step.type === StepType.Shape\n ) {\n if (variantAmount > 1 || singleVariantsRenderable) stepsWithRenderableConfiguration.push(step.stepName);\n } else {\n stepsWithRenderableConfiguration.push(step.stepName);\n }\n }\n }\n // Filter out scenes that don't have any renderable steps.\n const renderableScenes = activeScenes.filter((scene) => {\n const filteredScene = scene.renderableSteps.filter((step: Step<AnyStepData>) =>\n stepsWithRenderableConfiguration.includes(step.stepName),\n );\n return filteredScene.length > 0;\n });\n\n // Filter out unrenderable steps from the scenes.\n for (const renderableScene of renderableScenes) {\n renderableScene.renderableSteps = renderableScene.renderableSteps.filter((step: Step<AnyStepData>) =>\n stepsWithRenderableConfiguration.includes(step.stepName),\n );\n }\n\n return renderableScenes;\n};\n\nexport { getAllScenes, getActiveScenes, getRenderableRelevantScenes, stepConditionsAreSatisfied };\n","/**\n * A queue promise is a container for a promise that can be\n * executed at a later time.\n */\nexport abstract class QueueablePromise {\n readonly timestamp = Date.now();\n abstract execute(): Promise<any>;\n}\n\n/**\n * A promise queue contains any number of QueuePromise objects. These objects are stored within a PromiseQueue and executed\n * as quickly as possible in order. This is ideal in situations where a specific operation should be\n * applied in an ordered way while still making.\n */\nexport class PromiseQueue<T extends QueueablePromise> {\n private queue: T[] = [];\n private activePromise?: Promise<void> = undefined;\n private queueMaxSize: number | undefined = undefined;\n private isEnabled: boolean;\n\n /**\n * Constructs a new promise queue.\n * @param queueMaxSize An optional maximum size, when the max size is hit.\n * The older promises will be discarded.\n * @param enabled When false, the queue will not process any jobs. Assign `enabled` to true to start processing.\n */\n constructor(queueMaxSize?: number, enabled = true) {\n this.queueMaxSize = queueMaxSize;\n this.isEnabled = enabled;\n }\n\n /**\n * Enqueue a new promise.\n * @param promise A new promise to add to the queue.\n */\n enqueue(promise: T) {\n this.queue.push(promise);\n\n // If configured to do so, let's ensure the queue cannot grow too large by removing\n // older unprocessed work. This is great in situations where we know promises are\n // enqueued often and only the latest promises need to be executed.\n if (this.queueMaxSize !== undefined && this.queue.length > this.queueMaxSize) {\n const queueLength = this.queue.length - 1;\n for (let i = 0; i < queueLength; ++i) {\n this.queue.shift();\n }\n }\n\n if (!this.isEnabled) {\n return;\n }\n\n // If there's an active processing promise, it'll be picked up alongside the existing work.\n if (this.activePromise) {\n return;\n }\n // Otherwise we create a promise to handle this.\n this.activePromise = this.dequeue();\n }\n\n get enabled() {\n return this.isEnabled;\n }\n\n /**\n * Enable or disable the queue. When disabled, the queue will not process any jobs.\n * Disabling processing will not cancel any active promises.\n */\n set enabled(value: boolean) {\n if (!this.isEnabled && value && !this.activePromise && this.getRemainingQueueSize() > 0) {\n this.activePromise = this.dequeue();\n }\n this.isEnabled = value;\n }\n\n /**\n * @returns Returns true when work is being actively processed by this queue.\n */\n hasActivePromise() {\n return !!this.activePromise;\n }\n\n /**\n * @returns The number of unexecuted jobs remaining in the queue. Not including the active job.\n */\n getRemainingQueueSize() {\n return this.queue.length;\n }\n\n /**\n * Finalize the queue, any jobs that come in while this is in progress will result\n * in the promise being extended.\n */\n async finalize() {\n if (this.activePromise) return this.activePromise;\n return Promise.resolve();\n }\n\n /**\n * Once called will recursively resolve the jobs in the\n * queue until no more are available.\n */\n private async dequeue() {\n const item = this.queue.shift();\n // Is the queue empty.\n if (!item) {\n this.activePromise = undefined;\n return;\n }\n // Execute & process remaining messages.\n try {\n await item.execute();\n } catch (err) {\n console.log(err);\n } finally {\n await this.dequeue();\n }\n }\n}\n","export const generate = (): string => {\n const s4 = () => {\n return Math.floor((1 + Math.random()) * 0x10000)\n .toString(16)\n .substring(1);\n };\n return s4() + s4() + \"-\" + s4() + \"-\" + s4() + \"-\" + s4() + \"-\" + s4() + s4() + s4();\n};\n","import { LayoutElement, LayoutRenderingPurpose, PapyrusComponent, RenderingConfiguration } from \"../types\";\nimport { generate } from \"../util/guid\";\nimport { sortElementsByLayersWithIndex, elementFactory } from \"../CommandContext\";\n\nexport interface SVGLayoutProps {\n configuration: RenderingConfiguration;\n preserveAspectRatio?: string;\n outlineArea?: {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n scale?: number;\n hidden?: boolean; // When set the editable area will not be stroke. The mask will still take effect.\n };\n viewBox?: { x: number; y: number; width: number; height: number };\n width: number | string;\n height: number | string;\n position?: string;\n maxWidth?: string;\n maxHeight?: string;\n elements: LayoutElement[];\n backgroundColor?: string;\n outlineColor?: string;\n omitBoundClipping?: boolean;\n borderRadius?: number;\n}\n\nexport const SVGLayout: PapyrusComponent<SVGLayoutProps> = ({\n backgroundColor,\n outlineColor,\n borderRadius,\n configuration,\n elements,\n height,\n maxHeight,\n maxWidth,\n outlineArea,\n position,\n preserveAspectRatio,\n viewBox,\n width,\n}) => {\n const rx = borderRadius || 0;\n const strokeScale = 2 * (outlineArea?.scale || 1);\n const calculatedViewbox = viewBox || { x: 0, y: 0, width, height };\n const viewboxString = `${calculatedViewbox.x} ${calculatedViewbox.y} ${calculatedViewbox.width} ${calculatedViewbox.height}`;\n const maskId = generate();\n\n const defs = configuration.purpose === LayoutRenderingPurpose.FreeDesign && (\n <defs>\n <clipPath id=\"viewboxClip\">\n <rect width={calculatedViewbox.width} height={calculatedViewbox.height} rx={rx} />\n </clipPath>\n </defs>\n );\n\n const colorProfileElements = configuration.colorProfiles?.map((c, index) => {\n // Color profiles have no typescript definition. We tell the compiler to ignore their lack of existance.\n return (\n /* @ts-ignore */\n <color-profile key={index} name={c.name} xlinkHref={c.key}>\n {\" \"}\n {/* @ts-ignore */}\n </color-profile>\n );\n });\n\n // Mixin the rendering configuration if required\n const elementsWithConfiguration = elements.map((el) => {\n return {\n ...el,\n _renderingConfiguration: configuration,\n mask: outlineArea ? `url(#viewmask-${maskId})` : undefined,\n };\n });\n\n // Order the elements based on layer & index\n const sortedElements = sortElementsByLayersWithIndex(elementsWithConfiguration);\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlnsXlink=\"http://www.w3.org/1999/xlink\"\n xmlSpace=\"preserve\"\n version=\"1.1\"\n preserveAspectRatio={preserveAspectRatio}\n width={width}\n height={height}\n style={{\n gridColumn: 1,\n gridRow: 1,\n maxWidth,\n maxHeight,\n position: position as any,\n }}\n viewBox={viewboxString}\n >\n {colorProfileElements}\n {defs}\n {!!backgroundColor && (\n <rect\n id=\"layout-background\"\n width={calculatedViewbox.width}\n height={calculatedViewbox.height}\n fill={backgroundColor}\n rx={rx}\n />\n )}\n <g\n id=\"element-group\"\n clipPath={configuration.purpose === LayoutRenderingPurpose.FreeDesign ? \"url(#viewboxClip)\" : undefined}\n >\n {sortedElements.map((el) => elementFactory(el)).filter((el) => !!el)}\n </g>\n {outlineArea && (\n <rect\n x={outlineArea.x}\n y={outlineArea.y}\n width={outlineArea.width}\n height={outlineArea.height}\n fill=\"none\"\n stroke={outlineArea.hidden ? \"none\" : outlineColor ? outlineColor : \"#aaaaaa\"}\n strokeWidth={strokeScale / 2}\n strokeDasharray={`${strokeScale * 2} ${strokeScale}`}\n />\n )}\n {outlineArea && (\n <mask id={`viewmask-${maskId}`}>\n <rect\n x={calculatedViewbox.x}\n y={calculatedViewbox.y}\n width={calculatedViewbox.width}\n height={calculatedViewbox.height}\n fill=\"black\"\n />\n <rect\n x={outlineArea.x}\n y={outlineArea.y}\n width={outlineArea.width}\n height={outlineArea.height}\n fill=\"white\"\n />\n </mask>\n )}\n </svg>\n );\n};\n","import { LayoutElement, Point, ScaleAxis } from \"../types\";\n\n/**\n * Returns an axis aligned bounding box for a given element.\n * @param element The element to calculate an AABB for.\n * @returns The AABB for the element.\n */\nconst getAxisAlignedBoundingBox = (x: number, y: number, width: number, height: number, rotation: number) => {\n const rotationRadians = degreesToRadians(rotation);\n\n const halfX = width / 2;\n const halfY = height / 2;\n\n const midX = x + halfX;\n const midY = y + halfY;\n\n const sin = Math.sin(rotationRadians);\n const cos = Math.cos(rotationRadians);\n\n const c1x = halfX;\n const c2x = halfX;\n const c1y = -halfY;\n const c2y = halfY;\n\n const transformedC1X = c1x * cos - c1y * sin;\n const transformedC2X = c2x * cos - c2y * sin;\n const transformC1Y = c1x * sin + c1y * cos;\n const transformedC2Y = c2x * sin + c2y * cos;\n\n const extentX = Math.max(Math.abs(transformedC1X), Math.abs(transformedC2X));\n const extentY = Math.max(Math.abs(transformC1Y), Math.abs(transformedC2Y));\n\n return {\n minX: midX - extentX,\n maxX: midX + extentX,\n minY: midY - extentY,\n maxY: midY + extentY,\n };\n};\n\n// Returns angle ABC, between lines AB and BC\nconst findAngle = (a: Point, b: Point, c: Point) => {\n const ab = Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2));\n const bc = Math.sqrt(Math.pow(b.x - c.x, 2) + Math.pow(b.y - c.y, 2));\n const ac = Math.sqrt(Math.pow(c.x - a.x, 2) + Math.pow(c.y - a.y, 2));\n return Math.acos((bc * bc + ab * ab - ac * ac) / (2 * bc * ab)) * (180 / Math.PI);\n};\n\n/**\n * Degrees to radians.\n * @param degrees An angle in degrees.\n * @returns The equivelant angle in radians.\n */\nconst degreesToRadians = (degrees: number) => {\n return degrees * (Math.PI / 180);\n};\n\n/**\n * Radians to degrees.\n * @param radians An angle in radians.\n * @returns The equivelant angle in degrees.\n */\nconst radiansToDegrees = (radians: number) => {\n return radians * (180 / Math.PI);\n};\n\n/**\n * @param a The first value.\n * @param b The second value.\n * @returns Returns true if two values are within a distance to each other.\n */\nconst isCloseToValue = (a: number, b: number, allowableDistance: number) => {\n const diff = Math.abs(a - b);\n return diff < allowableDistance;\n};\n\nconst getTrueCoordinates = (point: Point, pointOfRotation: Point, rotation: number): Point => {\n const s = Math.sin(degreesToRadians(rotation));\n const c = Math.cos(degreesToRadians(rotation));\n return {\n x: (point.x - pointOfRotation.x) * c - (point.y - pointOfRotation.y) * s + pointOfRotation.x,\n y: (point.x - pointOfRotation.x) * s + (point.y - pointOfRotation.y) * c + pointOfRotation.y,\n };\n};\n\nconst getPointOfRotation = (nwPoint: Point, sePoint: Point): Point => {\n return {\n x: (nwPoint.x + sePoint.x) / 2,\n y: (nwPoint.y + sePoint.y) / 2,\n };\n};\n\nconst getNWPoint = (bounds: DOMRect, element: LayoutElement, scaleX: number, scaleY: number): Point => {\n return {\n x: bounds.x + element?.x * scaleX,\n y: bounds.y + element?.y * scaleY,\n };\n};\n\nconst getNEPoint = (bounds: DOMRect, element: LayoutElement, scaleX: number, scaleY: number): Point => {\n return {\n x: bounds.x + (element?.x + element?.width) * scaleX,\n y: bounds.y + element?.y * scaleY,\n };\n};\n\nconst getSWPoint = (bounds: DOMRect, element: LayoutElement, scaleX: number, scaleY: number): Point => {\n return {\n x: bounds.x + element?.x * scaleX,\n y: bounds.y + (element?.y + element?.height) * scaleY,\n };\n};\n\nconst getSEPoint = (bounds: DOMRect, element: LayoutElement, scaleX: number, scaleY: number): Point => {\n return {\n x: bounds.x + (element?.x + element?.width) * scaleX,\n y: bounds.y + (element?.y + element?.height) * scaleY,\n };\n};\n\n// Compass directions\n\nconst turnRightClockwise = (dir: ScaleAxis): ScaleAxis => {\n switch (dir) {\n case ScaleAxis.North:\n return ScaleAxis.East;\n case ScaleAxis.East:\n return ScaleAxis.South;\n case ScaleAxis.South:\n return ScaleAxis.West;\n case ScaleAxis.West:\n return ScaleAxis.North;\n case ScaleAxis.Northwest:\n return ScaleAxis.Northeast;\n case ScaleAxis.Northeast:\n return ScaleAxis.Southeast;\n case ScaleAxis.Southeast:\n return ScaleAxis.Southwest;\n case ScaleAxis.Southwest:\n return ScaleAxis.Northwest;\n }\n};\n\n// The (semi-)cardinal direction that you are currently facing if\n// you turned the given rotation from the given orignal direction.\nconst currentDirection = (originalDirection: ScaleAxis, rotation: number): ScaleAxis => {\n if (rotation > 45 && rotation <= 135) {\n return turnRightClockwise(originalDirection);\n }\n if (rotation > 135 && rotation <= 225) {\n return turnRightClockwise(turnRightClockwise(originalDirection));\n }\n if (rotation > 225 && rotation <= 315) {\n return turnRightClockwise(turnRightClockwise(turnRightClockwise(originalDirection)));\n }\n return originalDirection;\n};\n\n/**\n * Computes helpful values about a rotated element, Useful in calculating updated element locations.\n * @param element The element to calculate the vertices for.\n * @returns a, b, c, d starting from top left and moving clockwise. Center represents the point central to\n * all vertices on thge element.\n */\nconst getElementVertices = (\n element: { x: number; y: number; width: number; height: number; rotation: number },\n canvasBounds: Point = { x: 0, y: 0 },\n scale: Point = { x: 1, y: 1 },\n) => {\n const radians = degreesToRadians(element.rotation);\n\n // Find the unrotated vertices of the element. We'll rotate\n // these later to find the rotated vertices.\n\n const unrotatedTopLeft: Point = {\n x: canvasBounds.x + element.x * scale.x,\n y: canvasBounds.x + element.y * scale.y,\n };\n\n const unrotatedTopRight: Point = {\n x: element.x + element.width,\n y: element.y,\n };\n\n const unrotatedBottomRight: Point = {\n x: canvasBounds.x + (element.x + element.width) * scale.x,\n y: canvasBounds.y + (element.height + element.y) * scale.y,\n };\n\n const unrotatedBottomLeft: Point = {\n x: canvasBounds.x + element.x * scale.x,\n y: canvasBounds.y + (element.height + element.y) * scale.y,\n };\n\n // Find the center point of the element.\n // This will be the point that the element rotates on.\n const pointOfRotation: Point = {\n x: (unrotatedBottomLeft.x + unrotatedBottomRight.x) / 2,\n y: unrotatedBottomLeft.y - (element.height * scale.y) / 2,\n };\n\n // Find the actual coordinates of the element's bottom corners by translating to the origin,\n // rotating as required and translating back to current position.\n return {\n a: rotateAroundPoint(unrotatedTopLeft, pointOfRotation, radians),\n b: rotateAroundPoint(unrotatedTopRight, pointOfRotation, radians),\n c: rotateAroundPoint(unrotatedBottomRight, pointOfRotation, radians),\n d: rotateAroundPoint(unrotatedBottomLeft, pointOfRotation, radians),\n center: pointOfRotation,\n };\n};\n\n/**\n * Rotates a point around another point by an angle.\n * @param p The point to rotate.\n * @param c The point to rotate around..\n * @param angleRadians The angle to rotate.\n * @returns A new point transformed by the rotation.\n */\nconst rotateAroundPoint = (p: Point, c: Point, angleRadians: number) => {\n const sin = Math.sin(angleRadians);\n const cos = Math.cos(angleRadians);\n return {\n x: (p.x - c.x) * cos - (p.y - c.y) * sin + c.x,\n y: (p.x - c.x) * sin + (p.y - c.y) * cos + c.y,\n };\n};\n\nexport {\n currentDirection,\n degreesToRadians,\n findAngle,\n getAxisAlignedBoundingBox,\n getNEPoint,\n getNWPoint,\n getPointOfRotation,\n getSEPoint,\n getSWPoint,\n getTrueCoordinates,\n isCloseToValue,\n radiansToDegrees,\n turnRightClockwise,\n getElementVertices,\n rotateAroundPoint,\n};\n\n// All conversion constants are based on 72dpi\nexport const mmPerPixel = 0.352778;\nexport const cmPerPixel = 0.035277;\n","import { ImageElement, PapyrusComponent } from \"../types\";\nimport { degreesToRadians } from \"../util/math\";\n\nexport const Image: PapyrusComponent<Omit<ImageElement, \"type\">> = (props) => {\n const rotation = props.rotation || 0;\n const angleInRadians = degreesToRadians(rotation);\n const rotC = Math.cos(angleInRadians);\n const rotS = -Math.sin(angleInRadians);\n\n return (\n <g mask={props.stepName || props.productOverlay ? undefined : props.mask}>\n <g\n transform={`\n matrix(1, 0, 0, 1, ${props.x}, ${props.y})\n matrix(1, 0, 0, 1, ${props.width / 2}, ${props.height / 2})\n matrix(${rotC}, ${-rotS}, ${rotS}, ${rotC}, 0, 0)\n matrix(1, 0, 0, 1, ${-props.width / 2}, ${-props.height / 2})\n `}\n >\n <image\n xlinkHref={props.src}\n preserveAspectRatio={props.preserveAspectRatio}\n width={props.width}\n height={props.height}\n />\n </g>\n </g>\n );\n};\n","import { GroupElement, LayoutElement, PapyrusComponent } from \"../types\";\nimport { degreesToRadians } from \"../util/math\";\nimport { elementFactory, sortElementsByLayersWithIndex } from \"../CommandContext\";\n\nexport const Group: PapyrusComponent<Omit<GroupElement, \"type\">> = (props) => {\n const clipPathId = `spiff-group-clip-${props.id}`;\n const rotation = props.rotation || 0;\n const angleInRadians = degreesToRadians(rotation);\n const rotC = Math.cos(angleInRadians);\n const rotS = -Math.sin(angleInRadians);\n const sortedElements = sortElementsByLayersWithIndex(props.children);\n const buildDefinitions = () => {\n return (\n <clipPath id={clipPathId} preserveAspectRatio=\"none\">\n {props.clipPath ? (\n <path d={props.clipPath} />\n ) : (\n <rect x={0} y={0} width={props.width} height={props.height} />\n )}\n </clipPath>\n );\n };\n\n return (\n <>\n <defs>{buildDefinitions()}</defs>\n <g\n transform={`\n matrix(1, 0, 0, 1, ${props.x}, ${props.y})\n matrix(1, 0, 0, 1, ${props.width / 2}, ${props.height / 2})\n matrix(${rotC}, ${-rotS}, ${rotS}, ${rotC}, 0, 0)\n matrix(1, 0, 0, 1, ${-props.width / 2}, ${-props.height / 2})\n `}\n >\n {props._renderingConfiguration?.debug ? (\n <rect\n stroke=\"red\"\n opacity={0.3}\n fill=\"none\"\n x={0}\n y={0}\n width={props.width}\n height={props.height}\n />\n ) : undefined}\n {sortedElements\n .map((el) => elementFactory(el as LayoutElement))\n .filter((el) => !!el)\n .map((el) => (\n <g clipPath={`url(#${clipPathId})`}>{el}</g>\n ))}\n </g>\n </>\n );\n};\n","import { FrameElement, IllustrationElement, ImageElement, LayoutElementType, PapyrusComponent } from \"../types\";\nimport { degreesToRadians } from \"../util/math\";\nimport { modifySVGColors } from \"../util/illustration\";\nimport { svgToDataUrl } from \"../util/crossplatform\";\nimport { Group } from \"./Group\";\nimport { Fragment } from \"preact/jsx-runtime\";\n\nexport const Frame: PapyrusComponent<Omit<FrameElement, \"type\">> = (props) => {\n const patternLinkId = `spiff-frame-${props.id}`;\n const thresholdFilterId = `spiff-frame-threshold-${props.id}`;\n\n const getFrameContentSrc = () => {\n if (!props.pattern) {\n return \"\";\n }\n if (props.pattern.svg) {\n const modifiedSvg = modifySVGColors(props.pattern.svg, props.pattern.colors || {}, false);\n return svgToDataUrl(modifiedSvg);\n }\n return props.pattern.src;\n };\n\n if (!getFrameContentSrc()) {\n return <Fragment />;\n }\n\n const thresholdTableValues = (): string => {\n if (!props.threshold) {\n return \"\";\n }\n if (props.invertThreshold) {\n return \"1 \".repeat(props.threshold) + \"0 \".repeat(256 - props.threshold);\n }\n return \"0 \".repeat(props.threshold) + \"1 \".repeat(256 - props.threshold);\n };\n\n const renderDefinitions = () => {\n return (\n <>\n {props.useThreshold && (\n <defs>\n <filter id={thresholdFilterId} color-interpolation-filters=\"sRGB\">\n <feColorMatrix\n type=\"matrix\"\n values={`\n ${props.thresholdSaturation} ${props.thresholdSaturation} ${props.thresholdSaturation} 0 0\n ${props.thresholdSaturation} ${props.thresholdSaturation} ${props.thresholdSaturation} 0 0\n ${props.thresholdSaturation} ${props.thresholdSaturation} ${props.thresholdSaturation} 0 0\n 0 0 0 1 0\n `}\n result=\"greyscale\"\n ></feColorMatrix>\n <feComponentTransfer in=\"greyscale\">\n <feFuncR type=\"discrete\" tableValues={thresholdTableValues()} />\n <feFuncG type=\"discrete\" tableValues={thresholdTableValues()} />\n <feFuncB type=\"discrete\" tableValues={thresholdTableValues()} />\n </feComponentTransfer>\n </filter>\n </defs>\n )}\n </>\n );\n };\n\n // We only want to blur when a pattern is provided.\n const rotation = props.rotation || 0;\n const angleInRadians = degreesToRadians(rotation);\n const rotC = Math.cos(angleInRadians);\n const rotS = -Math.sin(angleInRadians);\n\n const getFrameContent = () => {\n const patternX = props.pattern?.x || 0;\n const patternY = props.pattern?.y || 0;\n const patternWidth = props.pattern?.width || 0;\n const patternHeight = props.pattern?.height || 0;\n const patternScaleX = props.pattern?.scaleX || 1;\n const patternScaleY = props.pattern?.scaleY || 1;\n const patternRotation = props.pattern?.rotation || 0;\n\n const children = props.pattern?.svg\n ? ({\n id: `${patternLinkId}-contents`,\n type: LayoutElementType.Illustration,\n x: patternX,\n y: patternY,\n rotation: patternRotation,\n width: patternWidth * patternScaleX,\n height: patternHeight * patternScaleY,\n src: getFrameContentSrc(),\n svg: props.pattern?.svg,\n colors: props.pattern?.colors,\n } as IllustrationElement)\n : ({\n id: `${patternLinkId}-contents`,\n type: LayoutElementType.Image,\n x: patternX,\n y: patternY,\n rotation: patternRotation,\n width: patternWidth * patternScaleX,\n height: patternHeight * patternScaleY,\n src: getFrameContentSrc(),\n } as ImageElement);\n return [children];\n };\n\n return (\n <>\n {renderDefinitions()}\n <g\n opacity={props.opacity}\n mask={props.stepName ? undefined : props.mask}\n filter={props.useThreshold ? `url(#${thresholdFilterId})` : undefined}\n >\n <g\n transform={`\n matrix(1, 0, 0, 1, ${props.x}, ${props.y})\n matrix(1, 0, 0, 1, ${props.width / 2}, ${props.height / 2})\n matrix(${rotC}, ${-rotS}, ${rotS}, ${rotC}, 0, 0)\n matrix(1, 0, 0, 1, ${-props.width / 2}, ${-props.height / 2})\n matrix(${props.scaleX}, 0, 0, ${props.scaleY}, 0, 0)\n `}\n >\n <Group\n id={patternLinkId}\n x={0}\n y={0}\n rotation={0}\n width={props.width}\n height={props.height}\n clipPath={props.path}\n children={getFrameContent()}\n />\n </g>\n </g>\n </>\n );\n};\n","import { parse as opentypeParse, Font, Glyph } from \"opentype.js\";\nimport {\n dataUrlToArrayBuffer,\n domParser,\n fetchAsArrayBuffer,\n loadFontFaceSet,\n xmlSerializer,\n} from \"../util/crossplatform\";\nimport { Declaration, parse, Rule } from \"css\";\nimport { decode } from \"html-entities\";\n\nconst metricCache: Map<string, FontMetrics> = new Map();\n\n/**\n * Stores cached information about metrics related to a specific font.\n */\nexport class FontMetrics {\n private font: Font;\n private glyphsFromText: Map<string, Glyph[]>;\n private kerningValues: Map<string, Map<string, number>>;\n private height: number;\n\n constructor(font: Font) {\n this.font = font;\n this.glyphsFromText = new Map();\n this.kerningValues = new Map();\n this.height = this.calculateApproximateHeight();\n }\n\n getFont(): Font {\n return this.font;\n }\n\n getGlyphs(text: string) {\n const oldGlyphs = this.glyphsFromText.get(text);\n if (oldGlyphs) {\n return oldGlyphs;\n }\n const newGlyphs = this.font.stringToGlyphs(text);\n this.glyphsFromText.set(text, newGlyphs);\n return newGlyphs;\n }\n\n /**\n * @returns The approximate height of any text line based on all main characters of the alphabet.\n */\n getApproximateHeight() {\n return this.height;\n }\n\n /**\n * Computes the exact height of a line of text.\n * @param text\n * @returns\n */\n getExactHeight(text: string): number {\n const glyphs = this.font.stringToGlyphs(text);\n let ascent = 0;\n let descent = 0;\n glyphs.forEach((glyph) => {\n const metrics = glyph.getMetrics();\n ascent = Math.max(ascent, metrics.yMax);\n descent = Math.min(descent, metrics.yMin);\n });\n return ascent - descent;\n }\n\n getKerningValue(a: Glyph, b: Glyph) {\n if (!a.name || !b.name) return undefined;\n let valuesForFirst = this.kerningValues.get(a.name);\n if (!valuesForFirst) {\n valuesForFirst = new Map();\n this.kerningValues.set(a.name, valuesForFirst);\n }\n let valueForSecond = valuesForFirst.get(b.name);\n if (!valueForSecond) {\n valueForSecond = this.font.getKerningValue(a, b);\n valuesForFirst.set(b.name, valueForSecond);\n }\n return valueForSecond;\n }\n\n private calculateApproximateHeight(): number {\n const chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n const glyphs = this.font.stringToGlyphs(chars);\n let ascent = 0;\n let descent = 0;\n glyphs.forEach((glyph) => {\n const metrics = glyph.getMetrics();\n ascent = Math.max(ascent, metrics.yMax);\n descent = Math.min(descent, metrics.yMin);\n });\n return ascent - descent;\n }\n}\n\nconst isDataURL = (url: string) => {\n return url.substring(0, 5).toLowerCase().trim() === \"data:\";\n};\n\nconst loadFontCache: Map<string, Promise<Font>> = new Map();\n/**\n * A function for loading and caching a font\n * @param url The URL to load either a web URL or dataURL\n * @param buffer An optional array buffer for the resource if available\n * @returns An opentype font object.\n */\nexport const loadFont = async (url: string): Promise<Font> => {\n if (loadFontCache.has(url)) {\n return loadFontCache.get(url)!;\n }\n const getFont = async () => {\n try {\n const metrics = getFontMetrics(url);\n return metrics.getFont();\n } catch {\n if (isDataURL(url)) {\n const arrayBuffer = dataUrlToArrayBuffer(url);\n const font = opentypeParse(arrayBuffer);\n cacheFontMetrics(url, font);\n return font;\n } else {\n const buffer = await fetchAsArrayBuffer(url, true);\n const font = opentypeParse(buffer);\n cacheFontMetrics(url, font);\n await loadFontFaceSet(font, url);\n return font;\n }\n }\n };\n const promise = getFont();\n loadFontCache.set(url, promise);\n return promise;\n};\n\n/**\n * Loads a font object from a given data URL.\n * @deprecated Use loadFont instead.\n * @param url The data URL to load.\n * @returns A font object.\n */\nexport const _loadFontExternalDataURL = (url: string): Font => {\n const arrayBuffer = dataUrlToArrayBuffer(url);\n const font = opentypeParse(arrayBuffer);\n cacheFontMetrics(url, font);\n return font;\n};\n\nexport const getFontMetrics = (assetUrl: string): FontMetrics => {\n const oldCache = metricCache.get(assetUrl);\n if (oldCache) {\n return oldCache;\n }\n throw new Error(\"Font metrics unavailable for font\");\n};\n\nconst cacheFontMetrics = (assetUrl: string, font: opentype.Font) => {\n const newCache = new FontMetrics(font);\n metricCache.set(assetUrl, newCache);\n return newCache;\n};\n\nexport const outlineFontsInSvg = async (svg: string): Promise<string> => {\n const parser: DOMParser = domParser();\n const parsedSvg = parser.parseFromString(svg, \"image/svg+xml\");\n const root = parsedSvg.firstElementChild!;\n\n const fontMap = new Map(); // Map font names to URLs.\n const styles = root.querySelectorAll(\"style\");\n styles.forEach((style) => {\n const tree = parse(style.innerHTML);\n tree.stylesheet?.rules.forEach((rule: Rule) => {\n if (rule.type === \"font-face\" && rule.declarations) {\n const fontFamily = (rule.declarations as Declaration[]).find(\n (d) => d.property === \"font-family\",\n )?.value;\n const src = (rule.declarations as Declaration[]).find((d) => d.property === \"src\")?.value;\n const url = src?.match(/'(https.*?)'/)?.[1];\n if (fontFamily && url) {\n fontMap.set(fontFamily, url);\n }\n }\n });\n });\n\n // Do the outlining.\n const tspans = parsedSvg.querySelectorAll(\"tspan\");\n for (let i = 0; i < tspans.length; i++) {\n const tspan = tspans.item(i);\n const textAncestor = tspan.closest(\"text\")!;\n const gAncestor = tspan.closest(\"g\")!;\n const fontFamily = textAncestor.getAttribute(\"font-family\")!;\n const font = await loadFont(fontMap.get(fontFamily));\n const text = decode(tspan.innerHTML);\n\n const fill = textAncestor.getAttribute(\"fill\");\n const stroke = textAncestor.getAttribute(\"stroke\");\n const strokeWidth = textAncestor.getAttribute(\"stroke-width\");\n\n const pathToMeasure = font.getPath(\n text,\n 0,\n 0,\n parseInt(textAncestor.getAttribute(\"font-size\") ?? \"72\"),\n );\n const width = pathToMeasure.getBoundingBox().x2 - pathToMeasure.getBoundingBox().x1;\n let offset = 0;\n const anchor = tspan.getAttribute(\"text-anchor\");\n if (anchor === \"middle\") {\n offset = width / 2;\n } else if (anchor === \"end\") {\n offset = width;\n }\n const path = font.getPath(\n text,\n parseFloat(tspan.getAttribute(\"x\") ?? \"0\") - offset,\n parseFloat(tspan.getAttribute(\"y\") ?? \"0\"),\n parseInt(textAncestor.getAttribute(\"font-size\") ?? \"72\")\n );\n\n path.fill = fill;\n path.stroke = stroke;\n path.strokeWidth = parseFloat(strokeWidth ?? \"0\");\n\n const pathString = path.toSVG(2);\n const pathDocument = parser.parseFromString(pathString, \"image/svg+xml\");\n const pathElement = pathDocument.firstElementChild!;\n gAncestor.appendChild(pathElement);\n }\n\n // Remove the old text elements.\n const texts = parsedSvg.querySelectorAll(\"text\");\n texts.forEach((t) => t.remove());\n\n const serialiser = xmlSerializer();\n const rebuiltSvg = serialiser.serializeToString(root);\n return rebuiltSvg;\n};\n","import { FontMetrics, getFontMetrics } from \"../../util/font\";\nimport { charWidth, defaultLineHeightFactor, lineWidth, textWidth, zip } from \"../shared\";\nimport { CanvasRegion, FontData, Region, TextboxElement } from \"../../types\";\nimport { Font } from \"opentype.js\";\n\nconst clampWidth = (lines: string[], currentWidth: number, fontScale: number, cache: FontMetrics): number => {\n return Math.max(charWidth(lines.join(\"\\n\"), fontScale, cache), currentWidth)\n}\n\n/**\n * Produce an array where text has been broken into lines that can\n * fit the given region with width = region.width and height = auto.\n */\nconst getLines = (\n region: CanvasRegion,\n text: string,\n fontSize: number,\n fontScale: number,\n cache: FontMetrics,\n lineHeight?: number,\n): TraditionalTextResults => {\n const lh = (lineHeight || defaultLineHeightFactor) * cache.getApproximateHeight();\n const lines = text.split(\"\\n\");\n\n try {\n // Split each line into lines that are less wide than the region.\n const processedLines = lines.flatMap(line => splitLineUntilFit(line, region.width, fontScale, cache));\n const calculatedLines = processedLines.flatMap(li => li.lines);\n return {\n lines: calculatedLines,\n requiredHeight: processedLines.flatMap(li => li.lines).length * (fontScale * lh),\n fontSize: fontSize,\n requiredWidth: clampWidth(calculatedLines, region.width, fontScale, cache)\n };\n } catch (e) {\n const allChars = text.split('');\n return {\n lines: allChars,\n requiredHeight: allChars.length * (fontScale * lh),\n fontSize: fontSize,\n requiredWidth: clampWidth(allChars, region.width, fontScale, cache)\n };\n }\n};\n\nconst splitLineUntilFit = (line: string, regionWidth: number, fontScale: number, cache: FontMetrics): { lines: string[], width: number } => {\n const initialWidth = textWidth(line, fontScale, cache);\n if (initialWidth <= regionWidth) {\n return { lines: [line], width: initialWidth };\n }\n\n const lineContainsSpace = line.indexOf(' ') > -1;\n if (!lineContainsSpace) {\n // No space, whole line is one word.\n if (line.length <= 1) {\n throw new Error(`Character ${line} is wider than region`);\n }\n const middle = Math.floor(line.length / 2);\n\n const splitA = splitLineUntilFit(line.slice(0, middle), regionWidth, fontScale, cache);\n const splitB = splitLineUntilFit(line.slice(middle), regionWidth, fontScale, cache);\n return { lines: [...splitA.lines, ...splitB.lines], width: Math.max(splitA.width, splitB.width) };\n }\n\n const allWords = line.split(' ');\n const lines: string[] = [];\n let maxWidth = -Infinity;\n\n let firstWordIndex = 0;\n while (firstWordIndex < allWords.length) {\n const firstWord = allWords[firstWordIndex];\n if (textWidth(firstWord, fontScale, cache) > regionWidth) {\n // First word is too big for one line.\n const split = splitLineUntilFit(firstWord, regionWidth, fontScale, cache);\n lines.push(...split.lines);\n maxWidth = Math.max(maxWidth, split.width);\n firstWordIndex++;\n } else {\n // Add words to temp line until we go over.\n const tempWords = [firstWord];\n maxWidth = Math.max(maxWidth, textWidth(firstWord, fontScale, cache));\n\n let lastWordIndex = firstWordIndex + 1;\n let fits = true;\n while (lastWordIndex < allWords.length && fits) {\n const nextWord = allWords[lastWordIndex];\n const wordsWidth = textWidth(`${tempWords.join(' ')} ${nextWord}`, fontScale, cache);\n if (wordsWidth <= regionWidth) {\n tempWords.push(nextWord);\n maxWidth = Math.max(maxWidth, wordsWidth);\n lastWordIndex++;\n } else {\n fits = false;\n }\n }\n lines.push(tempWords.join(' '));\n\n firstWordIndex = lastWordIndex;\n }\n }\n\n if (maxWidth < 0) {\n throw new Error(`No max width calculated for text: ${lines}.`);\n }\n return { lines, width: maxWidth };\n};\n\nexport interface TraditionalTextResults {\n lines: string[];\n fontSize: number,\n requiredHeight: number;\n requiredWidth: number;\n}\n\nconst calcFontSize = (\n lines: string[],\n cache: FontMetrics,\n font: Font,\n width: number,\n height: number,\n lineHeight?: number\n): number => {\n const lh = (lineHeight ?? defaultLineHeightFactor) * cache.getApproximateHeight();\n const fontScale = 1 / font.unitsPerEm;\n\n const desiredWidth = lineWidth(lines, fontScale, cache);\n const desiredHeight = lines.length * lh * fontScale;\n\n const fontSizeW = width / desiredWidth;\n const fontSizeH = height / desiredHeight;\n return Math.min(fontSizeH, fontSizeW);\n}\n\n/**\n * Automatically fit the dimensions and font size of a textbox, based on how the textbox has been changed\n * @param updatedText The new input text.\n * @param updatedElement The element in its new, updated state.\n * @param previousElement The element before any changes.\n * @param lineHeight The line height of the textbox.\n * @returns A collection of changes that are required to correctly update the textbox.\n */\nexport const refitTextbox = (\n updatedText: string,\n updatedElement: TextboxElement,\n previousElement?: TextboxElement,\n lineHeight?: number,\n): TraditionalTextResults => {\n const cache = getFontMetrics(updatedElement.fontData!.assetUrl);\n const font = cache.getFont();\n const fontScale = updatedElement.fontSize / font.unitsPerEm;\n\n if (!previousElement) {\n return getLines(updatedElement as unknown as CanvasRegion, updatedText, updatedElement.fontSize, fontScale, cache, lineHeight);\n }\n\n // fallbackLines is only used when not re-calculating the lines of text\n let fallbackLines: string[];\n if (!updatedElement.text) {\n fallbackLines = updatedElement.input?.split(\"\\n\") ?? [\"\"];\n } else {\n fallbackLines = updatedElement.text.split(\"\\n\");\n }\n\n // layout has not changed\n if (previousElement.input === updatedText\n && updatedElement.width === previousElement.width\n && updatedElement.height === previousElement.height\n && updatedElement.lineHeight === previousElement.lineHeight) {\n return {\n lines: fallbackLines,\n requiredHeight: updatedElement.height,\n requiredWidth: clampWidth(fallbackLines, updatedElement.width, fontScale, cache),\n fontSize: updatedElement.fontSize\n }\n }\n\n const oneAxisChange = (updatedElement.width !== previousElement.width) !== (updatedElement.height !== previousElement.height);\n if (updatedElement.lineHeight === previousElement.lineHeight\n && !oneAxisChange\n && previousElement.input === updatedText) {\n return {\n lines: fallbackLines,\n requiredHeight: updatedElement.height,\n requiredWidth: clampWidth(fallbackLines, updatedElement.width, fontScale, cache),\n fontSize: calcFontSize(fallbackLines, cache, font, updatedElement.width, updatedElement.height, lineHeight)\n };\n } else {\n return getLines(updatedElement as unknown as CanvasRegion, updatedText, updatedElement.fontSize, fontScale, cache, lineHeight);\n }\n}\n\n/**\n * If a textbox has a fixed font size, it's width should be changed to fit the text.\n */\nexport const recalculateTextboxRegion = (\n currentRegion: Region,\n fontData: FontData,\n fontSize: number,\n textLines: string[],\n align?: string,\n): Region => {\n const cache = getFontMetrics(fontData.assetUrl);\n const font = cache.getFont();\n\n let region = { ...currentRegion };\n const candidateRegion = { ...currentRegion };\n const requiredWidth = lineWidth(textLines, fontSize / font.unitsPerEm, getFontMetrics(fontData.assetUrl));\n\n if (requiredWidth && requiredWidth < region.width) {\n candidateRegion.width = requiredWidth;\n if (align === \"left\") {\n candidateRegion.left += Math.sin((region.rotation * Math.PI) / 360) * (region.width - requiredWidth);\n candidateRegion.top += (Math.sin((region.rotation * Math.PI) / 180) * (requiredWidth - region.width)) / 2;\n } else if (align === \"right\") {\n candidateRegion.left += region.width - requiredWidth;\n } else {\n candidateRegion.left += (region.width - requiredWidth) / 2;\n }\n if (\n textLines &&\n zip(textLines, textLines).every(([lineA, lineB]) => lineA === lineB)\n ) {\n region = candidateRegion;\n }\n }\n return region;\n};\n","import { FontMetrics } from \"../util/font\";\nimport { TextAlgorithm, TextboxElement } from \"../types\";\nimport { refitTextbox } from \"./algorithm/traditional\";\n\n/**\n * The size of a step used to compute font sizes.\n */\nexport const fontSizeStep = 1;\n\n/**\n * Computes the width of text. See the following link for a detailed breakdown.\n * https://developer.tizen.org/community/tip-tech/working-fonts-using-opentype.js?langswitch=en\n * @param text The text to get width for.\n * @param scale The scale\n * @param cache The font metric cache to be used for calculations.\n * @returns The width of the text.\n */\nexport const textWidth = (text: string, scale: number, cache: FontMetrics): number => {\n let width = 0;\n const glyphs = cache.getGlyphs(text);\n\n glyphs.forEach((glyph, idx) => {\n if (glyph.advanceWidth) {\n width += glyph.advanceWidth;\n }\n if (idx < glyphs.length - 1) {\n const kerningValue = cache.getKerningValue(glyph, glyphs[idx + 1]);\n width += kerningValue || 0;\n }\n });\n width *= scale;\n return width;\n};\n\n/**\n * Computes the width of the larges individual character in the input text.\n * @param text The input text.\n * @param scale The scale of the text.\n * @param cache The font metric cache to be used for calculations.\n * @returns The width of the largest character.\n */\nexport const charWidth = (text: string, scale: number, cache: FontMetrics): number => {\n let maxWidth = 0;\n const glyphs = cache.getGlyphs(text);\n\n glyphs.forEach((glyph, idx) => {\n if (glyph.advanceWidth) {\n maxWidth = Math.max(maxWidth, glyph.advanceWidth);\n }\n if (idx < glyphs.length - 1) {\n const kerningValue = cache.getKerningValue(glyph, glyphs[idx + 1]);\n maxWidth = Math.max(maxWidth, kerningValue || 0);\n }\n });\n maxWidth *= scale;\n return maxWidth;\n};\n\n/**\n * Computes the width of the largest line.\n * @param lines The input text split by line.\n * @param fontScale The scale of the text.\n * @param cache The font metric cache to be used for calculations.\n * @returns The width of the largest line.\n */\nexport const lineWidth = (lines: string[], fontScale: number, cache: FontMetrics): number => {\n let maxWidth = 0;\n lines.forEach((line) => {\n maxWidth = Math.max(maxWidth, textWidth(line, fontScale, cache));\n });\n return maxWidth;\n};\n\ninterface TextTransformationConfiguration {\n stripControlCharacters: boolean;\n vertical: boolean;\n uppercase: boolean;\n}\n\nconst transformationDefaults: TextTransformationConfiguration = {\n stripControlCharacters: true,\n vertical: false,\n uppercase: false,\n};\n\n/**\n * Applies a number of different transformations to a piece of text based on configuration\n * @param text The text to transform.\n * @param options The requested options, this will default to sensible defaults if not provided.\n * @returns A string represented the transformed value of the input text.\n */\nexport const applyTextTransformations = (\n text: string,\n options: Partial<TextTransformationConfiguration> = transformationDefaults,\n) => {\n // We apply our own defaults to any fields that aren't supplied.\n const configuration = { ...transformationDefaults, ...options };\n\n let result = text || \"\";\n\n // Control characters are not valid in XML, we strip them from any input to\n // ensure that invalid data doesn't enter the SVG generated by our system.\n // \\u000A and \\u000D are carriage return and newline sequences, we want to keep these.\n // eslint-disable-next-line no-control-regex\n if (configuration.stripControlCharacters) {\n result = result.replace(/^(?![\\u000A\\u000D])[\\u0000-\\u001F\\u007F-\\u009F]/g, \"\");\n }\n\n // Force upper case\n if (configuration.uppercase) {\n result = result.toUpperCase();\n }\n\n // Inserts newlines into text to make a vertical string\n if (configuration.vertical) {\n result = result.split(\"\").join(\"\\n\");\n }\n\n return result;\n};\n\n// https://stackoverflow.com/a/22015771\n// Helpful function for zipping two arrays together\nexport const zip = (xs: any[], ys: any[]) => {\n return xs.map((x, idx) => [x, ys[idx]]);\n};\n\nexport const getTextAlignment = (align: string = \"center\", isVertical: boolean = false) => {\n if (isVertical) {\n return \"center\";\n }\n return align;\n};\n\n/**\n * Returns the correct text anchor for the given alignment.\n */\nexport const getAnchor = (align?: string) => {\n if (align === \"left\") {\n return \"start\";\n }\n if (align === \"right\") {\n return \"end\";\n }\n return \"middle\";\n};\n\nexport const recomputeTextOnElement = (el: TextboxElement, newText: string, oldEl?: TextboxElement): TextboxElement => {\n if (!el.fontData) {\n return el;\n }\n const getCalculatedMixins = () => {\n // TODO: Pull the autosize algorithm in here as well. This means all sizing\n // will occur in one place. Any command that relies on text changes that could affect\n // the textbox size in any way should pass through this function.\n if (el.algorithm === TextAlgorithm.Traditional) {\n const calculatedText = refitTextbox(newText, el, oldEl, el.lineHeight);\n return {\n text: calculatedText.lines.join(\"\\n\"),\n height: calculatedText.requiredHeight,\n width: calculatedText.requiredWidth,\n fontSize: calculatedText.fontSize,\n input: newText,\n };\n } else {\n return {\n text: newText,\n };\n }\n };\n return {\n ...el,\n ...getCalculatedMixins(),\n };\n};\n\n/**\n * The default line height to use in situations where none is specified.\n * Typical default is suggested to be between 1.1 & 1.2\n */\nexport const defaultLineHeightFactor = 1.1;\n","import { WorkflowManager } from \"..\";\nimport Handlebars from \"handlebars\";\n\n/**\n * Attempts to render the template text. If the render fails for any reason, the original text will be returned.\n * @param text The template.\n * @param workflowManager The workflowManger to fetch the templating context for.\n * @returns The rendered text, or the original text if the render failed.\n */\nexport function renderTextTemplateForWorkflow(text: string, workflowManager: WorkflowManager): string {\n return renderTextTemplate(text, workflowManager.getTemplatingContext());\n}\n\n/**\n * Attempts to render the template text. If the render fails for any reason, the original text will be returned.\n * @param text The template.\n * @param context The rendering context.\n * @returns The rendered text, or the original text if the render failed.\n */\nexport function renderTextTemplate(text: string, context: any): string {\n try {\n text = Handlebars.compile(text)(context);\n } catch (e: any) {\n console.error(\"failed to render templated text\", e);\n }\n return text;\n}\n","import { getAnchor } from \"../text/shared\";\nimport { FontData, PapyrusComponent, TextboxElement } from \"../types\";\nimport { spotColorDefinitionString } from \"../util/color\";\nimport { getFontMetrics } from \"../util/font\";\nimport { renderTextTemplate } from \"../util/text\";\n\nexport const Textbox: PapyrusComponent<Omit<TextboxElement, \"type\">> = (props) => {\n const rotation = props.rotation || 0;\n const angleInRadians = (rotation * Math.PI) / 180.0;\n const rotC = Math.cos(angleInRadians);\n const rotS = -Math.sin(angleInRadians);\n const curvedPathId = `text-path-${props.id}`;\n const textFillId = `text-fill-${props.id}`;\n\n const xTranslation = props.x + (props.curved ? 0 : props.width / 2);\n const yTranslation = props.y + (props.curved ? 0 : props.height / 2);\n\n const text = renderTextTemplate(props.text || \"\", props._renderingConfiguration?.templatingContext);\n const lines = text.split(\"\\n\");\n\n const stroke =\n props.strokeColor?.browserValue && props.strokeThickness ? props.strokeColor?.browserValue : undefined;\n const strokeWidth = props.strokeColor?.browserValue && props.strokeThickness ? props.strokeThickness : undefined;\n\n if (props.curved && !props.paths) {\n return null;\n }\n\n if (!props.fontData) {\n return null;\n }\n\n const getFill = (): string => {\n if (props.textFillImage) {\n return `url(\"#${textFillId}\")`;\n }\n if (props._renderingConfiguration?.spotColors && props.fillSpotColorDefinition) {\n return `${props.fill} ${spotColorDefinitionString(props.fillSpotColorDefinition)}`;\n }\n return props.fill;\n };\n\n return (\n <>\n <defs>\n {props.textFillImage && (\n <pattern\n id={textFillId}\n patternUnits=\"userSpaceOnUse\"\n width={props.textFillImage.scale * props.textFillImage.width}\n height={props.textFillImage.scale * props.textFillImage.height}\n x={0}\n y={0}\n >\n <image\n href={props.textFillImage.src}\n xlinkHref={props.textFillImage.src}\n width={props.textFillImage.scale * props.textFillImage.width}\n height={props.textFillImage.scale * props.textFillImage.height}\n />\n </pattern>\n )}\n <style\n type=\"text/css\"\n dangerouslySetInnerHTML={{\n __html: `\n @font-face {\n font-family: '${props.fontData.name}';\n src: url('${props.fontData.assetUrl}') format('truetype');\n }\n `,\n }}\n />\n {props.curved && props.paths ? <path id={curvedPathId} d={props.paths[0]} /> : undefined}\n </defs>\n {props._renderingConfiguration?.debug ? (\n <rect stroke=\"blue\" fill=\"none\" x={props.x} y={props.y} width={props.width} height={props.height} />\n ) : undefined}\n\n <g mask={props.stepName ? undefined : props.mask}>\n <g transform={`matrix(${rotC}, ${-rotS}, ${rotS}, ${rotC}, ${xTranslation}, ${yTranslation})`}>\n <text\n xmlSpace=\"preserve\"\n fontFamily={`'${props.fontData.name}'`}\n fontSize={props.fontSize}\n fontStyle=\"normal\"\n fontWeight=\"normal\"\n fill={getFill()}\n style={{\n whiteSpace: \"pre\",\n userSelect: \"none\",\n }}\n stroke={stroke}\n strokeWidth={strokeWidth}\n >\n {props.curved ? (\n <TextPath text={text} curvedPathId={curvedPathId} align={props.align} />\n ) : (\n lines.map((line, idx) => {\n return (\n <TextSpan\n key={idx}\n align={props.vertical ? \"center\" : props.align}\n fontSize={props.fontSize}\n thisLineIdx={idx}\n amountLines={lines.length}\n text={line}\n textboxHeight={props.height}\n textboxWidth={props.width}\n lineHeight={props.lineHeight}\n vertical={props.vertical}\n verticalAlign={props.verticalAlign}\n fontData={props.fontData!}\n />\n );\n })\n )}\n </text>\n </g>\n </g>\n </>\n );\n};\n\nconst TextSpan: PapyrusComponent<{\n text: string;\n fontSize: number;\n thisLineIdx: number;\n amountLines: number;\n lineHeight?: number;\n textboxHeight: number;\n textboxWidth: number;\n align?: string;\n vertical?: boolean;\n verticalAlign?: string;\n fontData: FontData;\n}> = (props) => {\n const calcLineHeight = (): number => {\n if (props.lineHeight !== undefined) {\n // The lineHeight prop is only used by the deprecated, traditional algorithm.\n // If the lineHeight prop is present then calculate the line height the old way.\n return props.lineHeight * props.fontSize;\n }\n // Otherwise, calculate the line height in the same way as the\n // linesThatFit function of the autosize algorithm.\n const cache = getFontMetrics(props.fontData.assetUrl);\n const font = cache.getFont();\n const fontScale = props.fontSize / font.unitsPerEm;\n return cache.getApproximateHeight() * fontScale;\n };\n\n const getX = () => {\n if (props.align === \"left\") {\n return -props.textboxWidth / 2.0;\n }\n if (props.align === \"right\") {\n return props.textboxWidth / 2.0;\n }\n return 0.0;\n };\n\n // TODO: Write tests for this logic. Check coverage for lines\n const getY = () => {\n const lineHeight = calcLineHeight();\n const halfBoxHeight = props.textboxHeight / 2.0;\n\n if (props.verticalAlign === \"top\") {\n return -halfBoxHeight + (props.fontSize * 3) / 4 + props.thisLineIdx * lineHeight;\n }\n\n if (props.verticalAlign === \"bottom\") {\n const reverseIdx = props.amountLines - 1 - props.thisLineIdx;\n return halfBoxHeight - props.fontSize / 4 - reverseIdx * lineHeight;\n }\n\n // Vertically align to middle.\n // Lines before the middle line shift up,\n // lines after the middle line shift down.\n const middleLineIdx = (props.amountLines - 1) / 2.0;\n return (props.thisLineIdx - middleLineIdx) * lineHeight + props.fontSize / 4;\n };\n\n return (\n <tspan textAnchor={getAnchor(props.align)} x={getX()} y={`${getY()}px`}>\n {props.text}\n </tspan>\n );\n};\n\nconst TextPath: PapyrusComponent<{\n text: string;\n curvedPathId: string;\n align?: string;\n}> = (props) => {\n const targetId = `#${props.curvedPathId}`;\n const getStartOffset = () => {\n if (props.align === \"left\") {\n return \"0%\";\n }\n if (props.align === \"right\") {\n return \"100%\";\n }\n return \"50%\";\n };\n return (\n <textPath\n startOffset={getStartOffset()}\n textAnchor={getAnchor(props.align)}\n href={targetId}\n xlinkHref={targetId}\n >\n {props.text}\n </textPath>\n );\n};\n","import { Image } from \"./Image\";\nimport { modifySVGWithElementProperties } from \"../util/illustration\";\nimport { degreesToRadians } from \"../util/math\";\nimport { IllustrationElement, PapyrusComponent } from \"../types\";\n\nexport const Illustration: PapyrusComponent<Omit<IllustrationElement, \"type\">> = (props) => {\n // When caching is enabled we use the provided cached objectURL, this is much faster\n // than traversing and rendering the svg entirely inline.\n\n if (props.cachedObjectURL && !props._renderingConfiguration?.omitCachedFields) {\n return (\n <Image\n id={props.id}\n src={props.cachedObjectURL}\n x={props.x}\n y={props.y}\n width={props.width}\n height={props.height}\n rotation={props.rotation}\n preserveAspectRatio=\"none\"\n immutable={props.immutable}\n mask={props.stepName ? undefined : props.mask}\n />\n );\n }\n\n const rotation = props.rotation || 0;\n const angleInRadians = degreesToRadians(rotation);\n const rotC = Math.cos(angleInRadians);\n const rotS = -Math.sin(angleInRadians);\n\n const transform = `\n matrix(1, 0, 0, 1, ${props.x}, ${props.y})\n matrix(1, 0, 0, 1, ${props.width / 2}, ${props.height / 2})\n matrix(${rotC}, ${-rotS}, ${rotS}, ${rotC}, 0, 0)\n matrix(1, 0, 0, 1, ${-props.width / 2}, ${-props.height / 2})\n `;\n\n if (!props.svg) {\n throw new Error(\n `Illustration element ${props.id} (stepName ${props.stepName}) lacked svg from src ${props.src} at render time.`,\n );\n }\n\n return (\n <g mask={props.stepName ? undefined : props.mask}>\n <g\n transform={transform}\n dangerouslySetInnerHTML={{\n __html: modifySVGWithElementProperties(\n props.svg,\n props.width,\n props.height,\n props.colors,\n props._renderingConfiguration?.spotColors,\n ),\n }}\n />\n </g>\n );\n};\n","import { SVGLayoutProps, SVGLayout } from \"./Elements/SVGLayout\";\nimport { CanvasCommand, CreateLayoutCommand } from \"./command\";\nimport { Image } from \"./Elements/Image\";\nimport { Frame } from \"./Elements/Frame\";\nimport { Group } from \"./Elements/Group\";\nimport { Textbox } from \"./Elements/Textbox\";\nimport { Illustration } from \"./Elements/Illustration\";\nimport { generate } from \"./util/guid\";\n\nimport {\n LayoutsState,\n ILayout,\n LayoutElement,\n ImageElement,\n FrameElement,\n IllustrationElement,\n TextboxElement,\n RenderingConfiguration,\n LayoutState,\n Layerable,\n PapyrusNode,\n PapyrusComponent,\n LayoutElementType,\n GroupElement,\n} from \"./types\";\n\nexport interface CommandState {\n transaction: LayoutsState;\n}\n\nexport interface LayoutComponentConfiguration {\n renderingConfiguration: RenderingConfiguration;\n outlineArea?: {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n scale?: number;\n // If true the outline area won't be stroked.\n hidden?: boolean;\n };\n viewBox?: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n maxHeight?: string;\n maxWidth?: string;\n height?: string | number;\n width?: string | number;\n position?: string;\n borderRadius?: number;\n outlineColor?: string;\n backgroundColor?: string;\n}\n\nexport class CommandContext {\n private state: undefined | CommandState;\n private stateCallbacks: (() => void)[];\n private id: string;\n\n private prevCommands: CanvasCommand[];\n private nextCommands: CanvasCommand[];\n\n constructor() {\n this.id = generate();\n this.stateCallbacks = [];\n this.prevCommands = [];\n this.nextCommands = [];\n }\n\n registerStateCallback(callback: () => void) {\n this.stateCallbacks.push(callback);\n }\n\n unregisterStateCallback(callback: () => void) {\n this.stateCallbacks.filter((cb) => cb !== callback);\n }\n\n getState() {\n return this.state;\n }\n\n private runStateCallbacks() {\n this.stateCallbacks.forEach((cb) => cb());\n }\n\n apply(command: CanvasCommand, leaveOffUndoStack?: boolean) {\n if (!this.state) {\n throw new Error(`State not initialized for cc ${this.id}!`);\n }\n this.state = this.commandReducer(this.state, command);\n this.runStateCallbacks();\n this.nextCommands = [];\n if (!leaveOffUndoStack) {\n this.prevCommands.push(command);\n }\n }\n\n undo() {\n if (!this.state) {\n return;\n }\n const mostRecentCommand = this.prevCommands.pop();\n if (!mostRecentCommand) {\n return;\n }\n const undoneState = mostRecentCommand.undo();\n this.state = { ...this.state, transaction: undoneState };\n this.nextCommands.push(mostRecentCommand);\n this.runStateCallbacks();\n }\n\n redo() {\n if (!this.state) {\n return;\n }\n const mostImminentCommand = this.nextCommands.pop();\n if (!mostImminentCommand) {\n return;\n }\n this.state = this.commandReducer(this.state, mostImminentCommand);\n this.runStateCallbacks();\n this.prevCommands.push(mostImminentCommand);\n }\n\n /**\n * Find all commands in history with the given sequence ID,\n * discard all but the last and overwrite its oldState.\n */\n public flattenSequence(sequenceId: string, initialState: LayoutsState) {\n const commandSequence = this.prevCommands.filter((c) => c.sequenceId === sequenceId);\n const mostRecentCommand = commandSequence.pop();\n if (!mostRecentCommand) {\n return;\n }\n this.prevCommands = this.prevCommands.filter((c) => c.sequenceId !== sequenceId);\n mostRecentCommand?.overrideOldState(initialState);\n this.prevCommands.push(mostRecentCommand);\n }\n\n getLayoutById(layoutId: string): LayoutData {\n if (!this.state) {\n throw new Error(`State not initialized for cc ${this.id}!`);\n }\n const transactionState = this.state.transaction?.layouts?.[layoutId];\n const layout = transactionState?.layout;\n if (!layout) {\n throw new Error(`No layout: ${layoutId}`);\n }\n const els = [...(transactionState?.elements || [])];\n return this.getLayoutDataWithState(layout, els);\n }\n\n getAllLayouts() {\n if (!this.state) {\n throw new Error(`State not initialized for cc ${this.id}!`);\n }\n const layoutNamesWithDupes = [...Object.keys(this.state.transaction?.layouts)];\n const layoutNames = [...new Set(layoutNamesWithDupes)];\n return layoutNames.map((id) => this.getLayoutById(id));\n }\n\n private getLayoutDataWithState(layout: ILayout, elements: LayoutElement[]) {\n return {\n layoutState: {\n layout,\n elements,\n },\n getComponentWithProps: (configuration: LayoutComponentConfiguration) => {\n return getSvgElement(layout, elements, configuration);\n },\n } as LayoutData;\n }\n\n initialize(layouts: ILayout[], reloadedState?: LayoutsState) {\n if (reloadedState) {\n this.state = {\n transaction: reloadedState,\n };\n return;\n }\n let newState: LayoutsState = {\n serializableWorkflow: { steps: [] },\n layouts: {},\n };\n layouts.forEach((layout) => {\n newState = new CreateLayoutCommand(layout).apply(newState);\n });\n this.runStateCallbacks();\n this.state = {\n transaction: newState,\n };\n }\n\n private commandReducer(state: CommandState, command: CanvasCommand): CommandState {\n const transactionState = state.transaction || { layouts: {}, serializableWorkflow: { steps: [] } };\n return { ...state, transaction: command.apply(transactionState) };\n }\n}\n\nexport const elementFactory = (element: LayoutElement): PapyrusNode => {\n if (element.type === LayoutElementType.Image) {\n return <Image key={element.id} {...(element as ImageElement)} />;\n }\n if (element.type === LayoutElementType.Frame) {\n return <Frame key={element.id} {...(element as FrameElement)} />;\n }\n if (element.type === LayoutElementType.Illustration) {\n return <Illustration key={element.id} {...(element as IllustrationElement)} />;\n }\n if (element.type === LayoutElementType.Textbox) {\n return <Textbox key={element.id} {...(element as TextboxElement)} />;\n }\n if (element.type === LayoutElementType.Group) {\n return <Group key={element.id} {...(element as GroupElement)} />;\n }\n return null;\n};\n\nexport const getSvgElement = (\n layout: ILayout,\n elements: LayoutElement[],\n configuration: LayoutComponentConfiguration,\n): PapyrusNode => {\n const renderingConfiguration = configuration.renderingConfiguration;\n\n // Filter elements if required, any element can be tagged with exclude for print, meaning\n // that its value will not be sent up to the server.\n const filteredElements = renderingConfiguration?.removeExcludedElements\n ? elements.filter((el) => !el.excludeFromExport)\n : elements;\n\n return (\n <SVGLayout\n preserveAspectRatio={undefined}\n elements={filteredElements}\n backgroundColor={\n layout.transparentBackground\n ? undefined\n : configuration.backgroundColor\n ? configuration.backgroundColor\n : \"white\"\n }\n width={configuration.width || layout.width}\n height={configuration.height || layout.height}\n viewBox={\n renderingConfiguration?.region\n ? {\n x: renderingConfiguration.region.left,\n y: renderingConfiguration.region.top,\n width: renderingConfiguration.region.width,\n height: renderingConfiguration.region.height,\n }\n : {\n x: 0,\n y: 0,\n width: layout.width,\n height: layout.height,\n }\n }\n configuration={renderingConfiguration}\n outlineArea={configuration.outlineArea}\n maxHeight={configuration.maxHeight}\n maxWidth={configuration.maxWidth}\n position={configuration.position}\n borderRadius={configuration.borderRadius}\n outlineColor={configuration.outlineColor}\n />\n );\n};\n\n/**\n * Computes a list of elements sorted by layers first, lowest to highest. Followed by index within that layer, lowest to highest.\n * @returns The original array reference. Sorted in place.\n */\nexport function sortElementsByLayersWithIndex<T extends Layerable>(items: T[]): T[] {\n return items.sort((a, b) => {\n // Sort by layer first as this is the more significant factor.\n const aLayer = a.layer || 0;\n const bLayer = b.layer || 0;\n if (aLayer < bLayer) return -1;\n if (aLayer > bLayer) return 1;\n // If layer is equal, sort by index instead. Elements on the same layer\n // may be re-ordered amongst eachother.\n const aLayerIndex = a.layerIndex || 0;\n const bLayerIndex = b.layerIndex || 0;\n if (aLayerIndex < bLayerIndex) return -1;\n if (aLayerIndex > bLayerIndex) return 1;\n // Otherwise, they are at exactly the same place from a layering perspective, this actually isn't good. It means\n // we would be relying on stable sorting to ensure the elements don't fall out of the order we would expect.\n return 0;\n });\n}\n\nexport interface LayoutData {\n layoutState: LayoutState;\n Component: PapyrusComponent<SVGLayoutProps>;\n getComponentWithProps: (configuration: LayoutComponentConfiguration) => PapyrusComponent<SVGLayoutProps>;\n}\n","import { domParser, fetchAsArrayBuffer, fetchAsString } from \"./crossplatform\";\nimport { FrameOffsets, OptionResource, Region, VariantResource } from \"../types\";\nimport { getAttributesFromArrayBuffer } from \"./image\";\nimport { FrameData, PatternImageData } from \"../types\";\nimport { dataUriToBuffer } from \"data-uri-to-buffer\";\nimport { optionService } from \"../services/option\";\n\n/**\n * A map of src to pattern image data.\n */\nexport const patternImageDataCache = new Map<string, PatternImageData>();\n\n/**\n * A map of frame path to frame data relevant to that path.\n */\nexport const frameDataCache = new Map<string, FrameData>();\n/**\n * A cache of frame data generating promises.\n */\nconst frameDataPromiseCache = new Map<string, Promise<FrameData>>();\n\nexport const generateFrameSVG = async (region?: Region, src?: string): Promise<string> => {\n if (!src) {\n if (!region) throw new Error(\"No region or src supplied. Cannot construct frame!\");\n return generateDefaultRectangleFrameSvg(region);\n }\n return fetchAsString(src);\n};\n\n/**\n * TODO: This function isn't required anymore as the Group element will render a rect internally when no clipPath is given.\n * @param region A region to generate a rect from\n * @returns An SVG string representing a rectangle frame\n */\nexport const generateDefaultRectangleFrameSvg = (region: Region): string => {\n const width = region.width;\n const height = region.height;\n return `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${width} ${height}'>\n <path id=\"target-path\" d='M0 0 h ${width} v ${height} h ${-width} Z' />\n </svg>\n `;\n};\n\nexport const getVariant = async (\n designInputStepData: any, // FrameDesignInputStepData from generation types\n option?: OptionResource,\n): Promise<VariantResource | undefined> => {\n if (!option) {\n return undefined;\n }\n const variant = await optionService.getDefaultVariant(option, designInputStepData.frameVariantId);\n if (!variant) {\n throw new Error(`No variant with ID: ${designInputStepData.frameVariantId}`);\n }\n if (!variant.asset) {\n throw new Error(`No asset for variant with ID: ${designInputStepData.frameVariantId}`);\n }\n return variant;\n};\n\nexport const getFrameData = async (frameSvg: string): Promise<FrameData> => {\n if (frameDataPromiseCache.has(frameSvg)) {\n return frameDataPromiseCache.get(frameSvg)!;\n }\n const getFrameDataPromise = async () => {\n if (frameDataCache.has(frameSvg)) {\n return frameDataCache.get(frameSvg)!;\n }\n await new Promise((resolve) => setTimeout(resolve, 0));\n const parser = domParser();\n const frameDocument = parser.parseFromString(frameSvg, \"image/svg+xml\");\n const svg: Element | undefined = frameDocument.querySelector(\"svg\");\n if (!svg) {\n throw new Error(\"Malformed frame SVG: <svg> tag not found\");\n }\n const viewBox = svg.getAttribute(\"viewBox\");\n if (!viewBox) {\n throw new Error(\"SVG missing viewBox.\");\n }\n const viewBoxElems = viewBox.split(\" \");\n const viewBoxHeight = parseFloat(viewBoxElems[3]) || 1;\n const viewBoxWidth = parseFloat(viewBoxElems[2]) || 1;\n\n const elementById = frameDocument.getElementById(\"target-path\");\n const elementByClass = frameDocument.getElementsByClassName(\"st0\").item(0);\n\n // Newer frames specify a target id that we search for.\n if (elementById) {\n const path = elementById.getAttribute(\"d\");\n if (!path) {\n throw new Error(\"Malformed frame SVG: 'd' attribute not found on target element\");\n }\n const data = {\n path,\n width: viewBoxWidth,\n height: viewBoxHeight,\n };\n frameDataCache.set(path, data);\n return data;\n }\n\n // Common case in older frames, we have this code for backwards compat\n if (elementByClass) {\n const path = elementByClass.getAttribute(\"d\");\n if (!path) {\n throw new Error(\"Malformed frame SVG: 'd' attribute not found on target element\");\n }\n const data = {\n path,\n width: viewBoxWidth,\n height: viewBoxHeight,\n };\n frameDataCache.set(path, data);\n return data;\n }\n\n throw new Error(\"Malformed frame SVG\");\n };\n const frameDataPromise = getFrameDataPromise();\n frameDataPromiseCache.set(frameSvg, frameDataPromise);\n return frameDataPromise;\n};\n\nexport const calculateOffsets = (\n imageData: PatternImageData,\n frameData: FrameData,\n /** @deprecated These values were used by the old imposition system. */\n nondefaults?: { scale?: number; left?: number; top?: number },\n forceImageCover?: boolean,\n): FrameOffsets => {\n // Calculate the aspect ratios of the frame and the image\n const frameAspectRatio = frameData.width / frameData.height;\n const imageAspectRatio = imageData.width / imageData.height;\n\n let scaleFactor;\n if (forceImageCover) {\n // Ensure image covers the entire frame\n if (imageAspectRatio > frameAspectRatio) {\n // Image is wider, scale based on frame height\n scaleFactor = frameData.height / imageData.height;\n } else {\n // Image is taller, scale based on frame width\n scaleFactor = frameData.width / imageData.width;\n }\n } else {\n if (imageAspectRatio > frameAspectRatio) {\n // Image is wider, scale based on frame width\n scaleFactor = frameData.width / imageData.width;\n } else {\n // Image is taller, scale based on frame height\n scaleFactor = frameData.height / imageData.height;\n }\n }\n\n if (nondefaults?.scale !== undefined) {\n scaleFactor *= nondefaults?.scale;\n }\n\n // Compute center and left/top offsets\n const frameCenterHorizontal = frameData.width / 2;\n const frameCenterVertical = frameData.height / 2;\n const defaultLeft = frameCenterHorizontal - (imageData.width / 2) * scaleFactor;\n const left = nondefaults?.left || defaultLeft;\n const defaultTop = frameCenterVertical - (imageData.height / 2) * scaleFactor;\n const top = nondefaults?.top || defaultTop;\n return {\n x: left,\n y: top,\n zoom: scaleFactor,\n };\n};\n\nexport const getPatternImageData = async (src: string): Promise<PatternImageData> => {\n // Check the cache first.\n if (patternImageDataCache.has(src)) {\n return patternImageDataCache.get(src)!;\n }\n\n if (src.startsWith(\"data:image/svg+xml\")) {\n const parsed = dataUriToBuffer(src);\n const svg = new TextDecoder().decode(parsed.buffer);\n const attributes = svgStringDimensions(svg);\n const data = {\n src: src,\n width: attributes.width,\n height: attributes.height,\n aspect: attributes.width / attributes.height,\n };\n patternImageDataCache.set(src, data);\n return data;\n }\n\n // Otherwise load dimensions based on file type. SVG uses viewbox,\n // raster is based on natural dimensions\n const extension = src.split(\".\").pop()?.toLowerCase() ?? \"\";\n if (extension === \"svg\") {\n const svgData = await GetSVGDimensions(src);\n const width = svgData.width;\n const height = svgData.height;\n const data = {\n src: src,\n width,\n height,\n aspect: width / height,\n };\n patternImageDataCache.set(src, data);\n return data;\n } else {\n const arrayBuffer = await fetchAsArrayBuffer(src, true);\n // TODO: for now let's assume that anything that doesn't have a .svg extension is a raster.\n // Perhaps we should instead check the mime type to see if it doesn't have an svg mime type.\n //const mimeType = getMimeTypeOfArrayBuffer(arrayBuffer);\n //const isJpgExtension = extension === \"jpg\" || extension === \"jpeg\";\n const attributes = await getAttributesFromArrayBuffer(arrayBuffer);\n const data = {\n src: src,\n width: attributes.width,\n height: attributes.height,\n aspect: attributes.width / attributes.height,\n };\n patternImageDataCache.set(src, data);\n return data;\n }\n};\n\n/**\n * Returns dimensions of a given svg string in viewbox and rendered form and a dataURL allowing for\n * the SVG to be rendered cross origin on a canvas.\n * @param src The source for the SVG\n */\nexport const GetSVGDimensions = async (\n src: string,\n): Promise<{\n width: number;\n height: number;\n}> => {\n const svgText = await fetchAsString(src);\n return svgStringDimensions(svgText);\n};\n\n/**\n * Handle the different ways that lengths may be specified in an SVG.\n */\nconst lengthToPixels = (length: string): number => {\n if (length.endsWith(\"mm\")) {\n return Number(length.replace(\"mm\", \"\")) * 3.7795275591; // mm to px at 96dpi.\n }\n if (length.endsWith(\"px\")) {\n return Number(length.replace(\"px\", \"\"));\n }\n return Number(length); // Bare pixel amount.\n};\n\n/**\n * Return the dimensions of an SVG string.\n */\nexport const svgStringDimensions = (svgText: string): { width: number; height: number } => {\n const parser = domParser();\n const svgDOM = parser.parseFromString(svgText, \"image/svg+xml\");\n const svgElement = svgDOM.querySelector(\"svg\");\n if (!svgElement) {\n throw new Error(\"No svg tag found, this svg must be malformed!\");\n }\n const viewBox = svgElement.getAttribute(\"viewBox\");\n const width = svgElement.getAttribute(\"width\");\n const height = svgElement.getAttribute(\"height\");\n\n // Prioritize explicit height and width.\n const viewBoxValues =\n height && width\n ? [0, 0, lengthToPixels(width), lengthToPixels(height)]\n : viewBox?.split(\" \").map((str: string) => Number(str));\n if (!viewBoxValues) {\n throw new Error(\"No viewbox or width/height values detected on SVG file!\");\n }\n return {\n width: viewBoxValues[2],\n height: viewBoxValues[3],\n };\n};\n","import { generate } from \"../util/guid\";\nimport {\n ColorDefinition,\n FontData,\n FrameElement,\n FrameStepData,\n IllustrationElement,\n ImageElement,\n LayoutElementType,\n PictureStepData,\n Region,\n TextAlgorithm,\n TextboxElement,\n TextStepData,\n} from \"../types\";\nimport { getFontMetrics, loadFont } from \"../util/font\";\nimport { generateFrameSVG, getFrameData } from \"../util/frame\";\nimport { applyTextTransformations, getTextAlignment, recomputeTextOnElement, textWidth } from \"../text/shared\";\nimport { getAttributesFromArrayBuffer } from \"../util/image\";\nimport { LayoutData } from \"../CommandContext\";\nimport { generateSVGWithUnknownColors } from \"../util/illustration\";\nimport { Pith } from \"pith\";\nimport { recalculateTextboxRegion } from \"../text/algorithm/traditional\";\nimport { domParser, fetch, fetchAsArrayBuffer, fetchAsString, xmlSerializer } from \"../util/crossplatform\";\nimport { createCanvas, getDomParser, loadImage } from \"../customCanvas\";\n\nconst nextIndexForLayer = (layout: LayoutData, layer: number): number => {\n const elements = layout.layoutState.elements.filter((el) => el.layer === layer);\n const maxIndex = Math.max(...(elements.map((el) => el.layerIndex).filter((li) => li !== undefined) as number[]));\n return Math.max(maxIndex, 0) + 1;\n};\n\nconst getIllustrationBody = async (src: string): Promise<string> => {\n return new Promise((resolve) => {\n fetchAsString(src as string)\n .then((svg) => {\n resolve(svg);\n })\n .catch((e) => console.error(e));\n });\n};\n\nconst svgPromiseCache = new Map<string, Promise<string>>();\n\n/**\n * @param svg The SVG to get an object URL for.\n * @returns An object URL storing the cached image of this svg file.\n */\nexport const svgObjectURL = async (svg: string): Promise<string> => {\n if (svgPromiseCache.has(svg)) {\n return svgPromiseCache.get(svg)!;\n }\n\n const getCanvasObjectURLAsync = async (canvas: HTMLCanvasElement): Promise<string> => {\n return new Promise((resolve, reject) => {\n try {\n const canBuildObjectURL = !!URL && !!URL.createObjectURL;\n if (!canBuildObjectURL) throw new Error(\"Environment incapable of generating ObjectURL\");\n canvas.toBlob((blob) => {\n if (!blob) {\n if (canvas.width === 0 || canvas.height === 0)\n throw new Error(`Canvas dimensions are invalid (${canvas.width},${canvas.height})`);\n else if (canvas.width * canvas.height >= 268435456)\n throw new Error(`Canvas dimensions exceed device limit (${canvas.width},${canvas.height})`);\n throw new Error(\"Couldn't generate object URL for Illustration, the blob was undefined!\");\n }\n resolve(URL.createObjectURL(blob));\n });\n } catch (e: any) {\n reject(e);\n }\n });\n };\n\n const getPromise = async () => {\n const parser = domParser();\n const parsedSvg = parser.parseFromString(svg, \"image/svg+xml\");\n const root = parsedSvg.firstElementChild;\n\n if (!root) {\n throw new Error(\"Failed to read SVG\");\n }\n\n const serialiser = xmlSerializer();\n const rebuiltSvg = serialiser.serializeToString(root);\n const canvas = createCanvas();\n const ctx = canvas.getContext(\"2d\")!;\n const pith = await Pith.from(ctx as any, rebuiltSvg, {\n anonymousCrossOrigin: true,\n ignoreDimensions: false,\n createCanvas: createCanvas as any,\n createImage: loadImage as any,\n DOMParser: getDomParser(),\n fetch: fetch,\n });\n\n const widthString = root.getAttribute(\"width\");\n const heightString = root.getAttribute(\"height\");\n const cachedIllustrationQuality = 2048;\n if (heightString && widthString) {\n const height = parseFloat(heightString);\n const width = parseFloat(widthString);\n const aspect = width / height;\n if (aspect > 1) {\n // Wider than high\n pith.resize(cachedIllustrationQuality, cachedIllustrationQuality / aspect);\n } else {\n // Higher than wide\n pith.resize(cachedIllustrationQuality * aspect, cachedIllustrationQuality);\n }\n } else {\n pith.resize(cachedIllustrationQuality, cachedIllustrationQuality);\n }\n\n await pith.render();\n return await getCanvasObjectURLAsync(canvas as any);\n };\n const promise = getPromise();\n svgPromiseCache.set(svg, promise);\n return promise;\n};\n\n/**\n * Calculate a centered and reasonably sized region for the layout and content.\n */\nconst centralRegion = async (\n layout: LayoutData,\n type: LayoutElementType,\n link?: string,\n opts?: { text?: string; fontScale?: number },\n): Promise<Region> => {\n const coords = (layout.layoutState.layout.useEditableArea && layout.layoutState.layout.editableArea) || {\n width: layout.layoutState.layout.width,\n height: layout.layoutState.layout.height,\n x: 0,\n y: 0,\n };\n const lesserDim = coords.width < coords.height ? coords.width : coords.height;\n const size = layout.layoutState.layout.useEditableArea ? lesserDim / 1.3 : lesserDim / 2;\n\n const region = {\n top: coords.y + coords.height / 2 - size / 2,\n left: coords.x + coords.width / 2 - size / 2,\n width: size,\n height: size,\n rotation: 0,\n panelId: layout.layoutState.layout.panelId,\n };\n\n if (link && type === LayoutElementType.Illustration) {\n const svgData = await generateSVGWithUnknownColors(await getIllustrationBody(link));\n const parser = domParser();\n const parsedSvg = parser.parseFromString(svgData.svg, \"image/svg+xml\");\n const svgEl = parsedSvg.firstElementChild as SVGElement;\n const viewBox = svgEl.getAttribute(\"viewBox\");\n if (!viewBox) throw new Error(\"SVG missing viewBox.\");\n const oldHeight = region.height;\n const viewBoxElems = viewBox.split(\" \");\n const viewBoxWidth = parseFloat(viewBoxElems[2]) || 1;\n const viewBoxHeight = parseFloat(viewBoxElems[3]) || 1;\n const aspect = viewBoxWidth / viewBoxHeight;\n region.height = region.width / aspect;\n region.top += (oldHeight - region.height) / 2;\n }\n\n if (link && type === LayoutElementType.Image) {\n const oldHeight = region.height;\n const arrayBuffer = await fetchAsArrayBuffer(link);\n const attributes = await getAttributesFromArrayBuffer(arrayBuffer);\n const aspect = attributes.width / attributes.height;\n region.height = region.width / aspect;\n region.top += (oldHeight - region.height) / 2;\n }\n\n // When font size & text are provided, we compute based on the calculated text width\n if (link && type === LayoutElementType.Textbox && opts?.text && opts?.fontScale) {\n await loadFont(link);\n const cache = getFontMetrics(link);\n const calculatedTextWidth = textWidth(opts.text, opts?.fontScale, cache);\n region.width = Math.min(calculatedTextWidth, coords.width * 0.85);\n region.left = coords.x + coords.width / 2 - region.width / 2;\n }\n\n return region;\n};\n\nexport class LayoutElementFactory {\n static async getFrame(\n layout: LayoutData,\n opts: {\n region?: Region;\n configuration: Partial<FrameStepData>;\n src?: string;\n },\n ): Promise<FrameElement> {\n const frameSvg = await generateFrameSVG(opts.region, opts.src);\n const frameData = await getFrameData(frameSvg);\n\n const region = opts.region || (await centralRegion(layout, LayoutElementType.Frame));\n\n return {\n id: generate(),\n x: region.left,\n y: region.top,\n width: region.width,\n height: region.height,\n layer: region.layer || 0,\n layerIndex: region.layerIndex || nextIndexForLayer(layout, region.layer || 0),\n rotation: region.rotation,\n scaleX: region.width / frameData.width,\n scaleY: region.height / frameData.height,\n path: frameData.path,\n dataWidth: frameData.width,\n dataHeight: frameData.height,\n type: LayoutElementType.Frame,\n disablePlaceholder: opts.configuration.disablePlaceholder,\n focalBlur: opts.configuration.focalBlur,\n focalBlurStrength: opts.configuration.focalBlurStrength,\n focalBlurRadius: opts.configuration.focalBlurRadius,\n forceImageCover: opts.configuration.forceImageCover,\n pattern: undefined,\n immutable: region.immutable,\n };\n }\n\n static async getImage(\n layout: LayoutData,\n opts: {\n region?: Region;\n layout?: LayoutData;\n configuration: Partial<PictureStepData>;\n src: string;\n },\n ): Promise<ImageElement> {\n const region = opts.region || (await centralRegion(layout, LayoutElementType.Image, opts.src));\n\n return {\n id: generate(),\n src: opts.src,\n type: LayoutElementType.Image,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer || 0,\n layerIndex: region.layerIndex || nextIndexForLayer(layout, region.layer || 0),\n immutable: region.immutable,\n preserveAspectRatio: \"none\",\n };\n }\n\n static async getTextbox(\n layout: LayoutData,\n opts: {\n region?: Region;\n configuration: Partial<TextStepData>;\n fontSrc: string;\n designInputStep?: any; // TextDesignInputStepData old generation type from headless\n },\n ): Promise<TextboxElement> {\n const { configuration, fontSrc, designInputStep } = opts;\n\n // Load the font requested.\n const font = await loadFont(fontSrc);\n const fontData: FontData = {\n assetUrl: fontSrc,\n name: font.names.fullName[\"en\"],\n };\n\n const inputText = designInputStep?.text || configuration.defaultText || \"\";\n const replacedText = configuration.replaceableText\n ? configuration.replaceableText.replace(\"{{}}\", inputText)\n : inputText;\n\n // Transform based on configuration\n const text = applyTextTransformations(replacedText, {\n vertical: configuration.vertical,\n uppercase: configuration.uppercase,\n });\n\n const region =\n opts.region ||\n (await centralRegion(layout, LayoutElementType.Textbox, fontSrc, {\n text,\n fontScale: configuration.size ? configuration.size / font.unitsPerEm : undefined,\n }));\n\n const recomputedElement = recomputeTextOnElement(\n {\n id: generate(),\n type: LayoutElementType.Textbox,\n x: region.left,\n y: region.top,\n width: region.width,\n height: region.height,\n align: getTextAlignment(configuration.textAlign, configuration.vertical),\n curved: configuration.curved,\n fill: designInputStep?.color || configuration.colour || \"#000000\",\n fontData,\n layer: region.layer || 0,\n layerIndex: region.layerIndex || nextIndexForLayer(layout, region.layer || 0),\n paths: configuration.paths,\n rotation: region.rotation,\n vertical: configuration.vertical,\n verticalAlign: configuration.verticalAlign || \"middle\",\n algorithm: TextAlgorithm.Traditional,\n fontSize: configuration.size || Math.max(Math.round(region.height * 0.025), 1),\n text,\n input: inputText,\n },\n text,\n );\n const fittedRegion = recalculateTextboxRegion(\n { ...region, height: recomputedElement.height },\n fontData,\n recomputedElement.fontSize,\n recomputedElement?.text?.split(\"\\n\") || [],\n recomputedElement.align,\n );\n return {\n ...recomputedElement,\n x: fittedRegion.left,\n y: fittedRegion.top + (region.height - fittedRegion.height) / 2,\n width: fittedRegion.width,\n height: fittedRegion.height,\n };\n }\n\n static async getShape(\n layout: LayoutData,\n opts: { region?: { item: Region; index: number }; color: string },\n ): Promise<IllustrationElement> {\n const svg = `\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlnsXlink=\"http://www.w3.org/1999/xlink\"\n xmlSpace=\"preserve\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n width=\"1\"\n height=\"1\"\n viewBox=\"0 0 1 1\"\n >\n <rect\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n class=\"spiff-fill-shape\"\n fill=\"${opts.color}\"\n />\n </svg>\n `;\n const colors: { [key: string]: ColorDefinition } = {};\n colors[\"spiff-fill-shape\"] = { browserValue: opts.color };\n\n const region = opts.region?.item || (await centralRegion(layout, LayoutElementType.Illustration));\n\n const elementKey = generate();\n return {\n stepRegion: opts.region?.item,\n stepRegionIndex: opts.region?.index,\n colors,\n id: elementKey,\n svg,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer || 0,\n layerIndex: region.layerIndex || nextIndexForLayer(layout, region.layer || 0),\n immutable: region.immutable,\n };\n }\n\n static async getIllustration(\n layout: LayoutData,\n opts: { region?: { item: Region; index: number }; src: string },\n ): Promise<IllustrationElement> {\n const region = opts.region?.item || (await centralRegion(layout, LayoutElementType.Illustration, opts.src));\n\n const svgData = await generateSVGWithUnknownColors(await getIllustrationBody(opts.src));\n const objectURL = await svgObjectURL(svgData.svg);\n const elementKey = generate();\n return {\n cachedObjectURL: objectURL,\n stepRegion: opts.region?.item,\n stepRegionIndex: opts.region?.index,\n colors: svgData.colors,\n id: elementKey,\n src: opts.src,\n svg: svgData.svg,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer || 0,\n layerIndex: region.layerIndex || nextIndexForLayer(layout, region.layer || 0),\n immutable: region.immutable,\n };\n }\n}\n","import { sortElementsByLayersWithIndex } from \"./CommandContext\";\nimport { svgObjectURL } from \"./Elements/factory\";\nimport {\n LayoutElement,\n LayoutState,\n LayoutsState,\n IllustrationElement,\n FrameElement,\n LayoutElementType,\n TextboxElement,\n} from \"./types\";\nimport { fetchAsString } from \"./util/crossplatform\";\nimport { loadFont } from \"./util/font\";\nimport { generate } from \"./util/guid\";\nimport { generateSVGWithUnknownColors, modifySVGWithElementProperties } from \"./util/illustration\";\n\nexport class ElementNotFoundError extends Error {\n constructor() {\n super(\"Element not found!\");\n Object.setPrototypeOf(this, ElementNotFoundError.prototype);\n }\n}\n\nconst findElement = <T extends LayoutElement>(id: string, layouts: LayoutState[]): T => {\n const layout = findLayoutForElement(id, layouts);\n const element = layout.elements.find((el) => el.id === id);\n return element as T;\n};\n\nconst findLayoutForElement = (id: string, layouts: LayoutState[]): LayoutState => {\n const layoutForElement = Object.values(layouts).find((layoutState: LayoutState) => {\n return layoutState.elements.some((el) => el.id === id);\n });\n if (!layoutForElement) {\n throw new ElementNotFoundError();\n }\n return layoutForElement;\n};\n\nconst updatedLayoutForElement = (element: LayoutElement, state: LayoutState): LayoutState => {\n const updatedElements = [...state.elements.filter((el) => el.id !== element.id), element];\n const layeredElements = sortElementsByLayersWithIndex(updatedElements);\n return {\n layout: state.layout,\n elements: layeredElements,\n modificationID: generate(),\n };\n};\n\nconst rehydrateSerializedLayout = async (transactionState: LayoutsState) => {\n const layoutNamesWithDupes = [...Object.keys(transactionState.layouts)];\n const layoutNames = [...new Set(layoutNamesWithDupes)];\n\n for (let i = 0; i < layoutNames.length; i++) {\n const layoutName = layoutNames[i];\n const layout = transactionState.layouts[layoutName];\n await Promise.all(\n layout.elements.map(async (element) => {\n // Rehydrate any illustrations in the layout.\n if (element.type === \"illustration\") {\n const illustration = element as IllustrationElement;\n if (illustration.src && !illustration.svg) {\n const illustrationBody = await fetchAsString(illustration.src);\n const init = await generateSVGWithUnknownColors(illustrationBody);\n illustration.svg = modifySVGWithElementProperties(\n init.svg,\n illustration.width,\n illustration.height,\n illustration.colors,\n );\n }\n } else if (element.type === \"frame\") {\n const frame = element as FrameElement;\n if (frame.pattern?.colors && frame.pattern?.src) {\n const svgBody = await fetchAsString(frame.pattern?.src);\n const init = await generateSVGWithUnknownColors(svgBody);\n frame.pattern.svg = init.svg;\n }\n }\n // Sanitize values. This likely shouldn't be necessary, but some funky stuff can happen if these values are missing.\n if (isNaN(element.x)) {\n element.x = 0;\n }\n if (isNaN(element.y)) {\n element.y = 0;\n }\n if (isNaN(element.width)) {\n element.width = 0;\n }\n if (isNaN(element.height)) {\n element.height = 0;\n }\n if (isNaN(element.rotation)) {\n element.rotation = 0;\n }\n }),\n );\n }\n\n for (const layoutKey in transactionState.layouts) {\n const illustrations = transactionState.layouts[layoutKey].elements.filter(\n (el) => el.type === LayoutElementType.Illustration,\n );\n for (let i = 0; i < illustrations.length; ++i) {\n const el = illustrations[i] as IllustrationElement;\n if (el.src && el.svg) {\n try {\n el.cachedObjectURL = await svgObjectURL(el.svg);\n } catch (e) {\n // If computing the cached object URL fails, we should proceed anyway.\n console.log(e);\n }\n }\n }\n const fonts = transactionState.layouts[layoutKey].elements.filter(\n (el) => el.type === LayoutElementType.Textbox,\n );\n for (let i = 0; i < fonts.length; ++i) {\n const el = fonts[i] as TextboxElement;\n if (el.fontData?.assetUrl) {\n await loadFont(el.fontData.assetUrl);\n }\n }\n }\n};\n\nexport { findElement, findLayoutForElement, updatedLayoutForElement, rehydrateSerializedLayout };\n","import cloneDeep from \"lodash.clonedeep\";\nimport { ElementNotFoundError, findElement, findLayoutForElement, updatedLayoutForElement } from \"./LayoutsState\";\nimport { recomputeTextOnElement } from \"./text/shared\";\nimport {\n ColorDefinition,\n FontData,\n FrameElement,\n FrameOffsets,\n ILayout,\n IllustrationElement,\n ImageElement,\n LayoutElement,\n LayoutsState,\n LayoutState,\n PatternImageData,\n SerializableWorkflow,\n TextAlgorithm,\n TextboxElement,\n TextFillImage,\n TextFillSpotColor,\n} from \"./types\";\nimport { generate } from \"./util/guid\";\n\n/**\n * An abstract base class from which to extend all potential element commands. These commands\n * follow the command design pattern in software development. To learn more about this pattern\n * take a look at the following link.\n *\n * https://sourcemaking.com/design_patterns/command\n *\n */\nexport abstract class CanvasCommand {\n public abstract apply(state: LayoutsState): LayoutsState;\n\n // Undo/redo support.\n protected oldState?: LayoutsState;\n public undo(): LayoutsState {\n if (!this.oldState) {\n throw new Error(\"Cannot undo.\");\n }\n return this.oldState;\n }\n public overrideOldState(state: LayoutsState) {\n this.oldState = state;\n }\n public sequenceId?: string;\n}\n\n/**\n * Sets the serializable workflow in the reducer state.\n */\nexport class UpdateWorkflowStateCommand extends CanvasCommand {\n private serializableWorkflow: SerializableWorkflow;\n\n constructor(serializableWorkflow: SerializableWorkflow) {\n super();\n this.serializableWorkflow = serializableWorkflow;\n }\n\n public apply(state: LayoutsState): LayoutsState {\n this.oldState = state;\n\n return {\n ...state,\n serializableWorkflow: this.serializableWorkflow,\n };\n }\n}\n\n/**\n * Shifts an element with given ID from its current position to a new position.\n */\nexport class MoveCommand extends CanvasCommand {\n private id: string;\n private x: number;\n private y: number;\n\n constructor(id: string, x: number, y: number) {\n super();\n this.id = id;\n this.x = x;\n this.y = y;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement = {\n ...el,\n x: this.x,\n y: this.y,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\n/**\n * Rotates an element to a given angle in degrees.\n */\nexport class RotateCommand extends CanvasCommand {\n private id: string;\n private angle: number;\n\n constructor(id: string, angle: number) {\n super();\n this.id = id;\n this.angle = angle;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement = {\n ...el,\n rotation: this.angle,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\n/**\n * Updates the width and height of an element to reflect a new size. Negative values will be\n * converted to their absolute value. ie. -10 will become 10.\n */\nexport class ResizeCommand extends CanvasCommand {\n private id: string;\n private width: number;\n private height: number;\n\n constructor(id: string, width: number, height: number) {\n super();\n this.id = id;\n this.width = Math.abs(width);\n this.height = Math.abs(height);\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n let updatedElement = {\n ...el,\n width: this.width,\n height: this.height,\n };\n if (el.type === \"frame\") {\n const frame = updatedElement as FrameElement;\n frame.scaleX = (frame.scaleX * this.width) / el.width;\n frame.scaleY = (frame.scaleY * this.height) / el.height;\n } else if (el.type === \"textbox\") {\n const textbox = updatedElement as TextboxElement;\n const text =\n (!textbox.algorithm || textbox.algorithm === TextAlgorithm.Autosize ? textbox.text : textbox.input) ??\n \"\";\n updatedElement = recomputeTextOnElement(textbox, text, el as TextboxElement);\n }\n\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\n/**\n * Applys a list of command objects to the current state, the final state\n * will be that of all commands applied in the order of left to right.\n */\nexport class GroupCommand extends CanvasCommand {\n private commands: CanvasCommand[];\n constructor(commands: CanvasCommand[]) {\n super();\n this.commands = commands;\n }\n public apply(state: LayoutsState): LayoutsState {\n this.oldState = state;\n\n return this.commands.reduce<LayoutsState>((accumulatedState, curCommand) => {\n return curCommand.apply(accumulatedState);\n }, state);\n }\n}\n\n/*\n * Creates a new layout with a given layout from the server.\n * in layout array. Ensure to write a test for this as well.\n */\nexport class CreateLayoutCommand extends CanvasCommand {\n private layout: ILayout;\n\n constructor(layout: ILayout) {\n super();\n this.layout = layout;\n }\n\n public apply(state: LayoutsState): LayoutsState {\n this.oldState = state;\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [this.layout.id]: {\n elements: [],\n layout: { ...this.layout },\n modificationID: generate(),\n },\n },\n };\n }\n}\n\n/**\n * Clear all elements from a given layout.\n */\nexport class ClearLayoutCommand extends CanvasCommand {\n private panelName: string;\n\n constructor(panelName: string) {\n super();\n this.panelName = panelName;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const layouts = Object.values(state.layouts).map((layout) => {\n const targetLayout = layout.layout.panelId === this.panelName;\n const state: LayoutState = {\n ...layout,\n elements: targetLayout ? [] : [...layout.elements],\n modificationID: generate(),\n };\n return state;\n });\n const finalLayouts: { [key: string]: LayoutState } = {};\n layouts.forEach((layoutState) => {\n finalLayouts[layoutState.layout.id] = layoutState;\n });\n return {\n ...state,\n layouts: finalLayouts,\n };\n }\n}\n\n/**\n * Add an element to the canvas\n */\nexport class CreateElementCommand<T extends LayoutElement> extends CanvasCommand {\n private element: T;\n private layout: ILayout;\n\n /**\n * @param initialParams The initial parameters to be set on this new object\n * @param callback An optional callback function to be notified when the object has been instantiated\n * @param layout\n */\n constructor(element: T, layout: ILayout) {\n super();\n this.element = element;\n this.layout = layout;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n if (!state.layouts[this.layout.id]) {\n state.layouts[this.layout.id] = { layout: this.layout, elements: [], modificationID: \"\" };\n }\n\n const currentElementsInLayout = state.layouts[this.layout.id].elements;\n const duplicateElementAlreadyExists = currentElementsInLayout.find((el) => el.id === this.element.id);\n if (duplicateElementAlreadyExists) {\n throw new Error(\n `Failed to apply new ${this.element.type} element because ID ${this.element.id} already taken`,\n );\n }\n\n if (this.element.productOverlay || currentElementsInLayout.length === 0) {\n const newElements = [...currentElementsInLayout, this.element];\n if (this.element.layerIndex === undefined) {\n this.element.layerIndex = this.assignIndex(this.element, newElements);\n }\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [this.layout.id]: {\n ...state.layouts[this.layout.id],\n elements: newElements,\n modificationID: generate(),\n },\n },\n };\n }\n\n // If product overlay exists then it is the final element.\n const finalElement = currentElementsInLayout[currentElementsInLayout.length - 1];\n const productOverlay = finalElement.productOverlay ? finalElement : null;\n\n // Reindex elements.\n if (productOverlay) {\n currentElementsInLayout.pop();\n }\n let updatedLayoutsForElement: LayoutElement[];\n if (this.element.layerIndex !== null && this.element.layerIndex !== undefined) {\n updatedLayoutsForElement = [...currentElementsInLayout, this.element].sort((a, b) => {\n if (a.layerIndex !== undefined && b.layerIndex !== undefined) {\n return a.layerIndex - b.layerIndex;\n }\n return 0;\n });\n } else {\n const newIndex = this.assignIndex(this.element, currentElementsInLayout);\n this.element.layerIndex = newIndex !== undefined ? newIndex : 0;\n updatedLayoutsForElement = [...currentElementsInLayout, this.element];\n }\n if (productOverlay) {\n updatedLayoutsForElement.push(productOverlay);\n }\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [this.layout.id]: {\n ...state.layouts[this.layout.id],\n elements: updatedLayoutsForElement,\n modificationID: generate(),\n },\n },\n };\n }\n\n // Calculate layer index for an element that doesn't have an explicit index.\n private assignIndex(target: LayoutElement, elementArray: LayoutElement[]): number {\n if (elementArray.length === 0) {\n return 0;\n }\n // We find the highest index used on the layer of the target element.\n const lastIndexOfLayer = elementArray\n .filter((el) => (el.layer || 0) === (target.layer || 0))\n .sort((a, b) => (a.layerIndex || 0) - (b.layerIndex || 0))[elementArray.length - 1]?.layerIndex;\n\n return lastIndexOfLayer !== undefined ? lastIndexOfLayer + 1 : 0;\n }\n}\n\n/**\n * Delete an element on the canvas\n */\nexport class DeleteElementCommand extends CanvasCommand {\n private id: string;\n\n constructor(id: string) {\n super();\n this.id = id;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n let elementFound = false;\n const filteredLayouts = Object.values(state.layouts).map((layout) => {\n const filteredElements = layout.elements.filter((el) => el.id !== this.id);\n if (filteredElements.length !== layout.elements.length) {\n elementFound = true;\n }\n return {\n ...layout,\n elements: layout.elements.filter((el) => {\n return el.id !== this.id;\n }),\n modificationID: generate(),\n };\n });\n if (!elementFound) {\n console.log(`Failed to delete element ${this.id}`);\n }\n const finalLayouts: { [key: string]: LayoutState } = {};\n filteredLayouts.forEach((layoutState) => {\n finalLayouts[layoutState.layout.id] = layoutState;\n });\n return {\n ...state,\n layouts: finalLayouts,\n };\n }\n}\n\nexport class CloneElementCommand extends CanvasCommand {\n private el: LayoutElement;\n private layout: ILayout;\n\n constructor(el: LayoutElement, layout: ILayout) {\n super();\n this.el = cloneDeep(el);\n this.layout = layout;\n this.el.id = generate();\n this.el.x += 5;\n this.el.y += 5;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n return new CreateElementCommand(this.el, this.layout).apply(state);\n }\n}\n\nexport class FontColorCommand extends CanvasCommand {\n private id: string;\n private color: string;\n private textFillSpotColor?: TextFillSpotColor;\n\n constructor(id: string, color: string, textFillSpotColor?: TextFillSpotColor) {\n super();\n this.id = id;\n this.color = color;\n this.textFillSpotColor = textFillSpotColor;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts)) as TextboxElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n\n const updatedElement = {\n ...el,\n fill: this.color,\n fillSpotColorDefinition: this.textFillSpotColor,\n textFillImage: undefined,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class FontImageFillCommand extends CanvasCommand {\n private id: string;\n private imageFill: TextFillImage;\n\n constructor(id: string, imageFill: TextFillImage) {\n super();\n this.id = id;\n this.imageFill = imageFill;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts)) as TextboxElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n\n const updatedElement = {\n ...el,\n textFillImage: this.imageFill,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class FontSizeCommand extends CanvasCommand {\n private id: string;\n private size: number;\n\n constructor(id: string, size: number) {\n super();\n this.id = id;\n this.size = size;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts)) as TextboxElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement: TextboxElement = {\n ...el,\n fontSize: this.size,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n // FIXME: The autosize algorithm injects newlines outside of the commands, we need\n // to ignore the input text in that case. See getCalculatedMixins within recomputeTextOnElement\n // The logic for autosize should be shifted into there in the future.\n const text = (!el.algorithm || el.algorithm === TextAlgorithm.Autosize ? el.text : el.input) ?? \"\";\n const updatedLayout = updatedLayoutForElement(recomputeTextOnElement(updatedElement, text), layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class FontAlgorithmCommand extends CanvasCommand {\n private id: string;\n private algorithm: TextAlgorithm;\n\n constructor(id: string, algorithm: TextAlgorithm) {\n super();\n this.id = id;\n this.algorithm = algorithm;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement = {\n ...el,\n algorithm: this.algorithm,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class FontSourceCommand extends CanvasCommand {\n private id: string;\n private fontData: FontData;\n\n constructor(id: string, fontData: FontData) {\n super();\n this.id = id;\n this.fontData = fontData;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts)) as TextboxElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement: TextboxElement = {\n ...el,\n fontData: this.fontData,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const text = (!el.algorithm || el.algorithm === TextAlgorithm.Autosize ? el.text : el.input) ?? \"\";\n const updatedLayout = updatedLayoutForElement(recomputeTextOnElement(updatedElement, text), layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class FontAlignmentCommand extends CanvasCommand {\n private id: string;\n private align: \"left\" | \"center\" | \"right\";\n\n constructor(id: string, align: \"left\" | \"center\" | \"right\") {\n super();\n this.id = id;\n this.align = align;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts)) as TextboxElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement: TextboxElement = {\n ...el,\n align: this.align,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class UpdateFramePattern extends CanvasCommand {\n private id: string;\n private imageData: PatternImageData;\n private offsets: FrameOffsets;\n\n constructor(id: string, imageData: PatternImageData, offsets: FrameOffsets) {\n super();\n this.id = id;\n this.imageData = imageData;\n this.offsets = offsets;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const targetLayout = findLayoutForElement(this.id, Object.values(state.layouts));\n const index = targetLayout.elements.findIndex((el) => el.id === this.id);\n const existingPattern = (targetLayout.elements[index] as FrameElement).pattern;\n\n const newElements = [...targetLayout.elements];\n newElements.splice(index, 1, {\n ...targetLayout.elements[index],\n pattern: {\n ...existingPattern,\n src: this.imageData.src,\n x: this.offsets.x,\n y: this.offsets.y,\n width: this.imageData.width,\n height: this.imageData.height,\n scaleX: this.offsets.zoom,\n scaleY: this.offsets.zoom,\n svg: this.imageData.svg,\n colors: this.imageData.colors,\n },\n } as FrameElement); // FIXME: How can we assign LayoutElement correctly?\n\n const newLayout: LayoutState = {\n ...targetLayout,\n elements: newElements,\n modificationID: generate(),\n };\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [targetLayout.layout.id]: newLayout,\n },\n };\n }\n}\n\nexport class UpdateFrameThresholdSettingsCommand extends CanvasCommand {\n private id: string;\n private useThreshold: boolean;\n private invertThreshold: boolean;\n private threshold: number;\n private thresholdSaturation: number;\n\n constructor(\n id: string,\n useThreshold: boolean,\n invertThreshold: boolean,\n threshold: number,\n thresholdSaturation: number,\n ) {\n super();\n this.id = id;\n this.useThreshold = useThreshold;\n this.invertThreshold = invertThreshold;\n this.threshold = threshold;\n this.thresholdSaturation = thresholdSaturation;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n const el = findElement(this.id, Object.values(state.layouts)) as FrameElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n\n const updatedElement = {\n ...el,\n useThreshold: this.useThreshold,\n invertThreshold: this.invertThreshold,\n threshold: this.threshold,\n thresholdSaturation: this.thresholdSaturation,\n };\n\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class UpdateImageSourceCommand extends CanvasCommand {\n private id: string;\n private src: string;\n\n constructor(id: string, src: string) {\n super();\n this.id = id;\n this.src = src;\n }\n\n public apply(state: LayoutsState): LayoutsState {\n this.oldState = state;\n const el = findElement(this.id, Object.values(state.layouts)) as ImageElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement: ImageElement = {\n ...el,\n src: this.src,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\n/**\n * TextChange will modify the text displayed in a text box\n */\nexport class TextChangeCommand extends CanvasCommand {\n private id: string;\n private text: string;\n\n constructor(id: string, text: string) {\n super();\n this.id = id;\n this.text = text;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n const el = findElement(this.id, Object.values(state.layouts)) as TextboxElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(recomputeTextOnElement(el, this.text, el), layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class TextStrokeCommand extends CanvasCommand {\n private id: string;\n private strokeColor: ColorDefinition | undefined;\n private strokeThickness: string | undefined;\n\n constructor(id: string, strokeColor: ColorDefinition | undefined, strokeThickness: string | undefined) {\n super();\n this.id = id;\n this.strokeColor = strokeColor;\n this.strokeThickness = strokeThickness;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n const el = findElement(this.id, Object.values(state.layouts)) as TextboxElement;\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const updatedElement = {\n ...el,\n strokeColor: this.strokeColor,\n strokeThickness: this.strokeThickness,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class IllustrationColorCommand extends CanvasCommand {\n private id: string;\n private className: string;\n private fill: string | ColorDefinition;\n\n constructor(id: string, className: string, fill: string | ColorDefinition) {\n super();\n this.id = id;\n this.className = className;\n this.fill = fill;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const newColors = (el as IllustrationElement).colors || {};\n const oldColor = newColors[this.className];\n\n if (typeof this.fill === \"string\") {\n newColors[this.className] = {\n browserValue: this.fill,\n spotColor: oldColor?.spotColor,\n pmsValue: oldColor?.pmsValue,\n };\n } else {\n newColors[this.className] = {\n browserValue: this.fill.browserValue,\n spotColor: oldColor?.spotColor,\n pmsValue: this.fill.pmsValue,\n };\n }\n\n const updatedElement = {\n ...el,\n colors: newColors,\n };\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class IllustrationCacheCommand extends CanvasCommand {\n private id: string;\n private svgBody: string;\n private objectURL: string;\n\n constructor(id: string, svgBody: string, objectURL: string) {\n super();\n this.id = id;\n this.svgBody = svgBody;\n this.objectURL = objectURL;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n\n const updatedElement = {\n ...el,\n svg: this.svgBody,\n cachedObjectURL: this.objectURL,\n };\n\n const layout = findLayoutForElement(el.id, Object.values(state.layouts));\n const updatedLayout = updatedLayoutForElement(updatedElement, layout);\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayout,\n },\n };\n }\n}\n\nexport class BringToFrontCommand extends CanvasCommand {\n private id: string;\n\n /**\n * @param id The targeted element to bring to the front.\n */\n constructor(id: string) {\n super();\n this.id = id;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const layout = Object.values(state.layouts).find((l) => l.elements.find((el) => el.id === this.id));\n if (!layout) {\n throw new Error(\"Layout missing from state!\");\n }\n\n // We shift the element in front of the last index and then reorganise the layer indices\n // to suite the new ordering of the element array.\n const fromIndex = layout.elements.findIndex((el) => el.id === this.id);\n layout.elements.push(layout.elements.splice(fromIndex, 1)[0]);\n\n const updatedElements = [...layout.elements];\n updatedElements.forEach((el, idx) => (el.layerIndex = idx));\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: {\n ...state.layouts[layout.layout.id],\n elements: updatedElements,\n modificationID: generate(),\n },\n },\n };\n }\n}\n\nexport class BringToBackCommand extends CanvasCommand {\n private id: string;\n\n /**\n * @param id The targeted element to bring to the back.\n */\n constructor(id: string) {\n super();\n this.id = id;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const layout = Object.values(state.layouts).find((l) => l.elements.find((el) => el.id === this.id));\n if (!layout) {\n throw new Error(\"Layout missing from state!\");\n }\n\n // We shift the element backwards and then reorganise the layer indices\n // to suite the new ordering of the element array.\n const fromIndex = layout.elements.findIndex((el) => el.id === this.id);\n\n layout.elements.splice(fromIndex, 1);\n layout.elements.unshift(el);\n\n const updatedElements = [...layout.elements];\n const element = updatedElements.splice(fromIndex, 1)[0];\n updatedElements.splice(fromIndex, 0, element);\n updatedElements.forEach((el, idx) => (el.layerIndex = idx));\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: {\n ...state.layouts[layout.layout.id],\n elements: updatedElements,\n modificationID: generate(),\n },\n },\n };\n }\n}\n\n/**\n * Bring an element forward by one layer. Does nothing if the element is already at the front.\n */\nexport class BringForwardCommand extends CanvasCommand {\n private id: string;\n\n /**\n * @param id The targeted element to bring to the front.\n */\n constructor(id: string) {\n super();\n this.id = id;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const layout = Object.values(state.layouts).find((l) => l.elements.find((el) => el.id === this.id));\n if (!layout) {\n throw new Error(\"Layout missing from state!\");\n }\n\n // We shift the element forward and then reorganise the layer indices\n // to suite the new ordering of the element array.\n const fromIndex = layout.elements.findIndex((el) => el.id === this.id);\n const toIndex = fromIndex + 1;\n const updatedElements = [...layout.elements];\n const element = updatedElements.splice(fromIndex, 1)[0];\n updatedElements.splice(toIndex, 0, element);\n updatedElements.forEach((el, idx) => (el.layerIndex = idx));\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: {\n ...state.layouts[layout.layout.id],\n elements: updatedElements,\n modificationID: generate(),\n },\n },\n };\n }\n}\n\n/**\n * Send an element backwards by one layer. Does nothing if the element is already at the back.\n */\nexport class SendBackwardsCommand extends CanvasCommand {\n private id: string;\n\n /**\n * @param id The targeted element to bring to the front.\n */\n constructor(id: string) {\n super();\n this.id = id;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n const layout = Object.values(state.layouts).find((l) => l.elements.find((el) => el.id === this.id));\n if (!layout) {\n throw new Error(\"Layout missing from state!\");\n }\n\n // We shift the element backwards and then reorganise the layer indices\n // to suite the new ordering of the element array.\n const fromIndex = layout.elements.findIndex((el) => el.id === this.id);\n const toIndex = fromIndex - 1;\n const updatedElements = [...layout.elements];\n const element = updatedElements.splice(fromIndex, 1)[0];\n updatedElements.splice(toIndex, 0, element);\n updatedElements.forEach((el, idx) => (el.layerIndex = idx));\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: {\n ...state.layouts[layout.layout.id],\n elements: updatedElements,\n modificationID: generate(),\n },\n },\n };\n }\n}\n\n/**\n * Set the layer value of an element. The layer is half of the system involved with\n * determining order.\n */\nexport class LayerCommand extends CanvasCommand {\n private id: string;\n private value: number;\n\n /**\n * @param id The targeted element to change layer of.\n * @param value The new layer to set this element within.\n */\n constructor(id: string, value: number) {\n super();\n this.id = id;\n this.value = value;\n }\n\n public apply(state: LayoutsState) {\n this.oldState = state;\n\n const el = findElement(this.id, Object.values(state.layouts));\n if (!el.id) {\n throw new ElementNotFoundError();\n }\n\n const layout = Object.values(state.layouts).find((l) => l.elements.find((el) => el.id === this.id));\n if (!layout) {\n throw new Error(\"Layout missing from state!\");\n }\n\n return {\n ...state,\n layouts: {\n ...state.layouts,\n [layout.layout.id]: updatedLayoutForElement({ ...el, layer: this.value }, layout),\n },\n };\n }\n}\n","import { CanvasCommand, CreateElementCommand } from \"../../command\";\nimport { svgObjectURL } from \"../../Elements/factory\";\nimport { ILayout, IllustrationElement, ImageElement, LayoutElementType, Region, RegionElement, SilentStepData, Step, StepType } from \"../../types\";\nimport { Product } from \"../../types\";\nimport { fetchAsString } from \"../../util/crossplatform\";\nimport { LayoutNotFoundError, MisconfigurationError } from \"../../util/exception\";\nimport { generate } from \"../../util/guid\";\nimport { generateSVGWithUnknownColors } from \"../../util/illustration\";\n\nexport interface SilentStepTriggerResult {\n regionElement: RegionElement;\n command: CanvasCommand;\n}\n\nexport class SilentStepHandler {\n private configuration: Step<SilentStepData>;\n private layouts: ILayout[];\n private product?: Product;\n\n constructor(config: Step<SilentStepData>, layouts: ILayout[], product?: Product) {\n this.configuration = config;\n this.layouts = layouts;\n this.product = product ? product : undefined;\n }\n\n async trigger(): Promise<SilentStepTriggerResult[]> {\n if (!this.configuration.data.regions) {\n throw new MisconfigurationError(this.configuration, \"Missing regions.\");\n }\n if (this.configuration.type === StepType.SilentIllustration) {\n const promises = this.configuration.data.regions.map(this.processRegion);\n return Promise.all(promises);\n } else if (this.configuration.type === StepType.ProductOverlay) {\n return Promise.all(\n this.configuration.data.regions.map((region) => {\n const layout = this.layouts.find((layout: ILayout) => region.panelId === layout.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n return this.processRegion(region);\n }),\n );\n } else {\n return Promise.reject(\"Unknown silent step. This is a bug\");\n }\n }\n\n private processRegion = async (region: Region): Promise<SilentStepTriggerResult> => {\n const layout = this.layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n\n let assetUrl = \"\";\n if (this.configuration.type === StepType.ProductOverlay) {\n // Check related product for a overlay key\n let assetFromProduct = \"\";\n if (this.product?.overlayImageUrl) {\n assetFromProduct = this.product.overlayImageUrl;\n }\n assetUrl = assetFromProduct;\n if (!assetFromProduct) {\n throw new MisconfigurationError(this.configuration, \"Couldn't find an asset for product overlay step\");\n }\n }\n\n const assetType = this.evaluateAssetType();\n\n if (assetType === LayoutElementType.Image) {\n const assetUrl =\n this.configuration.type === StepType.SilentIllustration\n ? (this.configuration.data.asset?.fileLink)\n : (this.product?.overlayImageUrl);\n if (!assetUrl) {\n throw new Error(\"Undefined raster silent step source\");\n }\n const newElement: ImageElement = {\n stepName: this.configuration.stepName,\n id: generate(),\n src: assetUrl,\n type: assetType,\n y: region.top,\n x: region.left,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n productOverlay: this.configuration.type === StepType.ProductOverlay ? true : undefined,\n rotation: region.rotation,\n excludeFromExport: this.configuration.data.excludeFromPrint,\n preserveAspectRatio: \"none\",\n };\n return {\n regionElement: {\n id: newElement.id,\n region,\n },\n command: new CreateElementCommand<ImageElement>(newElement, layout),\n };\n } else {\n const src =\n this.configuration.type === StepType.SilentIllustration ? this.configuration.data.asset?.fileLink : assetUrl;\n const getIllustrationBody = async (): Promise<string> => {\n return new Promise((resolve, reject) => {\n if (!src) {\n reject(\"Undefined vector silent step source\");\n return;\n }\n fetchAsString(src, true)\n .then((svg) => {\n resolve(svg);\n })\n .catch((e) => console.error(e));\n });\n };\n const svgData = await generateSVGWithUnknownColors(await getIllustrationBody());\n const newElement: IllustrationElement = {\n stepName: this.configuration.stepName,\n id: generate(),\n cachedObjectURL: await svgObjectURL(svgData.svg),\n src: src,\n svg: svgData.svg,\n colors: svgData.colors,\n type: assetType,\n y: region.top,\n x: region.left,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n rotation: region.rotation,\n immutable: region.immutable,\n productOverlay: this.configuration.type === StepType.ProductOverlay ? true : undefined,\n excludeFromExport: this.configuration.data.excludeFromPrint,\n };\n return {\n regionElement: {\n id: newElement.id!,\n region,\n },\n command: new CreateElementCommand<IllustrationElement>(newElement, layout),\n };\n }\n };\n\n private evaluateAssetType(): LayoutElementType {\n // Try to determine the type by asset path.\n const url =\n this.configuration.type === StepType.ProductOverlay && this.product?.overlayImageUrl\n ? this.product.overlayImageUrl.toLowerCase()\n : this.configuration.data.asset?.fileLink?.toLowerCase().split(\"?\")[0];\n if (\n url?.startsWith(\"data:image/png\") ||\n url?.endsWith(\".jpeg\") ||\n url?.endsWith(\".jpg\") ||\n url?.endsWith(\".png\")\n ) {\n return LayoutElementType.Image;\n }\n if (url?.endsWith(\".svg\") || url?.startsWith(\"image/svg+xml\")) {\n return LayoutElementType.Illustration;\n }\n return LayoutElementType.Illustration;\n }\n}\n","import { spiffCoreConfiguration } from \"../Configuration\";\nimport { ResourceGenerationError } from \"../util/exception\";\nimport { fetch } from \"../util/crossplatform\";\n\nexport const shortenUrl = async (longUrl: string): Promise<string> => {\n const shortenerUrl = `${spiffCoreConfiguration.getServicesApiUrl()}/shortener`;\n try {\n const response = await fetch(shortenerUrl, {\n method: \"POST\",\n body: JSON.stringify({ longUrl }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n const json = await response.json();\n return json.shortUrl;\n } catch (e) {\n console.error(e);\n throw new ResourceGenerationError(\"Failed to shorten URL, see console.\");\n }\n};\n","// Something that periodically checks a condition and\n// executes a callback once that condition is true.\nexport class Poller {\n // The ID of the window setInterval call.\n private pollingId: number;\n\n // The amount of times that the condition has been checked.\n private attempts: number;\n\n // How long to wait between each poll.\n private readonly interval: number;\n\n // The maximum amount of times to check the condition.\n private readonly maxAttempts: number;\n\n // The condition to check.\n private readonly predicate: () => Promise<boolean>;\n\n // The function to execute when the condition is fulfilled.\n private readonly onSuccess: () => void;\n\n // The function to execute when the maximum polling attempts have been\n // hit and no success result was returned by the predicate.\n private readonly onFailure: () => void;\n\n private async poll() {\n try {\n if (await this.predicate()) {\n this.onSuccess();\n if (this.pollingId > -1) {\n window.clearInterval(this.pollingId);\n }\n return;\n }\n } catch (e) {\n //console.log(`Poller attempt ${this.attempts + 1} failed. Max attempts: ${this.maxAttempts}`);\n }\n this.attempts += 1;\n if (this.attempts < this.maxAttempts) {\n this.pollingId = window.setTimeout(this.poll.bind(this), this.interval);\n } else {\n this.onFailure();\n }\n }\n\n /**\n * Constructs a new polling service.\n * @param predicate An async function that returns true when polling has returned a successful result.\n * @param onSuccess The callback to be called when polling has returned a successful result.\n * @param onFailure The callback to be called when polling has returned a failed result.\n * @param interval The number of milliseconds to wait between each poll.\n * @param maxAttempts The maximum amount of times to check the condition.\n */\n constructor(\n predicate: () => Promise<boolean>,\n onSuccess: () => void,\n onFailure: () => void,\n interval: number = 3000,\n maxAttempts: number = 10,\n ) {\n this.onSuccess = onSuccess;\n this.onFailure = onFailure;\n this.predicate = predicate;\n this.attempts = 0;\n this.pollingId = -1;\n this.interval = interval;\n this.maxAttempts = maxAttempts;\n this.poll();\n }\n}\n","import {\n StepService,\n RegionElement,\n CommandWithFollowup,\n DigitalContentStepData,\n Step,\n LayoutsState,\n Region,\n ILayout,\n ImageElement,\n LayoutElementType,\n} from \"../../types\";\nimport { toString as urlToString } from \"qrcode\";\nimport { shortenUrl } from \"../shortener\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { Poller } from \"../../util/Poller\";\nimport {\n LayoutNotFoundError,\n MisconfigurationError,\n ResourceGenerationError,\n ResourceNotFoundError,\n} from \"../../util/exception\";\nimport { getAssets } from \"../asset\";\nimport { CreateElementCommand, DeleteElementCommand, GroupCommand } from \"../../command\";\nimport { generate } from \"../../util/guid\";\n\nexport const MAX_UPLOAD_SIZE_IN_MB = 100;\n\nclass DigitalContentStepService implements StepService<DigitalContentStepData> {\n async init(\n stepData: Step<DigitalContentStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n }\n return null;\n }\n\n private async reload(\n stepData: Step<DigitalContentStepData>,\n workflowManager: WorkflowManager,\n reducerState: LayoutsState,\n ) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n await workflowManager.setSelectionsAndElements(stepData.stepName, [], regionElements, async () => {\n const shortUrl = serializedStep?.storage?.videoShortUrl;\n const url = serializedStep?.storage?.videoUrl;\n workflowManager.updateStorage(stepData.stepName, {\n videoShortUrl: shortUrl,\n videoUrl: url,\n });\n });\n }\n\n async regenerateQRCode(\n elements: RegionElement[],\n assetKey: string,\n workflowManager: WorkflowManager,\n stepData: Step<DigitalContentStepData>,\n ) {\n const getMpegLink = async () => {\n const asset = (await getAssets([assetKey]))[0];\n const link = asset?.versions?.find((v) => v.name === \"mpeg4\")?.link;\n return { asset, link };\n };\n\n // Asset versions are attached to the asset shortly after asset upload. We poll to find these versions and\n // grab the link for the mp4 variant.\n const videoLink = await new Promise<{ rel: string; href: string }>((resolve, reject) => {\n new Poller(\n async () => !!(await getMpegLink()).link,\n async () => {\n const linkData = await getMpegLink();\n if (!linkData.link || !linkData.link) {\n throw new ResourceNotFoundError(linkData.asset);\n }\n resolve({\n rel: \"mpeg4\",\n href: linkData.link,\n });\n },\n () => {\n reject(\"Poller timed out with 40 attempts @ 3 second interval\");\n },\n 3000,\n 40,\n );\n });\n\n elements.forEach((elem) => workflowManager.getCommandDispatcher()(new DeleteElementCommand(elem.id)));\n const protocolPrefix = stepData.data.baseUrl.slice(0, 4) === \"http\" ? \"\" : \"https://\";\n const urlBuilder = new URL(protocolPrefix + stepData.data.baseUrl);\n urlBuilder.searchParams.append(\"video\", btoa(JSON.stringify([videoLink])));\n\n //iOS does not recognise a URL without the trailing slash on the pathname,\n urlBuilder.pathname = urlBuilder.pathname + (urlBuilder.pathname.slice(-1) === \"/\" ? \"\" : \"/\");\n\n const builtUrl = urlBuilder.toString();\n if (builtUrl.length >= 2000) {\n throw new ResourceGenerationError(\"Cannot create QR code, URL too long.\");\n }\n const shortUrl = await shortenUrl(builtUrl);\n\n if (!stepData.data || !stepData.data.regions) {\n throw new MisconfigurationError(stepData, \"Missing regions.\");\n }\n const regionElements = await this.regionElements(stepData);\n const result = await this.command(shortUrl, regionElements, workflowManager, stepData.stepName);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n await workflowManager.setSelectionsAndElements(stepData.stepName, [], regionElements, async () => {\n workflowManager.updateStorage(stepData.stepName, {\n videoShortUrl: shortUrl,\n videoUrl: videoLink.href,\n });\n });\n\n return shortUrl;\n }\n\n private async regionElements(stepData: Step<DigitalContentStepData>): Promise<RegionElement[]> {\n const createElementForRegion = (region: Region, regionIndex: number): RegionElement => {\n const elementKey = generate();\n return { id: elementKey, region, regionIndex };\n };\n\n return stepData.data.regions.map(createElementForRegion);\n }\n\n private async command(\n shortUrl: string,\n regionElements: RegionElement[],\n workflowManager: WorkflowManager,\n stepName: string,\n ): Promise<CommandWithFollowup | null> {\n const layouts = workflowManager.getLayouts();\n const base64data = btoa(await urlToString(shortUrl, { type: \"svg\" }));\n const dataUri = `data:image/svg+xml;base64,${base64data}`;\n const commands = regionElements.map((regionElement) => {\n const region = regionElement.region;\n const layout = layouts.find((layout: ILayout) => layout.panelId === region?.panelId);\n\n if (!layout && region) {\n throw new LayoutNotFoundError(region);\n }\n\n if (layout && !region) {\n throw new Error(\"Region not found\");\n }\n\n if (!layout || !region) {\n throw new Error(\"Neither a region or layout found!\");\n }\n\n return new CreateElementCommand<ImageElement>(\n {\n stepRegion: region,\n stepRegionIndex: regionElement.regionIndex,\n stepName: stepName,\n id: regionElement.id,\n src: dataUri,\n type: LayoutElementType.Image,\n y: region.top,\n x: region.left,\n width: region.width,\n height: region.height,\n rotation: 0,\n },\n layout,\n );\n });\n return { command: new GroupCommand(commands), followup: async () => {} };\n }\n}\n\nexport const digitalContentStepService = new DigitalContentStepService();\n","import { optionService } from \"../../option\";\nimport {\n RegionElement,\n StepService,\n CommandWithFollowup,\n FrameData,\n ColorOption,\n GlobalPropertyStateFileUploadStorage,\n FrameStepData,\n Step,\n LayoutsState,\n VariantResource,\n Asset,\n Region,\n ILayout,\n FrameElement,\n LayoutElementType,\n ColorDefinition,\n} from \"../../../types\";\nimport { Poller } from \"../../../util/Poller\";\nimport { WorkflowManager } from \"../../../WorkflowManager\";\nimport { assetService } from \"../../asset\";\nimport { FrameService } from \"./Service\";\nimport { LayoutNotFoundError, ResourceGenerationError, ResourceNotFoundError } from \"../../../util/exception\";\nimport { AssetNotFoundError } from \"../../../util/exception\";\nimport { browserColorToHex } from \"../../../util/color\";\nimport { fetch, fetchAsArrayBuffer, fetchAsString } from \"../../../util/crossplatform\";\nimport {\n calculateOffsets,\n generateDefaultRectangleFrameSvg,\n getFrameData,\n GetSVGDimensions,\n patternImageDataCache,\n} from \"../../../util/frame\";\nimport { CreateElementCommand, DeleteElementCommand, GroupCommand } from \"../../../command\";\nimport { generateSVGWithUnknownColors } from \"../../../util/illustration\";\nimport { getAttributesFromArrayBuffer } from \"../../../util/image\";\nimport { generate } from \"../../../util/guid\";\nimport { FrameStepHandle } from \"../../../stepHandles/steps/frame\";\n\nexport interface FrameCreateOpts {\n stepName?: string;\n frameData: FrameData;\n disablePlaceholder?: boolean;\n pattern?: any;\n}\n\nclass FrameStepService implements StepService<FrameStepData> {\n async init(\n stepData: Step<FrameStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n // If existing state then use it.\n const reducerStep = reducerState?.serializableWorkflow.steps.find(\n (step) => step.stepName === stepData.stepName,\n );\n if (\n (reducerStep?.storage && Object.keys(reducerStep.storage).length !== 0) ||\n (reducerStep?.selectedVariants && reducerStep.selectedVariants.length !== 0)\n ) {\n await this.reload(stepData, workflowManager, reducerState!);\n return null;\n }\n\n if (stepData.mandatory) {\n workflowManager.setMandatoryFulfilled(stepData.stepName, false);\n }\n workflowManager.markStepsAsInitialised([stepData.stepName]);\n\n // When a bundle is present we load the frame aspect.\n let initialPatternOverride: string | undefined = undefined;\n const bundle = workflowManager.getWorkflowExperience().getBundle();\n if (bundle && stepData.globalPropertyAspectConfigurations) {\n const stateManager = bundle.getGlobalPropertyStateManager();\n // FIXME: This might not be robust enough. I think we support more than Upload on frames.\n const uploadAspect = stepData.globalPropertyAspectConfigurations[0];\n const key = stateManager.getAspectStorage<GlobalPropertyStateFileUploadStorage>(uploadAspect.aspectName!);\n if (key && key.originalAssetKey) {\n initialPatternOverride = (await assetService.getLocalOrFromServer(key.originalAssetKey)).fileLink;\n }\n }\n\n // If an option exists then determine if there's a default variant.\n if (stepData.option && stepData.option.variants && stepData.option.variants.length > 0) {\n const option = stepData.option;\n const defaultVariant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n if (defaultVariant) {\n return this.selectVariantCommand(\n stepData,\n defaultVariant,\n [],\n workflowManager,\n undefined,\n initialPatternOverride ? initialPatternOverride : stepData.data.placeholderImageUrl,\n );\n }\n return null;\n }\n\n // If no option then create a square box.\n return this.selectVariantCommand(\n stepData,\n undefined,\n [],\n workflowManager,\n undefined,\n initialPatternOverride ? initialPatternOverride : stepData.data.placeholderImageUrl,\n );\n }\n\n private async reload(stepData: Step<FrameStepData>, workflowManager: WorkflowManager, reducerState: LayoutsState) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n if (!stepData.option || (stepData.option.variants || []).length === 0) {\n const frameSvgs = stepData.data.regions.map((region) => generateDefaultRectangleFrameSvg(region));\n workflowManager.updateStorage(stepData.stepName, {\n currentFrameSources: frameSvgs,\n });\n }\n if (serializedStep) {\n const finish = async () => {\n const storageColors = serializedStep.storage?.colors;\n const patternSrc = serializedStep.storage?.framePatternSrc;\n const offsets = serializedStep.storage?.frameOffsetsList;\n workflowManager.updateMetadata(stepData.stepName, {\n frameOffsetsList: offsets,\n framePatternSrc: patternSrc,\n });\n if (patternSrc) {\n const frameService = (\n workflowManager.getWorkflowExperience().getStepById(stepData.stepName) as\n | undefined\n | FrameStepHandle\n )?.frameService;\n if (!frameService) throw new Error(\"Frame service unavailable, cannot load pattern!\");\n // Load the pattern and recalculate offsets. Deserialized offsets will potentially be applied after.\n await this.loadPatternFromString(patternSrc, frameService, true, storageColors);\n workflowManager.updateMetadata(stepData.stepName, { image: patternSrc });\n workflowManager.updateStorage(stepData.stepName, {\n framePatternSrc: patternSrc,\n });\n this.validateColorCount(stepData, workflowManager);\n }\n if (offsets?.some((offset) => offset.zoom)) {\n const frameService = (\n workflowManager.getWorkflowExperience().getStepById(stepData.stepName) as\n | undefined\n | FrameStepHandle\n )?.frameService;\n if (!frameService) throw new Error(\"Frame service unavailable, cannot load pattern!\");\n frameService.updateOffsets(offsets);\n }\n workflowManager.setMandatoryFulfilled(stepData.stepName, true);\n };\n\n if (serializedStep.selectedVariants && serializedStep.selectedVariants.length > 0) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (stepData.option && variantId) {\n const variant = stepData.option.variants?.find((variant) => variant.id === variantId);\n if (variant) {\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [variant],\n regionElements,\n async () => {\n const frameSvgs = await Promise.all(\n stepData.data.regions.map((region) => this.frameSourceSvg(variant, region)),\n );\n workflowManager.updateStorage(stepData.stepName, { currentFrameSources: frameSvgs });\n await finish();\n },\n );\n }\n }\n } else {\n await workflowManager.setSelectionsAndElements(stepData.stepName, [], regionElements, finish);\n }\n }\n }\n\n async availableColors(stepData: Step<FrameStepData>, _workflowManager: WorkflowManager): Promise<ColorOption[]> {\n const colorOption = await optionService.ensureFullOption(stepData.data.colorOption);\n return (\n colorOption?.variants?.map((variant: VariantResource) => {\n return {\n fill: variant.color,\n stroke: variant.color,\n variant,\n pmsValue: variant.name,\n };\n }) ?? []\n );\n }\n\n selectImage(\n stepData: Step<FrameStepData>,\n asset: Asset,\n workflowManager: WorkflowManager,\n recalculateOffsets = true,\n ): Promise<void> {\n const assetSrc = FrameStepService.patternSource(asset);\n const existingSrc = workflowManager.getStepStorage(stepData.stepName)?.framePatternSrc;\n if (existingSrc && existingSrc === assetSrc) {\n return Promise.resolve();\n }\n workflowManager.setEditedStatus(stepData.stepName, true);\n const src = asset.fileLink || \"\";\n\n // TODO: Use mime type instead of extension\n if (src.endsWith(\".pdf\") || src.endsWith(\".eps\") || src.endsWith(\".ai\")) {\n // In the case of PDF we need to transcode first as\n // we don't have first class support for PDF files in frames.\n return new Promise<void>((resolve) => {\n workflowManager.addPoller(\n new Poller(\n async () => {\n const assetResponse = await assetService.getFromServer(asset.key || \"\");\n const svgVersion = assetResponse.versions?.find((v) => v.name === \"svg\");\n if (!svgVersion) return false;\n const fetchResult = await fetch(svgVersion.link);\n return fetchResult.status === 200;\n },\n () => {\n assetService.getLocalOrFromServer(asset.key || \"\").then((response) => {\n this.loadPatternFromAsset(response, stepData, workflowManager, recalculateOffsets).then(\n resolve,\n );\n });\n },\n () => {\n throw new ResourceGenerationError(\"Failed to resolve transcoded PDF\");\n },\n ),\n );\n });\n } else {\n return this.loadPatternFromAsset(asset, stepData, workflowManager, recalculateOffsets);\n }\n }\n\n async selectVariant(\n stepData: Step<FrameStepData>,\n variant: VariantResource | undefined,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n setFrameIsUpdating?: (status: boolean) => void,\n ) {\n const result = await this.selectVariantCommand(\n stepData,\n variant,\n elements,\n workflowManager,\n setFrameIsUpdating,\n );\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n getCreateElementCommand(\n id: string,\n region: Region,\n regionIndex: number | undefined,\n layout: ILayout,\n options: FrameCreateOpts,\n ) {\n return new CreateElementCommand<FrameElement>(\n {\n id,\n type: LayoutElementType.Frame,\n x: region.left,\n y: region.top,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n rotation: region.rotation,\n scaleX: region.width / options.frameData.width,\n scaleY: region.height / options.frameData.height,\n path: options.frameData.path,\n dataWidth: options.frameData.width,\n dataHeight: options.frameData.height,\n stepRegion: region,\n stepRegionIndex: regionIndex,\n stepName: options.stepName,\n disablePlaceholder: options.disablePlaceholder,\n pattern: options.pattern,\n immutable: region.immutable,\n },\n layout,\n );\n }\n\n async loadPatternFromString(\n src: string,\n frameService: FrameService,\n recalculateOffsets = true,\n colors:\n | {\n [key: string]: ColorDefinition;\n }\n | undefined = undefined,\n colorSafeSvg?: boolean,\n ) {\n if (src.endsWith(\"svg\")) {\n const svgData = await GetSVGDimensions(src);\n const width = svgData.width;\n const height = svgData.height;\n const originalSvg = await fetchAsString(src);\n if (colorSafeSvg) {\n const matches = originalSvg.match(/<(image|linearGradient|radialGradient)(\\s|>|\\/>)/gim);\n if (matches && matches.length > 0) {\n throw new Error(\n \"Vector files may not include images or gradients when a color limit is specified.\",\n );\n }\n }\n const svgAndColors = await generateSVGWithUnknownColors(originalSvg);\n const data = {\n src: src,\n width,\n height,\n aspect: width / height,\n svg: svgAndColors.svg,\n colors: colors ?? svgAndColors.colors,\n };\n patternImageDataCache.set(src, data);\n frameService.setPatternData(data, recalculateOffsets);\n } else {\n const arrayBuffer = await fetchAsArrayBuffer(src, true);\n const attributes = await getAttributesFromArrayBuffer(arrayBuffer);\n const data = {\n src: src,\n width: attributes.width,\n height: attributes.height,\n aspect: attributes.width / attributes.height,\n svg: undefined,\n colors: undefined,\n };\n patternImageDataCache.set(src, data);\n frameService.setPatternData(data, recalculateOffsets);\n }\n }\n\n async changeColors(\n stepData: Step<FrameStepData>,\n workflowManager: WorkflowManager,\n newFills: Map<string, ColorDefinition>,\n ) {\n const frameService = (\n workflowManager.getWorkflowExperience().getStepById(stepData.stepName) as undefined | FrameStepHandle\n )?.frameService;\n if (!frameService || !frameService.getImageData()?.svg) {\n console.warn(\"changeColors was called without an SVG being assigned to a frame step\");\n return;\n }\n const colorData = await this.calculateColorMetadata(frameService, stepData, newFills);\n workflowManager.updateMetadata(stepData.stepName, { colors: colorData.metadataColors });\n workflowManager.updateStorage(stepData.stepName, {\n colors: colorData.storageColors,\n });\n // Update image data without updating offsets\n frameService.setPatternData(\n {\n ...frameService.getImageData()!,\n colors: colorData.newColors,\n },\n false,\n );\n this.validateColorCount(stepData, workflowManager);\n }\n\n getUniqueColorCount(stepData: Step<FrameStepData>, workflowManager: WorkflowManager): number {\n const frameService = (\n workflowManager.getWorkflowExperience().getStepById(stepData.stepName) as undefined | FrameStepHandle\n )?.frameService;\n if (!frameService) return 0;\n const colors = frameService.getImageData()?.colors ?? {};\n const unique: string[] = [];\n for (const key in colors) {\n const color = colors[key];\n if (color.pmsValue) {\n const pms = color.pmsValue.trim().toLocaleLowerCase();\n if (!unique.includes(pms)) {\n unique.push(pms);\n }\n } else if (color.browserValue) {\n // browserColorToHex already sanitizes value\n const hex = browserColorToHex(color.browserValue);\n if (!unique.includes(hex)) {\n unique.push(hex);\n }\n }\n }\n return unique.length;\n }\n\n private async calculateColorMetadata(\n frameService: FrameService,\n stepData: Step<FrameStepData>,\n newFills: Map<string, ColorDefinition>,\n ) {\n if (!frameService.getImageData()?.svg) {\n return {\n newColors: undefined,\n metadataColors: undefined,\n storageColors: undefined,\n };\n }\n // Compute change in color and apply to metadata\n const newColors: { [key: string]: ColorDefinition } = { ...(frameService.getImageData()!.colors ?? {}) };\n const storageColors: any = {};\n Object.entries(newColors).forEach(([key, value]) => {\n const color: any = { browserValue: value.browserValue };\n storageColors[key] = color;\n });\n for (const [className, newFill] of newFills.entries()) {\n newColors[className] = { browserValue: newFill.browserValue, pmsValue: newFill.pmsValue };\n storageColors[className] = newFill;\n }\n\n let colors = Array.from(Object.values(newColors)).map((c) => c.browserValue);\n const colorOption = await optionService.ensureFullOption(stepData.data.colorOption);\n if (colorOption) {\n colorOption.variants?.forEach((v: VariantResource) => {\n colors = colors.map((c) => (c.toLowerCase() === v.color?.toLowerCase() ? v.name : c));\n });\n }\n return {\n newColors,\n metadataColors: colors,\n storageColors,\n };\n }\n\n private validateColorCount(stepData: Step<FrameStepData>, workflowManager: WorkflowManager) {\n const maxColors = stepData.data.colorPickerEnabled ? (stepData.data.maxColors ?? 0) : 0;\n workflowManager.setStepError(\n stepData.stepName,\n \"colors\",\n maxColors > 0 && this.getUniqueColorCount(stepData, workflowManager) > maxColors\n ? \"workflow.steps.frame.tooManyColors\"\n : undefined,\n );\n }\n\n private async selectVariantCommand(\n stepData: Step<FrameStepData>,\n variant: VariantResource | undefined,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n setFrameIsUpdating?: (status: boolean) => void,\n loadedPattern?: string,\n ): Promise<CommandWithFollowup | null> {\n const frameService = (\n workflowManager.getWorkflowExperience().getStepById(stepData.stepName) as undefined | FrameStepHandle\n )?.frameService;\n if (!frameService) throw new Error(\"Frame service unavailable, cannot load pattern!\");\n const frameSvgs = await Promise.all(\n stepData.data.regions.map((region) => this.frameSourceSvg(variant, region)),\n );\n setFrameIsUpdating && setFrameIsUpdating(true);\n const initZoom = stepData.data.initialZoomLevel;\n const createdData = await Promise.all(\n stepData.data.regions.map(async (r, index) => {\n const newFrameData = await getFrameData(frameSvgs[index]);\n const existingImage = frameService.getImageData();\n const removeExistingCommands = elements.map((elem) => new DeleteElementCommand(elem.id));\n const newOffsets = existingImage\n ? calculateOffsets(\n existingImage,\n newFrameData,\n initZoom && !stepData.data.forceImageCover ? { scale: initZoom } : undefined,\n stepData.data.forceImageCover,\n )\n : undefined;\n const pattern = existingImage\n ? {\n id: generate(),\n src: existingImage.src,\n x: newOffsets?.x || 0,\n y: newOffsets?.y || 0,\n width: existingImage.width,\n height: existingImage.height,\n scaleX: newOffsets?.zoom || 1,\n scaleY: newOffsets?.zoom || 1,\n rotation: 0,\n }\n : undefined;\n\n const newElementId = generate();\n const layouts = workflowManager.getLayouts();\n const layout = layouts.find((layout: ILayout) => layout.panelId === r.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(r);\n }\n return {\n command: this.getCreateElementCommand(newElementId, r, index, layout, {\n frameData: newFrameData,\n pattern,\n disablePlaceholder: stepData.data.disablePlaceholder,\n stepName: stepData.stepName,\n }),\n regionEl: {\n id: newElementId,\n region: r,\n regionIndex: index,\n },\n removeExistingCommands,\n };\n }),\n );\n\n const createCommands = createdData.map((d) => d.command);\n const removeExistingCommands = createdData.map((d) => d.removeExistingCommands).flat();\n return {\n command: new GroupCommand([...createCommands, ...removeExistingCommands]),\n followup: async () => {\n setFrameIsUpdating && setFrameIsUpdating(false);\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n variant ? [variant] : [],\n [...createdData.map((d) => d.regionEl)],\n async () => {\n workflowManager.updateStorage(stepData.stepName, { currentFrameSources: frameSvgs });\n if (loadedPattern) {\n const frameService = (\n workflowManager.getWorkflowExperience().getStepById(stepData.stepName) as\n | undefined\n | FrameStepHandle\n )?.frameService;\n if (!frameService) throw new Error(\"Frame service unavailable, cannot load pattern!\");\n await this.loadPatternFromString(loadedPattern, frameService, true);\n }\n },\n );\n },\n };\n }\n\n private frameSourceSvg = async (variant: undefined | VariantResource, region: Region): Promise<string> => {\n if (!variant) {\n return generateDefaultRectangleFrameSvg(region);\n }\n const asset = variant.asset;\n if (!asset) {\n throw new AssetNotFoundError(variant);\n }\n const link = asset.fileLink;\n if (link) {\n return fetchAsString(link, true);\n }\n throw new ResourceNotFoundError(asset);\n };\n\n /**\n * Grab the source to be used for a frame from the variant or throw otherwise.\n */\n static patternSource(asset: Asset) {\n const svgVersion = asset.versions?.find((v) => v.name === \"svg\");\n if (svgVersion?.link) {\n return svgVersion.link;\n }\n const cdnLink = asset.fileLink;\n if (cdnLink) {\n return cdnLink;\n }\n throw new ResourceNotFoundError(asset);\n }\n\n private async loadPatternFromAsset(\n asset: Asset,\n stepData: Step<FrameStepData>,\n workflowManager: WorkflowManager,\n recalculateOffsets: boolean,\n ): Promise<void> {\n const src = FrameStepService.patternSource(asset);\n const updateId = workflowManager.markUpdatePending();\n const frameService = (\n workflowManager.getWorkflowExperience().getStepById(stepData.stepName) as undefined | FrameStepHandle\n )?.frameService;\n if (!frameService) {\n workflowManager.markUpdateCompleted(updateId);\n throw new Error(\"Frame service unavailable, cannot load pattern!\");\n }\n try {\n await this.loadPatternFromString(\n src,\n frameService,\n recalculateOffsets,\n undefined,\n stepData.data.colorPickerEnabled && !!stepData.data.maxColors && stepData.data.maxColors > 0,\n );\n } catch (e: any) {\n workflowManager.markUpdateCompleted(updateId);\n throw e;\n }\n const colorData = await this.calculateColorMetadata(\n frameService,\n stepData,\n new Map(Object.entries(frameService.getImageData()?.colors ?? {})),\n );\n workflowManager.updateMetadata(stepData.stepName, { image: src, colors: colorData.metadataColors });\n workflowManager.updateStorage(stepData.stepName, {\n framePatternSrc: src,\n colors: colorData.storageColors,\n });\n workflowManager.markUpdateCompleted(updateId);\n\n workflowManager.setMandatoryFulfilled(stepData.stepName, true);\n workflowManager.setInformationResults(\n workflowManager.getInformationResults().filter((it) => it.stepID === stepData.stepName),\n );\n this.validateColorCount(stepData, workflowManager);\n }\n}\n\nexport const frameStepService = new FrameStepService();\n","import { optionService } from \"../option\";\nimport {\n ColorDefinition,\n CommandWithFollowup,\n ILayout,\n IllustrationElement,\n IllustrationStepData,\n LayoutElementType,\n LayoutsState,\n Region,\n Step,\n VariantResource,\n} from \"../../types\";\nimport { RegionElement, StepService } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { LayoutNotFoundError, MisconfigurationError, ResourceNotFoundError } from \"../../util/exception\";\nimport { AssetNotFoundError } from \"../../util/exception\";\nimport { fetchAsString } from \"../../util/crossplatform\";\nimport {\n CanvasCommand,\n CreateElementCommand,\n DeleteElementCommand,\n GroupCommand,\n IllustrationCacheCommand,\n IllustrationColorCommand,\n} from \"../../command\";\nimport { findElement } from \"../../LayoutsState\";\nimport { generateSVGWithUnknownColors, modifySVGWithElementProperties } from \"../../util/illustration\";\nimport { svgObjectURL } from \"../../Elements/factory\";\nimport { LayoutData } from \"../../CommandContext\";\nimport { generate } from \"../../util/guid\";\n\nexport interface SVGCreateOpts {\n stepName?: string;\n src: string;\n objectURL: string;\n svg: {\n svg: string;\n colors: { [key: string]: ColorDefinition };\n };\n}\n\nclass IllustrationStepService implements StepService<IllustrationStepData> {\n async getIllustrationBody(src: string): Promise<string> {\n return new Promise((resolve) => {\n fetchAsString(src as string, true)\n .then((svg) => {\n resolve(svg);\n })\n .catch((e) => console.error(e));\n });\n }\n\n getCreateElementCommand(id: string, region: Region, regionIndex: number, layout: ILayout, options: SVGCreateOpts) {\n return new CreateElementCommand<IllustrationElement>(\n {\n stepRegion: region,\n stepRegionIndex: regionIndex,\n stepName: options.stepName,\n colors: options.svg.colors,\n id,\n src: options.src,\n svg: options.svg.svg,\n cachedObjectURL: options.objectURL,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n },\n layout,\n );\n }\n\n getColors(stepData: Step<IllustrationStepData>, workflowManager: WorkflowManager) {\n const regionEls = workflowManager.getRegionElements(stepData.stepName) || [];\n if (regionEls.length === 0) return [];\n try {\n const layoutElement = findElement(\n regionEls[0].id,\n workflowManager.getAllLayoutData(),\n ) as IllustrationElement;\n return layoutElement.colors;\n } catch (e) {\n return [];\n }\n }\n\n async init(\n stepData: Step<IllustrationStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n const option = await optionService.getOptionForStep(stepData);\n if (!option) {\n throw new MisconfigurationError(stepData, \"No option configured for illustration step.\");\n }\n if (reducerState) {\n return await this.reload(stepData, workflowManager, reducerState);\n } else {\n const defaultVariant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n if (defaultVariant) {\n return await this.selectVariantCommand(stepData, defaultVariant, [], workflowManager);\n }\n }\n return null;\n }\n\n private async reload(\n stepData: Step<IllustrationStepData>,\n workflowManager: WorkflowManager,\n reducerState: LayoutsState,\n ) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const option = await optionService.getOptionForStep(stepData);\n if (serializedStep?.selectedVariants) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (option && variantId) {\n const variant = option.variants?.find((variant: VariantResource) => variant.id === variantId);\n if (variant) {\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [variant],\n regionElements,\n async () => {\n workflowManager.updateMetadata(stepData.stepName, {\n colors: serializedStep.storage?.colors,\n });\n },\n );\n }\n } else throw new Error(\"Required illustration variant no longer available\");\n }\n return null;\n }\n\n async availableColors(stepData: Step<IllustrationStepData>, _workflowManager: WorkflowManager) {\n const colorOption = await optionService.ensureFullOption(stepData.data.colorOption);\n if (colorOption) {\n return colorOption\n ? colorOption.variants?.map((variant: VariantResource) => {\n return {\n fill: variant.color,\n stroke: variant.color,\n variant,\n pmsValue: variant.name,\n };\n })\n : [];\n }\n return [];\n }\n\n async changeColorsCommand(\n svg: string,\n illustrationWidth: number,\n illustrationHeight: number,\n elements: string[],\n newFills: Map<string, string | ColorDefinition>,\n ): Promise<CanvasCommand> {\n const newColors: { [key: string]: ColorDefinition } = {};\n for (const [className, newFill] of newFills.entries()) {\n if (typeof newFill === \"string\") {\n newColors[className] = {\n browserValue: newFill,\n spotColor: undefined,\n pmsValue: undefined,\n };\n } else {\n newColors[className] = {\n browserValue: newFill.browserValue,\n spotColor: newFill.spotColor,\n pmsValue: newFill.pmsValue,\n };\n }\n }\n const svgData = modifySVGWithElementProperties(svg, illustrationWidth, illustrationHeight, newColors);\n const objectURL = await svgObjectURL(svgData);\n const commands: CanvasCommand[] = [];\n for (const id of elements) {\n for (const [className, newFill] of newFills.entries()) {\n commands.push(new IllustrationColorCommand(id, className, newFill));\n }\n commands.push(new IllustrationCacheCommand(id, svgData, objectURL));\n }\n return new GroupCommand(commands);\n }\n\n async changeColors(\n stepData: Step<IllustrationStepData>,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n newFills: Map<string, string | ColorDefinition>,\n ) {\n if (elements.length === 0) {\n return;\n }\n\n const layoutElement = findElement(\n elements[0].id,\n workflowManager\n .getCommandContext()\n .getAllLayouts()\n .map((layout) => layout.layoutState),\n ) as IllustrationElement;\n\n // Compute change in color and apply to metadata\n const newColors: { [key: string]: ColorDefinition } = { ...(layoutElement as IllustrationElement).colors };\n const storageColors: any = {};\n Object.entries(newColors).forEach(([key, value]) => {\n const color: any = { browserValue: value.browserValue, pmsValue: value.pmsValue };\n const spotColor = value.spotColor;\n if (spotColor) {\n color[\"spotColor\"] = { profileName: spotColor.profileName, namedColor: spotColor.namedColor };\n }\n storageColors[key] = color;\n });\n for (const [className, newFill] of newFills.entries()) {\n const fill = typeof newFill === \"string\" ? newFill : newFill.browserValue;\n const pmsValue = typeof newFill === \"string\" ? undefined : newFill.pmsValue;\n\n if (className === \"\") {\n // Ultimately we need to be able to set color channels as global config, but until then we\n // assume that if we have a color with ID \"\" then the illustration has one channel.\n // Currently we set classes like spiff-fill-black and spiff-fill-000000 but for\n // global config channels to work, ColorOptionGlobalPropertyHandle.applyColorVariant as written expects classes like spiff-fill-1.\n Object.keys(newColors).forEach((key) => {\n // We expect just one key.\n newColors[key] = { browserValue: fill, spotColor: newColors[key]?.spotColor, pmsValue };\n storageColors[key] = { browserValue: fill };\n });\n } else {\n newColors[className] = { browserValue: fill, spotColor: newColors[className]?.spotColor, pmsValue };\n storageColors[className] = { browserValue: fill };\n }\n }\n\n let colors = Array.from(Object.values(newColors)).map((c) => c.browserValue);\n\n const colorOption = await optionService.ensureFullOption(stepData.data.colorOption);\n if (colorOption) {\n colorOption.variants?.forEach((v: VariantResource) => {\n colors = colors.map((c) => (c.toLowerCase() === v.color?.toLowerCase() ? v.name : c));\n });\n }\n workflowManager.updateMetadata(stepData.stepName, { colors });\n const colorsForCommand: Map<string, ColorDefinition> = new Map();\n Object.entries(newColors).forEach(([key, value]) => {\n colorsForCommand.set(key, value);\n });\n\n if (!layoutElement.svg) {\n throw new Error(\"Colors changed before SVG loaded. This should never happen!\");\n }\n\n const command = await this.changeColorsCommand(\n layoutElement.svg,\n layoutElement.width,\n layoutElement.height,\n elements.map((el) => el.id),\n colorsForCommand,\n );\n workflowManager.updateStorage(stepData.stepName, {\n colors: storageColors,\n });\n workflowManager.getCommandDispatcher()(command);\n }\n\n async selectVariant(\n stepData: Step<IllustrationStepData>,\n variant: VariantResource,\n elements: RegionElement[],\n setIsUpdating: (isUpdating: boolean) => void,\n workflowManager: WorkflowManager,\n ) {\n setIsUpdating(true);\n try {\n const result = await this.selectVariantCommand(stepData, variant, elements, workflowManager);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n } finally {\n setIsUpdating(false);\n }\n }\n\n private async selectVariantCommand(\n stepData: Step<IllustrationStepData>,\n variant: VariantResource,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n ): Promise<CommandWithFollowup | null> {\n if (!stepData.data || !stepData.data.regions) {\n throw new MisconfigurationError(stepData, \"Missing regions.\");\n }\n const asset = variant.asset;\n if (!asset) {\n throw new AssetNotFoundError(variant);\n }\n const link = asset.fileLink;\n\n if (!link) {\n throw new ResourceNotFoundError(asset);\n }\n\n if (stepData.mandatory) {\n workflowManager.setMandatoryFulfilled(stepData.stepName, false);\n }\n\n const deleteCommands = elements.map((el) => new DeleteElementCommand(el.id));\n\n const svgData = await generateSVGWithUnknownColors(await this.getIllustrationBody(link));\n const objectURL = await svgObjectURL(svgData.svg);\n const createElementForRegion = (region: Region, regionIndex: number) => {\n const layout = workflowManager.getLayouts().find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n const elementKey = generate();\n return {\n regionElement: { id: elementKey, region, regionIndex },\n command: this.getCreateElementCommand(elementKey, region, regionIndex, layout, {\n stepName: stepData.stepName,\n src: link,\n objectURL,\n svg: svgData,\n }),\n };\n };\n const elementsWithCommands = stepData.data.regions.map(createElementForRegion);\n const createCommands = elementsWithCommands.map((r) => r.command);\n const commandList: CanvasCommand[] = [...deleteCommands, ...createCommands];\n\n let colors = Array.from(Object.values(svgData.colors)).map((c) => c.browserValue);\n const colorOption = await optionService.ensureFullOption(stepData.data.colorOption);\n if (colorOption) {\n colorOption.variants?.forEach((v: VariantResource) => {\n colors = colors.map((c) => (c.toLowerCase() === v.color?.toLowerCase() ? v.name : c));\n });\n }\n\n workflowManager.updateMetadata(stepData.stepName, { colors: colors });\n return {\n command: new GroupCommand(commandList),\n followup: async () => {\n const targetElements = elementsWithCommands.map((r) => r.regionElement);\n await workflowManager.setSelectionsAndElements(stepData.stepName, [variant], targetElements);\n\n // If the illustration has an asset configuration then we need to apply it.\n const defaultColorVariants = asset.assetConfiguration?.defaultColorVariants || [];\n if (defaultColorVariants.length !== 0) {\n const modifiedColors: { [id: string]: ColorDefinition } = {};\n const channelNumbers = asset.assetConfiguration?.channelNumbers || [];\n channelNumbers.forEach((cn) => {\n const v = defaultColorVariants.find((item) => item.channelNumber === cn.number);\n if (v) {\n modifiedColors[`${cn.id.replace(/\\W/g, \"\")}`] = { browserValue: v?.variant?.color || \"\" };\n }\n });\n await this.changeColors(\n stepData,\n targetElements,\n workflowManager,\n new Map(Object.entries(modifiedColors)),\n );\n }\n\n if (stepData.data.colorPickerEnabled) {\n // When the color picker is enabled & only 1 variant is available, we immediately apply\n // the variant to the illustration.\n const availableColors = (await this.availableColors(stepData, workflowManager)) || [];\n const colorEntries = Object.keys(svgData.colors);\n const singleColor = availableColors.length === 1 && colorEntries.length === 1;\n if (singleColor) {\n const color = availableColors[0];\n const entry = colorEntries[0];\n await this.changeColors(\n stepData,\n targetElements,\n workflowManager,\n new Map([[entry, color.variant.color!]]),\n );\n }\n\n if (!singleColor && defaultColorVariants.length === 0) {\n // This \"change\" is just to populate color metadata.\n await this.changeColors(stepData, targetElements, workflowManager, new Map());\n }\n }\n },\n };\n }\n}\n\nexport const illustrationStepService = new IllustrationStepService();\n","import { optionService } from \"../option\";\nimport { CommandWithFollowup, LayoutsState, MaterialStepData, Step, StepService, VariantResource } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { AssetNotFoundError, OptionNotFoundError } from \"../../util/exception\";\n\nclass MaterialStepService implements StepService<MaterialStepData> {\n async init(\n stepData: Step<MaterialStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<null | CommandWithFollowup> {\n const option = stepData.option;\n if (!option) {\n throw new OptionNotFoundError(stepData);\n }\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n } else {\n const defaultVariant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n if (defaultVariant) {\n return await this.selectVariantLambda(stepData, defaultVariant, workflowManager, () => {});\n }\n }\n return null;\n }\n\n private async reload(\n stepData: Step<MaterialStepData>,\n workflowManager: WorkflowManager,\n reducerState: LayoutsState,\n ) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const option = stepData.option;\n if (!option) throw new OptionNotFoundError(stepData);\n if (serializedStep?.selectedVariants) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (variantId) {\n const variant = option.variants?.find((variant: VariantResource) => variant.id === variantId);\n if (variant) {\n const material = variant.material;\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [variant],\n regionElements,\n async () => {\n const modelContainer = workflowManager.getModelContainer();\n if (modelContainer) {\n const variantPromises = stepData.data.targetMaterials.map((matName) => {\n return modelContainer.applyMaterialVariant(\n matName,\n option.id || \"\",\n material || {},\n );\n });\n Promise.all(variantPromises);\n }\n },\n );\n }\n }\n }\n }\n\n async selectVariant(\n step: Step<MaterialStepData>,\n variant: VariantResource,\n workflowManager: WorkflowManager,\n setApplying: (status: boolean) => void,\n ) {\n const result = await this.selectVariantLambda(step, variant, workflowManager, setApplying);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n private async selectVariantLambda(\n step: Step<MaterialStepData>,\n variant: VariantResource,\n workflowManager: WorkflowManager,\n setApplying: (status: boolean) => void,\n ): Promise<CommandWithFollowup | null> {\n const modelContainer = workflowManager.getModelContainer();\n setApplying(true);\n const material = variant.material;\n if (!material) {\n setApplying(false);\n throw new AssetNotFoundError(variant);\n }\n return {\n command: undefined,\n followup: async () => {\n await workflowManager.setSelectionsAndElements(step.stepName, [variant], [], async () => {\n try {\n if (modelContainer) {\n step.data.targetMaterials.forEach((matName) => {\n step.option &&\n modelContainer.applyMaterialVariant(matName, step.option.id || \"\", material);\n });\n }\n } finally {\n setApplying(false);\n }\n });\n },\n };\n }\n}\n\nexport const materialStepService = new MaterialStepService();\n","import { optionService } from \"../option\";\nimport { CommandWithFollowup, LayoutsState, ModelStepData, Step, StepService, VariantResource } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { OptionNotFoundError } from \"../../util/exception\";\nimport { AssetNotFoundError } from \"../../util/exception\";\n\nclass ModelStepService implements StepService<ModelStepData> {\n async init(\n stepData: Step<ModelStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n const option = await optionService.getOptionForStep(stepData);\n if (!option) throw new OptionNotFoundError(stepData);\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n } else {\n const defaultVariant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n if (defaultVariant) {\n return await this.selectVariantLambda(stepData, defaultVariant, workflowManager, () => {});\n }\n }\n return null;\n }\n\n private async reload(stepData: Step<ModelStepData>, workflowManager: WorkflowManager, reducerState: LayoutsState) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const option = await optionService.getOptionForStep(stepData);\n if (serializedStep?.selectedVariants) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (option && variantId) {\n const variant = option.variants?.find((variant: VariantResource) => variant.id === variantId);\n if (variant) {\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [variant],\n regionElements,\n async () => {\n const modelContainer = workflowManager.getModelContainer();\n if (modelContainer && stepData.option) {\n const highlightedRef = variant.asset?.fileLink;\n if (!highlightedRef) throw new AssetNotFoundError(variant);\n await modelContainer.applyModelVariant(\n stepData.stepName || \"\",\n {\n model: highlightedRef,\n contextService: workflowManager.getLayoutPreviewService(),\n },\n stepData.data.replaceProductModel || false,\n );\n }\n },\n );\n }\n }\n }\n }\n\n async selectVariant(\n step: Step<ModelStepData>,\n variant: VariantResource,\n workflowManager: WorkflowManager,\n setApplying: (status: boolean) => void,\n ) {\n const result = await this.selectVariantLambda(step, variant, workflowManager, setApplying);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n private async selectVariantLambda(\n step: Step<ModelStepData>,\n variant: VariantResource,\n workflowManager: WorkflowManager,\n setApplying: (status: boolean) => void,\n ): Promise<CommandWithFollowup | null> {\n setApplying(true);\n const modelRef = variant.asset?.fileLink;\n if (!modelRef) {\n throw new AssetNotFoundError(variant);\n }\n return {\n command: undefined,\n followup: async () => {\n await workflowManager.setSelectionsAndElements(step.stepName, [variant], [], async () => {\n try {\n const modelContainer = workflowManager.getModelContainer();\n // We let selection logic apply. But if the preview service has failed\n // to load we don't want to throw an error. Instead we just don't\n // load the 3D model.\n if (modelContainer) {\n await modelContainer.applyModelVariant(\n step.stepName,\n {\n model: modelRef,\n contextService: workflowManager.getLayoutPreviewService(),\n },\n step.data.replaceProductModel || false,\n );\n }\n } finally {\n setApplying(false);\n }\n });\n },\n };\n }\n}\n\nexport const modelStepService = new ModelStepService();\n","import { CanvasCommand, CreateElementCommand, DeleteElementCommand, GroupCommand } from \"../../command\";\nimport { TextChangeResult } from \"../../stepHandles/steps/text\";\nimport {\n RegionElement,\n StepService,\n CommandWithFollowup,\n ModuleStepData,\n Step,\n LayoutsState,\n Region,\n ILayout,\n IllustrationElement,\n LayoutElementType,\n} from \"../../types\";\nimport { generate } from \"../../util/guid\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { split } from \"unicode-default-word-boundary\";\n\nclass ModuleStepService implements StepService<ModuleStepData> {\n async init(\n stepData: Step<ModuleStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n } else {\n workflowManager.updateMetadata(stepData.stepName, { text: \"\" });\n return this.changeTextCommand(stepData, \"\", workflowManager, () => {});\n }\n return null;\n }\n\n private async reload(stepData: Step<ModuleStepData>, workflowManager: WorkflowManager, reducerState: LayoutsState) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n await workflowManager.setSelectionsAndElements(stepData.stepName, [], regionElements, async () => {\n workflowManager.updateStorage(stepData.stepName, { text: serializedStep?.storage?.text });\n workflowManager.setMandatoryFulfilled(stepData.stepName, serializedStep?.storage?.text !== \"\");\n });\n }\n\n async changeText(\n stepData: Step<ModuleStepData>,\n input: string,\n workflowManager: WorkflowManager,\n setError: (e: string) => void,\n ) {\n const result = await this.changeTextCommand(stepData, input, workflowManager, setError);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n private async changeTextCommand(\n stepData: Step<ModuleStepData>,\n input: string,\n workflowManager: WorkflowManager,\n setError: (e: string) => void,\n ): Promise<CommandWithFollowup | null> {\n const elements = workflowManager.getRegionElements(stepData.stepName);\n\n const module = workflowManager.getStepSpecificServices(stepData.stepName)?.module;\n if (!module) {\n console.error(\"Missing module.\");\n return null;\n }\n\n const profanityFilter = workflowManager.getWorkflowExperience().getProfanityList();\n const validationResult = this.validateInput(stepData, input, profanityFilter, setError);\n if (validationResult.errorData) {\n workflowManager.setMandatoryFulfilled(stepData.stepName, false);\n if (validationResult.errorData.blockedProfanity) {\n console.error(\"Blocked profanity.\");\n } else if (validationResult.errorData.hitCharacterLimit) {\n console.error(\"Too many characters.\");\n } else if (validationResult.errorData.unsupportedCharacters) {\n console.error(\"Unsupported characters.\");\n }\n return null;\n }\n workflowManager.setMandatoryFulfilled(stepData.stepName, input !== \"\");\n\n if (!stepData.data || !stepData.data.regions || stepData.data.regions.length <= 0) {\n console.error(\"Missing configuration.\");\n return null;\n }\n\n workflowManager.updateStorage(stepData.stepName, { text: input });\n workflowManager.updateMetadata(stepData.stepName, { text: input });\n\n const createElementFromRegion = (svg: string, region: Region, regionIndex?: number, existingKey?: string) => {\n const elementKey = existingKey || generate();\n const layouts = workflowManager.getLayouts();\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n console.error(`Can not find layout for region: ${region.panelId}`);\n return null;\n }\n\n const commands: CanvasCommand[] = [];\n if (existingKey) {\n commands.push(new DeleteElementCommand(elementKey));\n }\n commands.push(\n new CreateElementCommand<IllustrationElement>(\n {\n stepRegion: region,\n stepRegionIndex: regionIndex,\n stepName: stepData.stepName,\n colors: {},\n id: elementKey,\n svg: svg,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n },\n layout,\n ),\n );\n return {\n id: elementKey,\n region,\n command: new GroupCommand(commands),\n };\n };\n\n if (elements.length > 0) {\n // Create new elements from passed in elements' regions.\n const results = elements\n .map((regionElement) => {\n if (!regionElement.region) {\n return null;\n }\n const svg = module.svgPrint(input, regionElement.region);\n return createElementFromRegion(\n svg,\n regionElement.region,\n regionElement.regionIndex,\n regionElement.id,\n );\n })\n .filter((x) => !!x);\n const commands = results.filter((r) => !!r).map((r) => r && r.command);\n return {\n command: new GroupCommand(commands as CanvasCommand[]),\n followup: async () => {},\n };\n } else {\n // Create new elements from workflow step's regions.\n const results = stepData.data.regions.map((region, index) =>\n createElementFromRegion(module.svgPrint(input, region), region, index),\n );\n const commands = results.filter((r) => !!r).map((r) => r && r.command);\n return {\n command: new GroupCommand(commands as CanvasCommand[]),\n followup: async () => {\n const newElements = results.filter((r) => r).map((r) => r && { id: r.id, region: r.region });\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [],\n newElements as RegionElement[],\n );\n },\n };\n }\n }\n\n private validateInput(\n stepData: Step<ModuleStepData>,\n input: string,\n profanityFilter: string[],\n setError: (e: string) => void,\n ): TextChangeResult {\n if (stepData.data && stepData.data.maxLength) {\n const maxLength = stepData.data.maxLength;\n if (input.length > maxLength) {\n setError(\"Too many characters.\");\n return { input, helperData: {}, errorData: { hitCharacterLimit: true } };\n }\n }\n\n // Regex for filtering unwanted characters\n if (!/^$|^[a-zA-Z0-9 ]+$/.test(input)) {\n setError(\"Unsupported characters.\");\n return { input, helperData: {}, errorData: { unsupportedCharacters: true } };\n }\n\n // Check text against our blacklist\n const words = split(input.toLowerCase());\n for (const word of words) {\n for (const i in profanityFilter) {\n const profanity = profanityFilter[i].toLowerCase().replace(/\\s/g, \"\");\n const match = word === profanity;\n if (match) {\n setError(\"Blocked profanity.\");\n return { input, helperData: {}, errorData: { blockedProfanity: true } };\n }\n }\n }\n\n setError(\"\");\n return { input, helperData: {} };\n }\n}\n\nexport const moduleStepService = new ModuleStepService();\n","import {\n CommandWithFollowup,\n ILayout,\n ImageElement,\n LayoutElementType,\n LayoutsState,\n PictureStepData,\n Region,\n Step,\n VariantResource,\n} from \"../../types\";\nimport { StepService } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { LayoutNotFoundError, MisconfigurationError } from \"../../util/exception\";\nimport { AssetNotFoundError } from \"../../util/exception\";\nimport { CreateElementCommand, DeleteElementCommand, GroupCommand } from \"../../command\";\nimport { generate } from \"../../util/guid\";\nimport { optionService } from \"../option\";\n\nclass PictureStepService implements StepService<PictureStepData> {\n async init(\n stepData: Step<PictureStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n const option = await optionService.getOptionForStep(stepData);\n if (!option) {\n throw new MisconfigurationError(stepData, \"Missing option for picture step\");\n }\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n } else {\n const defaultVariant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n if (defaultVariant) {\n workflowManager.markStepsAsInitialised([stepData.stepName]);\n return this.selectVariantCommand(stepData, defaultVariant, workflowManager, () => {});\n }\n }\n workflowManager.markStepsAsInitialised([stepData.stepName]);\n return null;\n }\n\n private async reload(\n stepData: Step<PictureStepData>,\n workflowManager: WorkflowManager,\n reducerState: LayoutsState,\n ) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const option = await optionService.getOptionForStep(stepData);\n if (serializedStep?.selectedVariants) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (option && variantId) {\n const variant = option.variants?.find((variant: VariantResource) => variant.id === variantId);\n if (variant) {\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n await workflowManager.setSelectionsAndElements(stepData.stepName, [variant], regionElements);\n }\n }\n }\n }\n\n async selectVariant(\n stepData: Step<PictureStepData>,\n variant: VariantResource,\n workflowManager: WorkflowManager,\n setIsUpdating: (status: boolean) => void,\n ) {\n const result = await this.selectVariantCommand(stepData, variant, workflowManager, setIsUpdating);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n private async selectVariantCommand(\n stepData: Step<PictureStepData>,\n variant: VariantResource,\n workflowManager: WorkflowManager,\n setIsUpdating: (status: boolean) => void,\n ): Promise<CommandWithFollowup | null> {\n const asset = variant.asset;\n if (!asset) {\n throw new AssetNotFoundError(variant);\n }\n const link = asset?.fileLink;\n if (!link) {\n console.error(\"No URL for picture!\");\n return null;\n }\n\n setIsUpdating(true);\n if (stepData.mandatory) {\n workflowManager.setMandatoryFulfilled(stepData.stepName, false);\n }\n\n // Remove existing images.\n const elements = workflowManager.getRegionElements(stepData.stepName);\n const deletionCommands = elements.map((elem) => new DeleteElementCommand(elem.id));\n\n // If images exists, delete them in preparation for creating new images.\n const createElementForRegion = (region: Region, regionIndex: number) => {\n const layouts = workflowManager.getLayouts();\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n // Create a new image.\n const elementKey = generate();\n return {\n regionElement: { id: elementKey, region, regionIndex },\n command: new CreateElementCommand<ImageElement>(\n {\n stepName: stepData.stepName,\n stepRegion: region,\n stepRegionIndex: regionIndex,\n id: elementKey,\n src: link,\n type: LayoutElementType.Image,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n preserveAspectRatio: \"none\",\n },\n layout,\n ),\n };\n };\n\n const newElements = stepData.data.regions.map(createElementForRegion);\n return {\n command: new GroupCommand([...deletionCommands, ...newElements.map((el) => el.command)]),\n followup: async () => {\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [variant],\n newElements.map((el) => el.regionElement),\n async () => {\n setIsUpdating(false);\n },\n );\n },\n };\n }\n}\n\nexport const pictureStepService = new PictureStepService();\n","import { optionService } from \"../option\";\nimport { CommandWithFollowup, LayoutsState, QuestionStepData, Step, StepService, VariantResource } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { MisconfigurationError } from \"../../util/exception\";\n\nclass QuestionStepService implements StepService<QuestionStepData> {\n async init(\n stepData: Step<QuestionStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n const option = stepData.option;\n if (!option) {\n throw new MisconfigurationError(stepData, \"Missing option for question step\");\n }\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n } else {\n const defaultVariant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n if (defaultVariant) {\n return this.selectVariantLambda(stepData, defaultVariant.id || \"\", workflowManager);\n }\n }\n return null;\n }\n\n private async reload(\n stepData: Step<QuestionStepData>,\n workflowManager: WorkflowManager,\n reducerState: LayoutsState,\n ) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const option = await optionService.getOptionForStep(stepData);\n if (serializedStep?.selectedVariants) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (option && variantId) {\n const variant = option.variants?.find((variant) => variant.id === variantId);\n if (variant) {\n await workflowManager.setSelectionsAndElements(stepData.stepName, [variant], []);\n }\n }\n }\n }\n\n async selectVariant(stepData: Step<QuestionStepData>, variantId: string, workflowManager: WorkflowManager) {\n // Select variant.\n const result = await this.selectVariantLambda(stepData, variantId, workflowManager);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n private async selectVariantLambda(\n stepData: Step<QuestionStepData>,\n variantId: string,\n workflowManager: WorkflowManager,\n ): Promise<CommandWithFollowup | null> {\n const option = await optionService.getOptionForStep(stepData);\n if (!option) {\n throw new MisconfigurationError(stepData, \"Missing option for question step\");\n }\n const variants = option.variants;\n if (!variants) {\n throw new MisconfigurationError(stepData, \"Option for question step is missing variants\");\n }\n const variant =\n variants.length > 1 ? variants.find((variant: VariantResource) => variant.id === variantId) : variants[0];\n if (!variant) {\n throw new Error(\n `Failed to find selected variant ${variantId} in option ${option.id} of step ${stepData.stepName} (${stepData.stepTitle})`,\n );\n }\n\n return {\n command: undefined,\n followup: async () => {\n await workflowManager.setSelectionsAndElements(stepData.stepName, [variant], []);\n },\n };\n }\n}\n\nexport const questionStepService = new QuestionStepService();\n","import { optionService } from \"../option\";\nimport {\n RegionElement,\n StepService,\n ColorOption,\n CommandWithFollowup,\n ShapeStepData,\n Step,\n VariantResource,\n ILayout,\n LayoutsState,\n Region,\n ColorDefinition,\n IllustrationElement,\n LayoutElementType,\n} from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { LayoutNotFoundError, OptionNotFoundError } from \"../../util/exception\";\nimport { CanvasCommand, CreateElementCommand, GroupCommand, IllustrationColorCommand } from \"../../command\";\nimport { generate } from \"../../util/guid\";\n\nclass ShapeStepService implements StepService<ShapeStepData> {\n readonly shapeFillId = \"spiff-fill-shape\";\n\n // Get the step's options.\n async availableColours(stepData: Step<ShapeStepData>) {\n const option = await optionService.getOptionForStep(stepData);\n if (option) {\n return (\n option.variants?.map((variant: VariantResource) => {\n return {\n fill: variant.color,\n stroke: variant.color,\n variant,\n };\n }) || []\n );\n }\n return [];\n }\n\n setCustomColor(color: string, stepData: Step<ShapeStepData>, manager: WorkflowManager) {\n const layouts = manager.getLayouts();\n const elements = manager.getRegionElements(stepData.stepName) || [];\n const commands = elements\n .map((stepElement: RegionElement) => {\n const region = stepElement.region;\n const layout = layouts.find((layout: ILayout) => layout.panelId === region?.panelId);\n if (!layout) throw new LayoutNotFoundError(region!);\n return new IllustrationColorCommand(stepElement.id, this.shapeFillId, color);\n })\n .filter((c) => !!c);\n manager.getCommandDispatcher()(new GroupCommand(commands));\n manager.updateStorage(stepData.stepName, { colour: color });\n }\n\n async init(\n stepData: Step<ShapeStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n const option = await optionService.getOptionForStep(stepData);\n if (!option) {\n throw new OptionNotFoundError(stepData);\n }\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n } else {\n const variant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n if (!variant) {\n return null;\n }\n return this.selectVariantCommand(\n stepData,\n {\n fill: variant.color,\n stroke: variant.color,\n variant,\n },\n [],\n workflowManager,\n );\n }\n return null;\n }\n\n async selectVariant(\n stepData: Step<ShapeStepData>,\n colourOption: ColorOption,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n ) {\n const result = await this.selectVariantCommand(stepData, colourOption, elements, workflowManager);\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n private async reload(stepData: Step<ShapeStepData>, workflowManager: WorkflowManager, reducerState: LayoutsState) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const option = await optionService.getOptionForStep(stepData);\n if (serializedStep?.selectedVariants) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (option && variantId) {\n const variant = option.variants?.find((variant) => variant.id === variantId);\n if (variant) {\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [variant],\n regionElements,\n async () => {\n workflowManager.updateStorage(stepData.stepName, {\n colour: serializedStep?.storage?.colour || \"\",\n });\n },\n );\n }\n }\n }\n }\n\n private async selectVariantCommand(\n stepData: Step<ShapeStepData>,\n colourOption: ColorOption,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n ): Promise<CommandWithFollowup | null> {\n const layouts = workflowManager.getLayouts();\n const existingColor = workflowManager.getStepStorage(stepData.stepName)?.colour;\n const getColor = () => {\n if (colourOption.variant?.color === \"#custom\") return existingColor || \"#FFFFFF\";\n if (colourOption.variant?.color) return colourOption.variant.color;\n throw new Error(\"Failed to resolve color for shape step.\");\n };\n if (elements.length > 0) {\n const updateCommand = (stepElement: RegionElement) => {\n const region = stepElement.region;\n const layout = layouts.find((layout: ILayout) => layout.panelId === region?.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region!);\n }\n const newColor = getColor();\n return new IllustrationColorCommand(stepElement.id, this.shapeFillId, newColor);\n };\n const commands = elements.map(updateCommand).filter((c) => !!c);\n return {\n command: new GroupCommand(commands as CanvasCommand[]),\n followup: async () => {\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n colourOption.variant ? [colourOption.variant] : [],\n elements,\n );\n workflowManager.updateStorage(stepData.stepName, { colour: getColor() });\n },\n };\n } else {\n // No existing elements, create new ones.\n const createElementForRegion = (region: Region, regionIndex: number) => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n const newColor = getColor();\n const svg = `\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlnsXlink=\"http://www.w3.org/1999/xlink\"\n xmlSpace=\"preserve\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n width=\"1\"\n height=\"1\"\n viewBox=\"0 0 1 1\"\n >\n <rect\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n class=\"${this.shapeFillId}\"\n fill=\"${newColor}\"\n />\n </svg>\n `;\n const colors: { [key: string]: ColorDefinition } = {};\n colors[this.shapeFillId] = { browserValue: newColor };\n\n const elementKey = generate();\n return {\n id: elementKey,\n region,\n command: new CreateElementCommand<IllustrationElement>(\n {\n stepRegion: region,\n stepRegionIndex: regionIndex,\n stepName: stepData.stepName,\n colors,\n id: elementKey,\n svg,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n excludeFromExport: stepData.data.excludeFromPrint,\n },\n layout,\n ),\n };\n };\n const results = stepData.data.regions.map(createElementForRegion);\n const commands = results.filter((r) => !!r).map((r) => r?.command);\n const elements = results\n .filter((r) => !!r)\n .map((r, index) => {\n return { id: r!.id, region: r!.region, regionIndex: index };\n });\n return {\n command: new GroupCommand(commands as CanvasCommand[]),\n followup: async () => {\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n colourOption.variant ? [colourOption.variant] : [],\n elements,\n async () => {\n workflowManager.updateStorage(stepData.stepName, { colour: getColor() });\n },\n );\n },\n };\n }\n }\n}\n\nexport const shapeStepService = new ShapeStepService();\n","import { InformationMessageType } from \"../WorkflowManager\";\n\nexport type ToastCallback = (callbackOptions: {\n toastMessage: null | string;\n toastType: InformationMessageType | null;\n}) => void;\n\nclass Toast {\n private latestToast: null | string;\n private toastType: InformationMessageType | null;\n\n private toastCallbacks: ToastCallback[];\n\n constructor() {\n this.latestToast = null;\n this.toastType = null;\n this.toastCallbacks = [];\n }\n\n addToastCallback(callback: ToastCallback) {\n callback({\n toastMessage: this.latestToast,\n toastType: this.toastType,\n });\n this.toastCallbacks.push(callback);\n }\n\n removeToastCallback(callback: ToastCallback) {\n this.toastCallbacks = this.toastCallbacks.filter((it) => it !== callback);\n }\n\n setLatestToast(errorMessage: null | string, errorType: InformationMessageType | null) {\n this.latestToast = errorMessage;\n this.toastType = errorType;\n this.onToastChange();\n }\n\n private onToastChange() {\n this.toastCallbacks.forEach((callback) =>\n callback({\n toastMessage: this.latestToast,\n toastType: this.toastType,\n }),\n );\n }\n}\n\nconst toast = new Toast();\nexport { toast };\n","import { FontMetrics, getFontMetrics } from \"../../util/font\";\nimport { FontData, Region, SizeRange } from \"../../types\";\nimport { fontSizeStep, textWidth } from \"../shared\";\n\n/**\n * Produce an array where text has been broken into lines that can\n * fit the region at the current size.\n * If it can't be done then return null;\n */\nconst linesThatFit = (\n region: Region,\n linesToBreak: string[],\n fontSize: number,\n fontScale: number,\n cache: FontMetrics,\n): [null | string[], null | number] => {\n if (linesToBreak.some(line => line === undefined || line === null)) {\n throw new Error(`Failed to autosize lines: ${linesToBreak.join(\", \")}`);\n }\n let lines = linesToBreak.map(line => line.split(\"\\n\")).flat();\n let amountLines = lines.length;\n let widthsPerLine = lines.map((line) => textWidth(line, fontScale, cache));\n const lineHeight = cache.getApproximateHeight() * fontScale;\n\n let couldStillFit = true;\n while (couldStillFit) {\n // Determine if textbox would be too high.\n // If the textbox is too high, line breaking isn't going to help.\n // Height of the textbox is the height of the last line plus its vertical offset.\n const textboxHeight = lineHeight + (amountLines - 1) * fontSize;\n if (textboxHeight > region.height) {\n return [null, null];\n }\n\n // Determine if textbox would be too wide.\n // It's not too high, so if it's not too wide then we've succeeded.\n // Width of the whole textbox is the width of the longest line.\n const textboxWidth = Math.max(...widthsPerLine);\n if (textboxWidth <= region.width) {\n return [lines, textboxWidth];\n }\n\n // It's too wide. Find the widest line and look for a space.\n const idxWidestLine = widthsPerLine.reduce((iMax, x, i, arr) => (x > arr[iMax] ? i : iMax), 0);\n const widestLine = lines[idxWidestLine];\n\n // Find the latest space to split at that makes the current widest line fit.\n let foundGoodSpacing = false;\n let idxOfSpace = widestLine.length;\n while (!foundGoodSpacing && idxOfSpace > -1) {\n idxOfSpace = widestLine.lastIndexOf(\" \", idxOfSpace - 1);\n const splitLine = [widestLine.slice(0, idxOfSpace), widestLine.slice(idxOfSpace + 1)];\n const splitWidths = splitLine.map((line) => textWidth(line, fontScale, cache));\n const firstWidth = splitWidths[0];\n if (firstWidth <= region.width) {\n lines = [...lines.slice(0, idxWidestLine), ...splitLine, ...lines.slice(idxWidestLine + 1)];\n widthsPerLine = [\n ...widthsPerLine.slice(0, idxWidestLine),\n ...splitWidths,\n ...widthsPerLine.slice(idxWidestLine + 1),\n ];\n amountLines += 1;\n foundGoodSpacing = true;\n }\n }\n if (!foundGoodSpacing) {\n couldStillFit = false;\n }\n }\n\n // No way to fit.\n return [null, null];\n};\n\n/**\n * Determine what the font size for a text element should be,\n * taking autosizing into account.\n * @Deprecated Old Text system, Transition to new system when Autosizing has been brought across in a way that makes sense.\n */\nexport const determineCorrectFontSizeAndLines = (\n curFontSize: number,\n fontData: FontData,\n region: Region,\n linesToBreak: string[],\n sizeRange: SizeRange,\n): [number, null | string[], null | number] => {\n let lines;\n let requiredWidth;\n\n const cache = getFontMetrics(fontData.assetUrl);\n const font = cache.getFont();\n\n // Fixed Mode: Text is computed based on fixed text size.\n if (sizeRange.size) {\n const fontScale = curFontSize / font.unitsPerEm;\n [lines, requiredWidth] = linesThatFit(region, linesToBreak, curFontSize, fontScale, cache);\n return [sizeRange.size, lines, requiredWidth];\n }\n\n // Variable Mode: Text is computed based on a range\n const nonUserMin = 6;\n let calculatedFontSize = nonUserMin - fontSizeStep;\n if (linesToBreak.length > 0) {\n let lines: null | string[] = linesToBreak;\n let fontScale = 0;\n while ((!sizeRange.maxSize || calculatedFontSize <= sizeRange.maxSize) && lines) {\n calculatedFontSize += fontSizeStep;\n fontScale = calculatedFontSize / font.unitsPerEm;\n [lines, requiredWidth] = linesThatFit(region, linesToBreak, calculatedFontSize, fontScale, cache);\n }\n }\n if (calculatedFontSize > nonUserMin) {\n // Correct for final enlargement.\n calculatedFontSize -= fontSizeStep;\n }\n if (sizeRange.minSize && calculatedFontSize < sizeRange.minSize) {\n // Correct for minimum font size.\n calculatedFontSize = sizeRange.minSize;\n }\n const fontScale = calculatedFontSize / font.unitsPerEm;\n [lines, requiredWidth] = linesThatFit(region, linesToBreak, calculatedFontSize, fontScale, cache);\n return [calculatedFontSize, lines, requiredWidth];\n};\n\n// https://stackoverflow.com/a/22015771\nconst zip = (xs: any[], ys: any[]) => {\n return xs.map((x, idx) => [x, ys[idx]]);\n};\n\n/**\n * If a textbox has a fixed font size, it's width should be changed to fit the text.\n * Needs to take rotation into consideration.\n * The left alignment case appears to be resolved but the other cases have not been addressed.\n * @Deprecated Old Text system, Transition to new system when Autosizing has been brought across in a way that makes sense.\n */\nexport const determineCorrectTextboxRegion = (\n currentRegion: Region,\n fontData: FontData,\n fontSize: number,\n textLines: string[],\n align?: string,\n): Region => {\n let region = { ...currentRegion };\n const candidateRegion = { ...currentRegion };\n // requiredWidth could be const but the others must be let.\n // eslint-disable-next-line prefer-const\n let [calculatedFontSize, goodLines, requiredWidth] = determineCorrectFontSizeAndLines(\n fontSize,\n fontData,\n candidateRegion,\n textLines,\n { size: 0, minSize: fontSize, maxSize: fontSize },\n );\n if (requiredWidth && requiredWidth < region.width) {\n candidateRegion.width = requiredWidth;\n if (align === \"left\") {\n candidateRegion.left += Math.sin((region.rotation * Math.PI) / 360) * (region.width - requiredWidth);\n candidateRegion.top += (Math.sin((region.rotation * Math.PI) / 180) * (requiredWidth - region.width)) / 2;\n } else if (align === \"right\") {\n candidateRegion.left += region.width - requiredWidth;\n } else {\n candidateRegion.left += (region.width - requiredWidth) / 2;\n }\n [calculatedFontSize, goodLines] = determineCorrectFontSizeAndLines(fontSize, fontData, candidateRegion, textLines, {\n size: fontSize,\n });\n if (\n calculatedFontSize === fontSize &&\n goodLines &&\n zip(textLines, goodLines).every(([lineA, lineB]) => lineA === lineB)\n ) {\n region = candidateRegion;\n }\n }\n return region;\n};\n","import {\n AspectType,\n ColorDefinition,\n ColorOption,\n CommandWithFollowup,\n FontData,\n ILayout,\n LayoutElementType,\n LayoutsState,\n OptionResource,\n Region,\n RegionElement,\n Step,\n StepService,\n TextboxElement,\n TextFillImage,\n TextStepData,\n TextStepStorage,\n VariantResource,\n} from \"../../../types\";\nimport { InformationMessageType, WorkflowManager } from \"../../../WorkflowManager\";\nimport { optionService } from \"../../option\";\nimport { toast } from \"../../toast\";\nimport { AssetNotFoundError, ResourceNotFoundError, UnhandledBehaviorError } from \"../../../util/exception\";\nimport { split } from \"unicode-default-word-boundary\";\nimport {\n CanvasCommand,\n CreateElementCommand,\n FontAlignmentCommand,\n FontColorCommand,\n FontImageFillCommand,\n FontSizeCommand,\n FontSourceCommand,\n GroupCommand,\n TextChangeCommand,\n TextStrokeCommand,\n} from \"../../../command\";\nimport { getPatternImageData } from \"../../../util/frame\";\nimport { findElement } from \"../../../LayoutsState\";\nimport { getFontMetrics, loadFont } from \"../../../util/font\";\nimport { applyTextTransformations } from \"../../../text/shared\";\nimport { determineCorrectFontSizeAndLines } from \"../../../text/algorithm/autosize\";\nimport { generate } from \"../../../util/guid\";\nimport { renderTextTemplateForWorkflow } from \"../../../util/text\";\n\n/**\n * The font size used when the font size is not specified in configuration.\n */\nconst defaultFontSize = 30;\ninterface TextFillSpotColor {\n profileName: string;\n namedColor: string;\n}\ninterface CreatedElementData {\n regionElement: RegionElement;\n commands: CanvasCommand[];\n newElement: TextboxElement;\n fontData: FontData;\n}\n\ninterface TextUpdateResult {\n command?: GroupCommand;\n helperData: {\n charactersRemaining?: number;\n };\n errorData?: TextErrorData;\n}\n\nexport interface TextErrorData {\n blockedProfanity?: boolean;\n doesNotFit?: boolean;\n hitCharacterLimit?: boolean;\n illegalMultipleLines?: boolean;\n unsupportedCharacters?: boolean;\n}\n\n// https://joefallon.net/2018/09/typescript-try-catch-finally-and-custom-errors/\nclass FontLoadError extends Error {\n constructor(message?: string) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = FontLoadError.name;\n }\n}\n\n// A set of allowable glyphs, open type doesn't see these glyphs as valid\n// but they're generally always actually supplied. To prevent filtering them out\n// we check if a glyph matches this list.\nconst allowableGlyphs = [\"‘\", \"’\", \"“\", \"”\", \"\\n\"];\n\nclass RegionLayoutMissingError extends Error {\n constructor(message?: string) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = RegionLayoutMissingError.name;\n }\n}\n\nclass TextStepService implements StepService<TextStepData> {\n // A cache of computed possible colors. We store here to get a stable reference\n // to prevent react from re-rendering\n private cachedColors = new Map<string, ColorOption[]>();\n // HACK: These two could possibly be merged\n private cachedStrokeColors = new Map<string, ColorOption[]>();\n\n public async init(\n stepData: Step<TextStepData>,\n workflowManager: WorkflowManager,\n reducerState?: LayoutsState,\n ): Promise<CommandWithFollowup | null> {\n const option = await optionService.getOptionForStep(stepData);\n if (!option) {\n return null;\n }\n if (reducerState) {\n await this.reload(stepData, workflowManager, reducerState);\n } else {\n const defaultImageFillVariant = await this.getDefaultImageFillVariant(stepData.data);\n const imageFillLink = defaultImageFillVariant?.asset?.fileLink;\n const imageFillDataRaw = imageFillLink ? await getPatternImageData(imageFillLink) : undefined;\n const imageFillData = imageFillDataRaw\n ? {\n src: imageFillDataRaw.src,\n height: imageFillDataRaw.height,\n width: imageFillDataRaw.width,\n scale: stepData.data.imageFillScale || 1,\n }\n : undefined;\n const defaultStroke = await this.getDefaultStrokeColorVariant(stepData.data);\n const strokeData =\n stepData.data.strokeEnabled && defaultStroke?.color\n ? {\n browserValue: defaultStroke.color,\n pmsValue: defaultStroke.name,\n }\n : undefined;\n\n let text = stepData.data.defaultText || \"\";\n // When a bundle is present we load the text aspect.\n const bundle = workflowManager.getWorkflowExperience().getBundle();\n if (bundle && stepData.globalPropertyAspectConfigurations) {\n const aspects = bundle.getGlobalPropertyConfiguration()?.aspects;\n const aspect = aspects?.find(\n (a) =>\n a.type === AspectType.Text &&\n stepData.globalPropertyAspectConfigurations?.map((c) => c.aspectName).includes(a.name),\n );\n if (aspect) {\n const stateManager = bundle.getGlobalPropertyStateManager();\n const aspectText = stateManager.getAspect(aspect.name);\n if (aspectText) {\n text = aspectText;\n }\n }\n }\n\n workflowManager.updateStorage(stepData.stepName, {\n text,\n inputText: stepData.data.defaultText || \"\",\n color:\n (await this.getDefaultColorVariant(stepData.data))?.color ||\n (await this.getDefaultColor(stepData.data)),\n fillImage: imageFillData,\n strokeColor: strokeData,\n });\n\n workflowManager.updateMetadata(stepData.stepName, {\n text,\n color:\n (await this.getDefaultColorVariant(stepData.data))?.name ||\n (await this.getDefaultColor(stepData.data)),\n fillImage: defaultImageFillVariant?.name,\n strokeColor: stepData.data.strokeEnabled ? defaultStroke?.color : undefined,\n });\n\n const defaultVariant = await optionService.getDefaultVariant(option, stepData.overrideDefaultVariantId);\n\n if (defaultVariant) {\n return this.selectVariantCommand(\n stepData,\n defaultVariant,\n { text },\n [],\n workflowManager,\n () => {},\n () => {},\n imageFillData,\n strokeData,\n );\n }\n }\n return null;\n }\n\n public findLayoutElements(workflowManager: WorkflowManager, step: Step<TextStepData>) {\n const elements = workflowManager.getRegionElements(step.stepName);\n const foundElements = elements.map((el) => {\n return findElement(el.id, workflowManager.getAllLayoutData()) as TextboxElement;\n });\n return foundElements;\n }\n\n /**\n * Get the colors that can be used for a given text step.\n * @param stepData The text step to get colors for.\n * @returns A list of color objects containing fill, stroke and variant if available.\n */\n public async availableFillColors(stepData: Step<TextStepData>): Promise<ColorOption[]> {\n // Check cache first.\n const cached = this.cachedColors.get(stepData.stepName);\n if (cached) {\n return cached;\n }\n\n // Otherwise check option\n const colorOption = await optionService.ensureFullOption(stepData.data.colorOption);\n if (colorOption) {\n const colors =\n colorOption.variants?.map((variant: VariantResource) => {\n return {\n fill: variant.color,\n stroke: variant.color,\n variant,\n };\n }) || [];\n this.cachedColors.set(stepData.stepName, colors);\n return colors;\n }\n\n return [];\n }\n\n public changeAlignment(\n stepData: Step<TextStepData>,\n alignment: \"left\" | \"center\" | \"right\",\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n ) {\n if (!stepData.data || !stepData.data.regions) {\n return;\n }\n const commandDispatcher = workflowManager.getCommandDispatcher();\n\n for (const regionElement of elements) {\n const command = new FontAlignmentCommand(regionElement.id, alignment);\n commandDispatcher(command);\n }\n }\n\n public async changeFillColor(\n stepData: Step<TextStepData>,\n newColor: ColorOption,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n ) {\n if (!stepData.data || !stepData.data.regions) {\n return;\n }\n const commandDispatcher = workflowManager.getCommandDispatcher();\n\n if (newColor.variant) {\n workflowManager.updateMetadata(stepData.stepName, { color: newColor.variant.name });\n } else {\n workflowManager.updateMetadata(stepData.stepName, { color: newColor.fill });\n }\n // Handle generation of spot color information if required.\n const colorOption = await optionService.ensureFullOption(stepData.data.colorOption);\n const textFillSpotColor = colorOption\n ? this.createTextFillSpotColor(colorOption, newColor.variant!)\n : undefined;\n if (colorOption) {\n workflowManager.updateStorage(stepData.stepName, {\n color: newColor.fill,\n colorProfileAssetKey: colorOption.colorProfile?.key,\n });\n } else {\n workflowManager.updateStorage(stepData.stepName, {\n color: newColor.fill,\n });\n }\n // Apply color changes to each element targeted by the step.\n for (const regionElement of elements) {\n if (!newColor.fill) {\n throw new Error(\"Fill not set on new color selection!\");\n }\n const command = new FontColorCommand(regionElement.id, newColor.fill, textFillSpotColor);\n commandDispatcher(command);\n }\n }\n\n public async availableFillImages(stepData: Step<TextStepData>): Promise<TextFillImage[]> {\n const imageFillOption = await optionService.ensureFullOption(stepData.data.imageFillOption);\n if (imageFillOption) {\n const imageFillUrls =\n (imageFillOption.variants?.map((v) => v.asset?.fileLink)?.filter((url) => !!url) as string[]) || [];\n return Promise.all(\n imageFillUrls.map(async (url) => {\n const data = await getPatternImageData(url);\n return {\n src: url,\n width: data.width,\n height: data.height,\n scale: stepData.data.imageFillScale || 1,\n };\n }),\n );\n }\n return Promise.resolve([]);\n }\n\n public async changeFillImage(\n stepData: Step<TextStepData>,\n fillImage: TextFillImage,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n ) {\n if (!stepData.data || !stepData.data.regions) {\n return;\n }\n const commandDispatcher = workflowManager.getCommandDispatcher();\n const variant = stepData.option?.variants?.find((v) => v.asset?.fileLink === fillImage.src);\n workflowManager.updateMetadata(stepData.stepName, { fillImage: variant?.name });\n workflowManager.updateStorage(stepData.stepName, {\n fillImage,\n });\n\n for (const regionElement of elements) {\n const command = new FontImageFillCommand(regionElement.id, fillImage);\n commandDispatcher(command);\n }\n }\n\n /**\n * Get the colors that can be used for a given text step's stroke.\n * @param stepData The text step to get colors for.\n * @returns A list of color objects containing fill, stroke and variant if available.\n */\n public async availableStrokeColors(stepData: Step<TextStepData>): Promise<ColorOption[]> {\n // Check cache first.\n const cached = this.cachedStrokeColors.get(stepData.stepName);\n if (cached) {\n return cached;\n }\n\n // Otherwise check option\n const strokeOption = await optionService.ensureFullOption(stepData.data.strokeOption);\n if (strokeOption) {\n const colors =\n strokeOption.variants?.map((variant: VariantResource) => {\n return {\n fill: variant.color,\n stroke: variant.color,\n variant,\n };\n }) || [];\n this.cachedStrokeColors.set(stepData.stepName, colors);\n return colors;\n }\n\n return [];\n }\n\n public async changeStrokeColor(\n stepData: Step<TextStepData>,\n newColor: ColorOption | undefined,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n ) {\n if (!stepData.data || !stepData.data.regions) {\n return;\n }\n const commandDispatcher = workflowManager.getCommandDispatcher();\n\n if (newColor?.variant) {\n workflowManager.updateMetadata(stepData.stepName, { strokeColor: newColor.variant.name });\n } else {\n workflowManager.updateMetadata(stepData.stepName, { strokeColor: newColor?.fill });\n }\n const colorDefinition: ColorDefinition | undefined = newColor\n ? {\n browserValue: newColor.fill!,\n pmsValue: newColor.pmsValue,\n }\n : undefined;\n workflowManager.updateStorage(stepData.stepName, {\n strokeColor: colorDefinition,\n });\n // Apply color changes to each element targeted by the step.\n for (const regionElement of elements) {\n const command = new TextStrokeCommand(regionElement.id, colorDefinition, stepData.data?.strokeThickness);\n commandDispatcher(command);\n }\n }\n\n /**\n * Given an element and a string, filters any characters from the string that are\n * not supported by the font of the given element.\n * @param text The text string to filter.\n * @param fontData An optional fontData object, when provided, we use the font table to determine glyphs that aren't provided and additionally strip these out also.\n * @returns A new string representing the passed string with unsupported characters removed.\n */\n public filterUnsupportedCharacters = (text: string, fontData?: FontData): string => {\n // A list of character code ranges that we don't support. Mostly known emoji ranges.\n let filteredText = text.replace(\n /(\\r\\n|\\r|(\\u2665|\\u00a9|\\u00ae|[\\u2000-\\u2017]|[\\u201E-\\u3300]]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff]))/gm,\n \"\",\n );\n // Use opentype to determine if the font supports the character, remove otherwise.\n // There are special cases however. Refer to 'allowableGlyphs'\n const badCharacterCodes: string[] = [];\n const opentypeFont = fontData ? getFontMetrics(fontData.assetUrl) : undefined;\n if (opentypeFont) {\n const searchableGlyphs = filteredText\n .split(\"\")\n .filter((char) => !allowableGlyphs.includes(char))\n .join(\"\");\n const glyphs = searchableGlyphs.split(\"\").map((char) => opentypeFont.getFont().charToGlyph(char));\n // Find all characters in the input text that don't work with our system.\n for (let i = 0; i < glyphs.length; i++) {\n const undefinedGlyph = glyphs[i].name === \".notdef\";\n if (undefinedGlyph) {\n badCharacterCodes.push(String.fromCharCode(searchableGlyphs.charCodeAt(i)));\n }\n }\n }\n // Once we have a list of unsupported character codes, let's remove them.\n for (let i = 0; i < badCharacterCodes.length; i++) {\n filteredText = filteredText.replaceAll(badCharacterCodes[i], \"\");\n }\n return filteredText;\n };\n\n public getProcessedInput(input: string, stepData: TextStepData, customiseAllText: boolean): string {\n const injectedText = customiseAllText ? input : this.injectReplaceableText(input, stepData);\n return applyTextTransformations(injectedText, {\n vertical: stepData.vertical,\n uppercase: stepData.uppercase,\n });\n }\n\n public updateInputText(\n input: string,\n elements: TextboxElement[],\n step: Step<TextStepData>,\n workflowManager: WorkflowManager,\n ): TextUpdateResult {\n const storage = workflowManager.getStepStorage(step.stepName) as TextStepStorage | undefined;\n const renderedText = renderTextTemplateForWorkflow(input, workflowManager);\n const processedText = this.getProcessedInput(renderedText, step.data, storage?.customiseAllText ?? false);\n\n const response: TextUpdateResult = {\n command: undefined,\n helperData: {},\n errorData: this.getErrorsForText(input, processedText, step, workflowManager),\n };\n\n // Check the input text for validity.\n if (response.errorData) {\n return response;\n }\n\n // Otherwise set helper text to character limit\n response.helperData.charactersRemaining = step.data.maxLength - processedText.length;\n\n // Calculate font size and lines with new text.\n // TODO: We need to shift this into TextChangeCommand\n const commands: CanvasCommand[] = [];\n const correctFontSizes = new Map<string, number>();\n const correctLineLists = new Map<string, null | string[]>();\n for (const el of elements) {\n if (!el.fontData) throw new UnhandledBehaviorError(\"Failed to resolve font data for text.\");\n const [newFontSize, newLines] = determineCorrectFontSizeAndLines(\n el.fontSize,\n el.fontData,\n { left: el.x, top: el.y, width: el.width, height: el.height, rotation: el.rotation, panelId: \"\" },\n [processedText],\n { size: step.data.size, minSize: step.data.minSize, maxSize: step.data.maxSize },\n );\n correctFontSizes.set(el.id, newFontSize);\n correctLineLists.set(el.id, newLines);\n const newText = step.data.curved ? processedText : (newLines || []).join(\"\\n\");\n commands.push(this.generateTextChangeCommandsForRegion(newFontSize, step.data, el.id, newText));\n }\n\n if (!step.data.curved && elements.length > 0) {\n const allFit = Array.from(correctLineLists.values()).every((x) => x);\n if (!allFit) {\n if (!response.errorData) {\n response.errorData = {};\n }\n response.errorData.doesNotFit = true;\n return response;\n }\n }\n\n // Notify workflow of text changes.\n workflowManager.updateStorage(step.stepName, { text: input });\n workflowManager.updateMetadata(step.stepName, {\n text: processedText,\n });\n\n if ((storage?.defaultCleared || !step.data.deleteDefaultOnFocus) && processedText.trim() !== \"\") {\n workflowManager.setMandatoryFulfilled(step.stepName, true);\n }\n\n response.command = new GroupCommand(commands);\n return response;\n }\n\n public async selectVariant(\n step: Step<TextStepData>,\n variant: VariantResource,\n workflowManager: WorkflowManager,\n setError: (errorMessage?: string) => void,\n setHelperText: (text: string) => void,\n ) {\n const result = await this.selectVariantCommand(\n step,\n variant,\n workflowManager.getStepStorage(step.stepName) || {},\n workflowManager.getRegionElements(step.stepName),\n workflowManager,\n setError,\n setHelperText,\n );\n if (result) {\n result.command && workflowManager.getCommandDispatcher()(result.command);\n result.followup && (await result.followup());\n }\n }\n\n public textAlign = (stepData: TextStepData) => {\n if (stepData.vertical) {\n return \"center\";\n }\n return stepData.textAlign || \"center\";\n };\n\n public createTextFillSpotColor(\n colorOption: OptionResource,\n variant: VariantResource,\n ): TextFillSpotColor | undefined {\n const colorProfileAsset = colorOption.colorProfile;\n if (colorProfileAsset) {\n const profileNameStrWithoutSpaces = (colorProfileAsset.name || \"\").replace(/\\s/g, \"-\");\n const amountToSlice = profileNameStrWithoutSpaces.lastIndexOf(\"/\");\n const profileNameFiltered = profileNameStrWithoutSpaces.slice(amountToSlice + 1); // Removes all characters before the last instance of /\n const finalFilteredName = profileNameFiltered.slice(0, -4); // Removes last 4 characters in the string which is the file extension (eg .icc)\n if (!variant.namedColor) throw new Error(\"variant named color not set!\");\n return {\n profileName: finalFilteredName,\n namedColor: variant.namedColor,\n };\n }\n\n return undefined;\n }\n\n private async reload(stepData: Step<TextStepData>, workflowManager: WorkflowManager, reducerState: LayoutsState) {\n const serializedStep = workflowManager.getSerializedStep(\n stepData.stepName,\n reducerState.serializableWorkflow.steps,\n );\n const layouts = Object.values(reducerState.layouts);\n const elements = layouts.map((layout) => layout.elements).flat();\n const elementsForStep = elements.filter((el) => el.stepName === stepData.stepName);\n const option = await optionService.getOptionForStep(stepData);\n\n if (serializedStep?.selectedVariants) {\n const variantId = serializedStep.selectedVariants[0].id;\n if (option && variantId) {\n const variant = option.variants?.find((variant: VariantResource) => variant.id === variantId);\n if (variant) {\n const fontData = await this.fontDataFromVariant(variant);\n const regionElements = elementsForStep.map((el) => ({\n id: el.id,\n region: el.stepRegion,\n regionIndex: el.stepRegionIndex,\n }));\n const color = serializedStep.storage?.color;\n let text = serializedStep.storage?.text;\n\n // When a bundle is present we load the text aspect.\n const bundle = workflowManager.getWorkflowExperience().getBundle();\n if (bundle && stepData.globalPropertyAspectConfigurations) {\n const aspects = bundle.getGlobalPropertyConfiguration()?.aspects;\n const aspect = aspects?.find(\n (a) =>\n a.type === AspectType.Text &&\n stepData.globalPropertyAspectConfigurations?.map((c) => c.aspectName).includes(a.name),\n );\n if (aspect) {\n const stateManager = bundle.getGlobalPropertyStateManager();\n const aspectText = stateManager.getAspect(aspect.name);\n if (aspectText) {\n text = aspectText;\n }\n }\n }\n\n await workflowManager.setSelectionsAndElements(\n stepData.stepName,\n [variant],\n regionElements,\n async () => {\n workflowManager.updateMetadata(stepData.stepName, { color, text });\n workflowManager.updateStorage(stepData.stepName, { text, inputText: text });\n const fontSourceCommands = elementsForStep.map((el) => {\n const command = new FontSourceCommand(el.id, fontData);\n return command;\n });\n const groupCommand = new GroupCommand(fontSourceCommands);\n workflowManager.getCommandDispatcher()(groupCommand);\n },\n );\n if (elementsForStep.length === 0 && option) {\n // Assume we are reloading a conditional step.\n const defaultVariant = await optionService.getDefaultVariant(\n option,\n stepData.overrideDefaultVariantId,\n );\n if (defaultVariant) {\n const com = await this.selectVariantCommand(\n stepData,\n defaultVariant,\n { text },\n [],\n workflowManager,\n () => {},\n () => {},\n );\n if (com?.command) workflowManager.getCommandDispatcher()(com.command);\n }\n } else {\n const { command } = textStepService.updateInputText(\n text || \"\",\n elementsForStep as TextboxElement[],\n stepData,\n workflowManager,\n );\n command && workflowManager.getCommandDispatcher()(command);\n }\n }\n }\n } else {\n // When a bundle is present we load the text aspect.\n const bundle = workflowManager.getWorkflowExperience().getBundle();\n if (bundle && stepData.globalPropertyAspectConfigurations) {\n const aspects = bundle.getGlobalPropertyConfiguration()?.aspects;\n const aspect = aspects?.find(\n (a) =>\n a.type === AspectType.Text &&\n stepData.globalPropertyAspectConfigurations?.map((c) => c.aspectName).includes(a.name),\n );\n if (aspect) {\n const stateManager = bundle.getGlobalPropertyStateManager();\n const aspectText = stateManager.getAspect(aspect.name);\n if (aspectText) {\n if (elementsForStep.length === 0 && option) {\n // Assume we are reloading a conditional step.\n const defaultVariant = await optionService.getDefaultVariant(\n option,\n stepData.overrideDefaultVariantId,\n );\n if (defaultVariant) {\n const com = await this.selectVariantCommand(\n stepData,\n defaultVariant,\n { text: aspectText },\n [],\n workflowManager,\n () => {},\n () => {},\n );\n if (com?.command) workflowManager.getCommandDispatcher()(com.command);\n }\n } else {\n const { command } = textStepService.updateInputText(\n aspectText,\n elementsForStep as TextboxElement[],\n stepData,\n workflowManager,\n );\n command && workflowManager.getCommandDispatcher()(command);\n }\n }\n }\n }\n }\n }\n\n private async getDefaultColorVariant(step: TextStepData): Promise<VariantResource | undefined> {\n const colorOption = step.colorOption;\n if (!colorOption) return undefined;\n return optionService.getDefaultVariant(colorOption);\n }\n\n private async getDefaultColor(step: TextStepData): Promise<string | undefined> {\n const colorOption = step.colorOption;\n if (!colorOption) return undefined;\n const defaultVariant = await optionService.getDefaultVariant(colorOption);\n return defaultVariant?.color;\n }\n\n private async getDefaultImageFillVariant(step: TextStepData): Promise<VariantResource | undefined> {\n const option = step.imageFillOption;\n if (!option) return undefined;\n return optionService.getDefaultVariant(option);\n }\n\n private async getDefaultStrokeColorVariant(step: TextStepData): Promise<VariantResource | undefined> {\n const option = step.strokeOption;\n if (!option) return undefined;\n return optionService.getDefaultVariant(option);\n }\n\n /**\n * Validates a string of text based on step configuration.\n * @param text The text to validate\n * @param renderedText The text after being rendered via templating\n * @param step The step providing configuration\n * @param workflowManager Workflow manager for access to workflow state\n * @returns A list of errors. Empty if the text passes validation.\n */\n private getErrorsForText = (\n text: string,\n renderedText: string,\n step: Step<TextStepData>,\n workflowManager: WorkflowManager,\n ): undefined | TextErrorData => {\n let errorData: undefined | TextErrorData = undefined;\n\n // Ensure character limit is maintained\n if (!!step.data && !!step.data.maxLength && renderedText.length > step.data.maxLength) {\n if (!errorData) {\n errorData = {};\n }\n errorData.hitCharacterLimit = true;\n }\n\n // Check text against our blacklist\n const profanityFilter = workflowManager.getWorkflowExperience().getProfanityList();\n const words = split(text.toLowerCase());\n for (const word of words) {\n for (const i in profanityFilter) {\n const profanity = profanityFilter[i].toLowerCase().replace(/\\s/g, \"\");\n const match = word === profanity;\n if (match) {\n if (!errorData) {\n errorData = {};\n }\n errorData.blockedProfanity = true;\n break;\n }\n }\n }\n\n // Potentially don't allow newlines.\n const breaksNewlineRule = !step.data.allowNewlines && (text.includes(\"\\n\") || text.includes(\"\\r\"));\n if (breaksNewlineRule) {\n if (!errorData) {\n errorData = {};\n }\n errorData.illegalMultipleLines = true;\n }\n\n return errorData;\n };\n\n private async fontDataFromVariant(variant: VariantResource): Promise<FontData> {\n const fontAsset = variant.asset;\n if (!fontAsset) {\n throw new AssetNotFoundError(variant);\n }\n const fontUrl = fontAsset.fileLink;\n if (!fontUrl) {\n throw new ResourceNotFoundError(fontAsset);\n }\n const font = await loadFont(fontUrl);\n return {\n assetUrl: fontUrl,\n name: font.names.fullName[\"en\"],\n };\n }\n\n private async selectVariantCommand(\n step: Step<TextStepData>,\n variant: VariantResource,\n storage: TextStepStorage,\n elements: RegionElement[],\n workflowManager: WorkflowManager,\n setError: (errorMessage?: string) => void,\n setHelperText: (text: string) => void,\n imageFillData?: { src: string; height: number; width: number; scale: number },\n strokeData?: ColorDefinition,\n ): Promise<CommandWithFollowup | null> {\n const updateId = workflowManager.markUpdatePending();\n\n const fontData = await this.fontDataFromVariant(variant);\n\n let shouldReturnResult = true;\n const wrappedSetError = (errorMessage?: string) => {\n setError(errorMessage);\n if (errorMessage) {\n shouldReturnResult = false;\n }\n };\n\n if (elements.length > 0) {\n const commands: CanvasCommand[] = elements.map((elem) => {\n const command = new FontSourceCommand(elem.id, fontData);\n return command;\n });\n\n if (imageFillData) {\n const imageFillCommands = elements.map((elem) => new FontImageFillCommand(elem.id, imageFillData));\n commands.push(...imageFillCommands);\n }\n\n if (strokeData) {\n const strokeCommands = elements.map((elem) => {\n return new TextStrokeCommand(elem.id, strokeData, step.data.strokeThickness);\n });\n commands.push(...strokeCommands);\n }\n\n const sizingCommand = await this.changeInputTextWithRegion(\n step,\n step.data.size || defaultFontSize,\n fontData,\n storage.text || \"\",\n storage,\n workflowManager,\n storage?.customiseAllText ?? false,\n wrappedSetError,\n setHelperText,\n );\n sizingCommand && commands.push(sizingCommand);\n const command = new GroupCommand(commands);\n if (shouldReturnResult) {\n return {\n command: command,\n followup: async () => {\n workflowManager.markUpdateCompleted(updateId);\n await workflowManager.setSelectionsAndElements(step.stepName, [variant], elements);\n },\n };\n } else {\n return null;\n }\n } else {\n const newlyCreatedData = await this.createTextboxRegions(\n step.stepName,\n variant,\n step.data,\n fontData,\n storage,\n workflowManager,\n );\n\n const sizingCommand = await this.changeInputTextWithRegion(\n step,\n step.data.size || defaultFontSize,\n fontData,\n newlyCreatedData[0]?.newElement.input || storage.text || step.data.defaultText || \"\",\n storage,\n workflowManager,\n storage?.customiseAllText ?? false,\n wrappedSetError,\n setHelperText,\n );\n\n const commands = newlyCreatedData.flatMap((data) => data.commands);\n\n if (imageFillData) {\n const imageFillCommands = newlyCreatedData.map(\n (data) => new FontImageFillCommand(data.regionElement.id, imageFillData),\n );\n commands.push(...imageFillCommands);\n }\n\n if (strokeData) {\n const strokeCommands = newlyCreatedData.map(\n (elem) => new TextStrokeCommand(elem.newElement.id, strokeData, step.data.strokeThickness),\n );\n commands.push(...strokeCommands);\n }\n\n sizingCommand && commands.push(sizingCommand);\n const groupCommand = new GroupCommand(commands);\n\n if (shouldReturnResult) {\n return {\n command: groupCommand,\n followup: async () => {\n workflowManager.markUpdateCompleted(updateId);\n },\n };\n } else {\n return null;\n }\n }\n }\n\n /**\n * When a text step specifies replaceable text, the text input by the user will replace\n * a specific token within a larger string of text specified in the step configuration. Otherwise\n * this function will just return the text it's given when the feature is disabled.\n */\n private injectReplaceableText(text: string, stepData: TextStepData) {\n if (stepData.replaceableText) {\n return stepData.replaceableText.replace(`{{}}`, text);\n } else {\n return text;\n }\n }\n\n private async createTextboxRegions(\n stepName: string,\n variant: VariantResource,\n stepData: TextStepData,\n fontData: FontData,\n storage: TextStepStorage,\n workflowManager: WorkflowManager,\n ): Promise<CreatedElementData[]> {\n if (!stepData || !stepData.regions) {\n throw new Error(\"Step data not supplied\");\n }\n\n const currentText = storage.text || stepData.defaultText || \"\";\n const renderedText = renderTextTemplateForWorkflow(currentText, workflowManager);\n const transformedText = this.getProcessedInput(renderedText, stepData, false);\n const addFontToRegion = async (region: Region, regionIndex: number): Promise<CreatedElementData> => {\n const layouts = workflowManager.getLayouts();\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n\n // Create new element.\n const elementId = generate();\n try {\n if (!layout) {\n throw new RegionLayoutMissingError(\"Failed to find layout for region: \" + region.panelId);\n }\n const colorOption = await optionService.ensureFullOption(stepData.colorOption);\n\n let textFillSpotColor: TextFillSpotColor | undefined = undefined;\n if (colorOption && colorOption.variants) {\n const defaultVariant = await optionService.getDefaultVariant(colorOption);\n if (defaultVariant) {\n textFillSpotColor = this.createTextFillSpotColor(colorOption, defaultVariant);\n workflowManager.updateStorage(stepName, {\n colorProfileAssetKey: colorOption.colorProfile?.key,\n });\n }\n }\n\n const defaultColor = await this.getDefaultColor(stepData);\n const startingFill = defaultColor ? defaultColor : \"#000000\";\n\n const newElement: TextboxElement = {\n stepRegion: region,\n stepRegionIndex: regionIndex,\n stepName: stepName,\n align: this.textAlign(stepData),\n fill: storage.color ? storage.color : startingFill,\n fontSize: stepData.size || defaultFontSize,\n fontData,\n id: elementId,\n layer: region.layer,\n layerIndex: region.layerIndex,\n rotation: region.rotation,\n text: transformedText,\n input: currentText,\n type: LayoutElementType.Textbox,\n vertical: stepData.vertical,\n x: region.left,\n y: region.top,\n height: region.height,\n width: region.width,\n immutable: region.immutable,\n verticalAlign: stepData.verticalAlign || \"middle\",\n curved: stepData.curved,\n paths: stepData.paths,\n fillSpotColorDefinition: textFillSpotColor,\n };\n\n const sizingCommands: CanvasCommand[] = [];\n const correctFontSizes = new Map<string, number>();\n const correctLineLists = new Map<string, null | string[]>();\n if (!newElement.fontData) throw new UnhandledBehaviorError(\"Failed to resolve font data for text.\");\n const [newFontSize, newLines] = determineCorrectFontSizeAndLines(\n newElement.fontSize,\n newElement.fontData,\n {\n left: newElement.x,\n top: newElement.y,\n width: newElement.width,\n height: newElement.height,\n rotation: newElement.rotation,\n panelId: \"\",\n },\n [transformedText],\n { size: stepData.size, minSize: stepData.minSize, maxSize: stepData.maxSize },\n );\n correctFontSizes.set(newElement.id, newFontSize);\n correctLineLists.set(newElement.id, newLines);\n const newText = stepData.curved || stepData.vertical ? transformedText : (newLines || []).join(\"\\n\");\n sizingCommands.push(\n this.generateTextChangeCommandsForRegion(newFontSize, stepData, newElement.id, newText),\n );\n\n const newCommand = new CreateElementCommand(newElement, layout);\n\n return {\n regionElement: { id: elementId, region, regionIndex },\n commands: [newCommand, ...sizingCommands],\n newElement,\n fontData,\n };\n } catch (err) {\n console.log(err);\n throw new FontLoadError(\"Error adding font to region\");\n }\n };\n\n const newElementData = await Promise.all(stepData.regions.map(addFontToRegion)).catch((e) => {\n if (e instanceof FontLoadError) {\n toast.setLatestToast(\"Failed to load font.\", InformationMessageType.Error);\n throw e;\n } else if (e instanceof RegionLayoutMissingError) {\n throw e;\n } else {\n throw new Error(e);\n }\n });\n\n await workflowManager.setSelectionsAndElements(\n stepName,\n [variant],\n newElementData.map((e) => e.regionElement),\n async () => {\n workflowManager.updateMetadata(stepName, {\n text: currentText,\n });\n workflowManager.updateStorage(stepName, {\n text: currentText,\n });\n },\n );\n\n return newElementData;\n }\n\n private generateTextChangeCommandsForRegion(\n correctFontSize: number,\n stepData: TextStepData,\n elementId: string,\n newText: string,\n ): GroupCommand {\n const commands: CanvasCommand[] = [];\n const textChangeCommand = new TextChangeCommand(elementId, newText);\n commands.push(textChangeCommand);\n // If the user has specified a font size range as opposed to a\n // static font size then do sizing.\n if (!stepData.size) {\n const fontSizeCommand = new FontSizeCommand(elementId, correctFontSize);\n commands.push(fontSizeCommand);\n }\n const groupCommand = new GroupCommand(commands);\n return groupCommand;\n }\n\n /**\n * @deprecated\n */\n private async changeInputTextWithRegion(\n step: Step<TextStepData>,\n /**\n * @deprecated\n */\n curFontSize: number,\n /**\n * @deprecated\n */\n curFontData: FontData,\n input: string | undefined,\n storage: TextStepStorage,\n workflowManager: WorkflowManager,\n customiseAllText: boolean,\n setError: (errorMessage?: string) => void,\n setHelperText: (text: string) => void,\n setFlashRedError?: (status: boolean) => void,\n ): Promise<GroupCommand | undefined> {\n // Control characters are not valid in XML, we strip them from any input to\n // ensure that invalid data doesn't enter the SVG generated by our system.\n // \\u000A and \\u000D are carriage return and newline sequences, we want to keep these.\n // eslint-disable-next-line no-control-regex\n const newText = (input || \"\").replace(/^(?![\\u000A\\u000D])[\\u0000-\\u001F\\u007F-\\u009F]/g, \"\");\n const renderedText = renderTextTemplateForWorkflow(newText, workflowManager);\n const transformedText = this.getProcessedInput(renderedText, step.data, customiseAllText);\n\n const existingRegionEls = workflowManager.getRegionElements(step.stepName);\n const correctFontSizes = new Map<string, number>();\n const correctLineLists = new Map<string, null | string[]>();\n\n // Calculate font size and lines with new text.\n for (const regionElement of existingRegionEls) {\n if (regionElement.region) {\n const [newFontSize, newLines] = determineCorrectFontSizeAndLines(\n curFontSize,\n curFontData,\n regionElement.region,\n [transformedText],\n { size: step.data.size, minSize: step.data.minSize, maxSize: step.data.maxSize },\n );\n correctFontSizes.set(regionElement.id, newFontSize);\n correctLineLists.set(regionElement.id, newLines);\n }\n }\n\n const helperTextGenerator = () => {\n // Ensure character limit is maintained\n if (!!step.data && !!step.data.maxLength && transformedText.length > step.data.maxLength) {\n if (setFlashRedError) {\n setFlashRedError(true);\n }\n return { info: \"0\" };\n }\n\n // Check text against our blacklist\n const profanityFilter = workflowManager.getWorkflowExperience().getProfanityList();\n const words = split(transformedText.toLowerCase());\n for (const word of words) {\n for (const i in profanityFilter) {\n const profanity = profanityFilter[i].toLowerCase().replace(/\\s/g, \"\");\n const match = word === profanity;\n if (match) {\n const msg = \"Blocked profanity.\";\n setError(msg);\n return { error: msg };\n }\n }\n }\n\n // Potentially don't allow newlines.\n if (\n !step.data.vertical &&\n !step.data.allowNewlines &&\n (transformedText.includes(\"\\n\") || transformedText.includes(\"\\r\"))\n ) {\n const msg = \"Text may not span multiple lines.\"; \n setError(msg);\n return { error: msg };\n }\n\n if (!step.data.curved) {\n const allFit = Array.from(correctLineLists.values()).every((x) => x);\n if (!allFit) {\n const msg = \"Text does not fit.\" \n setError(msg);\n return { error: msg };\n }\n }\n\n setError(undefined);\n return { info: (step.data.maxLength - transformedText.length).toString() };\n };\n\n // Check the input text for validity.\n const newHelperText = helperTextGenerator();\n\n if (newHelperText.error) {\n setHelperText(newHelperText.error);\n return;\n }\n\n setHelperText(`${newHelperText.info} characters remaining` || \"\");\n\n if (setFlashRedError) {\n return;\n }\n\n workflowManager.updateStorage(step.stepName, { text: newText });\n workflowManager.updateMetadata(step.stepName, {\n text: this.injectReplaceableText(newText, step.data),\n });\n\n if ((storage.defaultCleared || !step.data.deleteDefaultOnFocus) && newText.trim() !== \"\") {\n workflowManager.setMandatoryFulfilled(step.stepName, true);\n }\n const commands: CanvasCommand[] = [];\n for (const regionElement of existingRegionEls) {\n const newText = step.data.curved\n ? transformedText\n : (correctLineLists.get(regionElement.id) || []).join(\"\\n\");\n commands.push(\n this.generateTextChangeCommandsForRegion(\n correctFontSizes.get(regionElement.id) || 1,\n step.data,\n regionElement.id,\n newText,\n ),\n );\n }\n\n const groupCommand = new GroupCommand(commands);\n return groupCommand;\n }\n}\n\nexport const textStepService = new TextStepService();\n","import { Region } from \"../types\";\n\nexport abstract class ModuleProduct {\n /**\n * Name used by class. Usually product or brand name.\n */\n abstract moduleName: string;\n\n /**\n * SVG with styled path positioned on a background image. To be displayed to user.\n */\n abstract svgPreview(text: string, region: Region): string;\n\n /**\n * SVG with styled path positioned on a background image. To be submitted for print.\n */\n abstract svgPrint(text: string, region: Region): string;\n}\n","export const fontTtfDataUrl =\n \"data:application/octet-stream;base64,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DOYNZA3mDlQOyg88D54QEBCGEQARchHsEmIS1BOWFAwUghTwFWIV1BaiFxQXkhgEGMYZdBomGtQbfhwYHL4dYB3+HpgfPh/oIJYhPCHmIpQjRiPsJJolSCXuJpQnQifoKJIpRAAmAAn/8QAK//sADP/7AA3/+wAO//sAD//7ABD/+wAR//sAEv/7ABP/+wAU//sAFf/xABb/8QAZ//sAHf/2AB7/+wAf//sAIP/xACH/+wAi//sAI//7ACT/+wAl//EAJv/2ACf/8QAo//sAKf/2ACr/+wAr//sALP/sAC3/7AAu/+IAL//dADD/9gAx/+wAMv/7ADP/+wA0//YAKwAG//EACP/nAAn/4gAK/9MAC//iAAz/9gAN/+IADv/sAA//4gAQ/9gAEf/iABL/1QAT//EAFP/nABX/8QAW/9gAMf/TADL/pgAz//MANP/nADX/8QA2//EAN//7ADj/7gA5//YAOv/7ADv/2AA8//EAPf/2AD7/9gA///EAQP/sAEH/+wBC/+wAQ//xAET/7ABF/+wARv/2AEf/3QBI/90ASf/EAEr/zgBL//YAKwAG//YAB//2AAn/3QAL/+wADP/sAA3/8QAO//YAD//sABD/8QAR/+wAEv/iABP/5wAU/+wAFf/dABb/7AAX/78AMf/YADL/sAAz/+IANP/iADX/8QA2/+cAN//xADj/3QA5/+wAOv/2ADv/4gA8//EAPf/xAD7/8QA///YAQP/YAEH/9gBC/+cAQ//sAET/7ABF/+wARv/xAEf/zgBI/9MASf/OAEr/zgBL/+wAKgAG//YAB//iAAj/4gAK/+IADP/dAA3/ugAO/+IAD//iABD/5wAR/+IAEv/dABP/yQAU/90AFf+mABb/0wAx/5gAMv/YADP/4gA0/9MANf/xADb/7AA3/+wAOP/iADn/7AA6//EAO//dADz/5wA9/+wAPv/sAD//5wBA/9gAQf/sAEL/zgBD/+wARP/YAEX/tQBG/90AR/+hAEj/oQBJ/8QASv+DAEv/7AAqAAb/8QAH/90ACP/YAAn/oQAL/8kADP/iAA3/sAAO/+cAD//YABD/4gAR/90AEv/bABP/4gAU/+IAFf/TABb/5wAg/+QAMf/nADL/3AAz//QANP/rADX/9AA2//IAN//4ADj/8AA5//QAOv/1ADv/7AA8/+oAPf/7AD7/9wA///IAQP/tAEH/+wBC/+IAQ//2AET/4wBF/7YARv/vAEf/pgBK/6MAS//yACYAB//TAAj/8QAK/84ADP/dAA3/9gAO//EAD//dABD/pgAR/8kAEv+6ABP/7AAU/90AFf/OADH/xAAy/5IAM//sADT/3QA1/+cANv/xADf/9gA4/90AO/9WADz/5wA9//EAPv/sAD//5wBA/84AQf/dAEL/0wBD/+cARP/nAEX/5wBG/+cAR//dAEj/2ABJ/7oASv/JAEv/4gAsAAb/+wAH//sACP/xAAn/zgAK/+cAC//dAAz/9gAN/9gADv/tAA//7AAQ/+kAEf/rABL/3QAT/90AFP/hABX/3QAW/90AMf/nADL/vwAz/+cANP/nADX/8QA2//EAN//sADj/5wA5//YAOv/2ADv/4gA8//EAPf/2AD7/+wA///sAQP/2AEH/+wBC/+wAQ//7AET/7ABF/9MARv/7AEf/yQBI/84ASf+wAEr/xABL/+cADgAG//sACf/xAAv/7AAN//sADv/7AA8AAAAR//EAEv/0ABP/9gAU//EAFf/xABb/7AAx//YAQP/2ACkABv/7AAf/9gAI//sACf/iAAr/5wAL/+wADP/vAA3/3QAO//sAD//qABD/8QAR/+wAEv/nABP/8QAU/+cAFf/iABb/7AAx/+cAMv/vADP//AA0/+cANf/7ADb//gA4//EAOf/8ADr//AA7/+kAPP/6AD3//QA+//4AP//7AEL/6gBD//0ARP/2AEX/7ABG//EAR//YAEj/4gBJ/+wASv/LAEv//AAsAAb/+wAH//EACP/2AAn/0wAK/+IAC//JAAz/5wAN/90ADv/iAA//7AAQ/+cAEf/sABL/3QAT/9MAFP/iABX/zgAW/+cAMf/YADL/xAAz/+wANP/dADX/6AA2//EAN//xADj/4wA5//EAOv/2ADv/7AA8/+wAPf/sAD7/9gA//+wAQP/iAEH/8QBC/90AQ//nAET/5wBF/8QARv/mAEf/xABI/8kASf+1AEr/rQBL/+IALAAG//sAB//7AAj/9gAJ/9MACv/2AAv/ugAM/+kADf/dAA7/9gAP/+wAEP/2ABH/8AAS//EAE//2ABT/5wAV/9gAFv/sADH/vwAy/9UAM//eADT/3wA1//EANv/xADf/9gA4/+IAOf/xADr/9gA7/+wAPP/xAD3/9gA+//EAP//2AED/2ABB//EAQv/nAEP/9gBE/+cARf/TAEb/8QBH/9gASP/YAEn/xgBK/78AS//xACsABv/7AAf/9gAI/+wACf/TAAr/5wAL/90ADP/lAA3/zgAO/90AD//dABD/7AAR/+IAEv/iABP/2AAU/+IAFf/JABb/5wAx/90AMv/EADP/6wA0/+EANf/wADb/8AA4/9wAOf/dADr/7AA7/9gAPP/sAD3/5wA+/+wAP//iAED/0wBB/+IAQv/YAEP/4gBE/84ARf/JAEb/4gBH/8kASP/OAEn/vwBK/8kAS//TACwABv/7AAf/3wAI/+cACf+wAAr/4wAL/8kADP/dAA3/xwAO/+cAD//dABD/7AAR/+cAEv/iABP/yQAU/9cAFf+/ABb/4gAa/+kAMf/YADL/uwAz/+EANP/dADb/6wA3//MAOP/lADn/8QA6//IAO//eADz/5wA9/+4APv/zAD//8ABA/+IAQf/2AEL/6gBD//YARP/kAEX/zABG/+8AR/+0AEj/uwBJ/64ASv+vAEv/5QAsAAb/+wAH/90ACP/nAAn/4gAK/9MAC//nAAz/3QAN//YADv/eAA//3QAQ/7AAEf/OABL/sAAT//sAFP/dABX/0wAW/9MAMf/iADL/iAAz//YANP/OADX/9gA2//EAN//xADj/0wA5//YAOv/zADv/gAA8//EAPf/7AD7/+wA///YAQP/OAEH/7gBC/84AQ//2AET/2ABF//sARv/2AEf/5wBI/+cASf/TAEr/4gBL/+wALAAG//sAB//2AAj/8QAJ/9gACv/nAAv/3QAM/+IADf/dAA7/4gAP/+IAEP/nABH/5wAS/9gAE//YABT/3QAV/84AFv/sADH/5wAy/78AM//nADT/2AA1/+cANv/nADf/7AA4/90AOf/sADr/7AA7/+cAPP/sAD3/8QA+/+wAP//xAED/4gBB//EAQv/dAEP/5wBE/+IARf/YAEb/5wBH/78ASP/HAEn/sABK/7UAS//dACsABv/xAAf/8QAI/+IACf/dAAr/0wAL/+IADP/iAA3/3QAO/+cAD//dABD/zgAR/9MAEv/EABP/0wAU/84AFv/dADH/4gAy/6EAM//jADT/3QA1/+wANv/sADf/5wA4/90AOf/nADr/8QA7/78APP/xAD3/9gA+/+wAP//nAED/3QBB/+cAQv/nAEP/5wBE/+IARf/OAEb/3QBH/8QASP/JAEn/lwBK/7oAS//YACkABv/sAAf/0wAI/90ACf/OAAr/3QAM/90ADf/EAA7/5wAP/9gAEP/YABH/3QAS/9MAE//YABT/4gAV/90AMf/sADL/wAAz/+8ANP/kADX/6wA2//AAN//2ADj/5AA5//EAOv/uADv/1gA8//QAPf/2AD7/8QA///AAQP/dAEH/7ABD/+gARP/YAEX/1QBG/+wAR/+3AEj/wwBJ/7UASv+wAEv/5gAeAAf/zgAi/+4AI//5ACT/7wAy/9AAM//pADT/sQA1/+sANv/nADf/5gA4/7oAOf/vADr/9wA7/9AAPP/sAD3/6wA+/+YAP//sAED/uwBB/+kAQv+7AEP/5ABE/9QARf+6AEb/0ABH/34ASP+SAEn/zQBK/5sAS//nABwAF//RACT//wAy/9EAM//uADT/5wA1/+8ANv/3ADf/7gA4/+gAOf/3ADr/+wA7/9oAPP/vAD3/9wA+/+4AP//vAED/4QBB//cAQv/nAEP/7wBE/+4ARf/QAEb/9wBH/8EASP/MAEn/wwBK/7sAS//nABwAF//QABv/+QAy/8EAM//zADT/6wA1//sANv/zADf/+wA4/+8AOf/zADr//gA7/+EAPP/vAD3/9wA+//kAP//3AED/4gBB//kAQv/jAEP/8wBE/+YARf/VAEb/+QBH/84ASP/JAEn/twBK/8EAS//rAB8ABv/7ABL/3wAX/8kAJf/5ACv/7wAy/7oAM//zADT/6wA1/+8ANv/uADf/8wA4/+oAOf/vADr/7wA7/9QAPP/5AD3//gA+//EAP//vAED/4wBB//MAQv/mAEP/7gBE/+cARf/XAEb/6wBH/8kASP/JAEn/twBK/7cAS//nACAABv/7ACQAAgAl/+8AJ//5AC3//gAv//4AMv/oADP//QA0/+sANf/7ADb/+gA3//sAOP/jADn/9wA6//oAO//kADz//wA9//0APv/+AD8AAABA/+gAQf/7AEL/6ABD//sARP/sAEX/8QBG//sAR//qAEj/6wBJ/+cASv/qAEv/+QAbAAb/+wAl/+8AMv+5ADP/+wA0/+8ANf/7ADb/+wA3//0AOP/vADn/+wA6AAAAO/+7ADz//gA9//4APv/7AED/7ABB//4AQv/nAEP/+QBE//kARf/7AEb/+QBH//MASP/rAEn/4gBK/+8AS//7AB0ABv/2ABf/zgAl/+8AMv+3ADP/9wA0/+sANf/3ADb/8QA3//kAOP/uADn/8wA6//sAO//YADz/8wA9/+4APv/3AD//8wBA/+MAQf/3AEL/6QBD/+8ARP/nAEX/1ABG/+8AR//JAEj/zABJ/6YASv/JAEv/3AAcAAb/+wAX//MAJf/7ADL/6wAz//4ANP/uADX/+wA2//4AN//+ADj/8wA5//0AOv/+ADv/7gA8//4APf/+AD7/+wA///4AQP/uAEL/9wBD//4ARP/+AEX/+QBG//4AR//uAEj/9wBJ/+4ASv/zAEv//gAYAAb/+wAx//YAMv/rADP//wA0//MANf//ADYAAQA3//8AOP/zADv/6AA8//4APf/+AD4AAQBA/+4AQf//AEL/8wBD//4ARP/4AEX//QBH/+wASP/3AEn/7ABK//EASwABABwABv/2ABf/4QAy/8oAM//9ADT/+QA1//4ANv/7ADf//gA4//MAOf/+ADr//wA7/+EAPP/7AD3//gA+//4AP//+AED/7wBB//4AQv/zAEP//gBE//sARf/7AEb//gBH/+8ASP/5AEn/2gBK//oAS//+AB0ABv/nABf/5wAx/7AAMv/hADP/7gA0/7QANf/rADb/5wA3/+4AOP+sADn/6wA6//kAO/+3ADz/6gA9/+8APv/nAD//5wBA/6wAQf/uAEL/rgBD/+cARP+8AEX/3ABG/9oAR//cAEj/0QBJ/9oASv/RAEv/7wAeAAb/9gAX//cAI//9ADH/vwAy/+4AM//5ADT/2gA1//4ANv/3ADf/+wA4/9oAOf/3ADr/+wA7/+cAPP/7AD3/+QA+//cAP//5AED/1ABB//sAQv/cAEP/9wBE/+8ARf/JAEb/6wBH/8QASP++AEn/5wBK/8EAS//+ABwAF//7ADH/7AAy/+QAM//+ADT/7gA1//4ANgAAADf//QA4//cAOf/7ADr//gA7/+4APP/+AD3//gA+//0AP//7AED/7wBB//4AQv/uAEP//gBE//cARf/7AEb/+QBH/+gASP/vAEn/6wBK/+gAS//+AB4ABv/7ABf/8wAa//4AHf/3ACX/9wAq//4AMf/2ADL/5AAz//0ANP/zADX/+wA2//4AN//+ADj/+QA7/+4APf/+AD7/+wA///4AQP/2AEH/+gBC/+4AQ//7AET/+QBF//sARv/+AEf/8wBI/+8ASf/zAEr/6wBL//4AHQAG//EAJP/3ADH/7AAy/7sAM//sADT/4wA1/+8ANv/vADf/9wA4/+QAOf/qADr/9wA7/98APP/vAD3/9wA+/+sAP//uAED/4wBB/+4AQv/mAEP/7wBE/+IARf/VAEb/7gBH/8MASP/GAEn/uwBK/7oAS//fABwABv/sACT//gAy/54AM//rADT/6gA1//EANv/rADf/9wA4/+MAOf/oADr/9wA7/64APP/sAD3/8QA+/+wAP//sAED/4QBB//MAQv/oAEP/5ABE/9gARf/kAEb/7gBH/9EASP/QAEn/uwBK/8QAS//zADAAF//3ABj//wAZ/+kAGv//ABv//QAc//4AHf/pAB7/+wAf//8AIP/iACH//gAi//8AI//+ACT//wAl/+IAJ//uACj//gAp/+cAKv/hACv/+QAs/8MALf/QAC7/5AAv/8wAMP//ADL/4QAz//4ANP/jADX/9wA3//kAOP/fADn/9wA7/+IAPP/5AD3/+gA+//EAP//6AED/2gBB/+8AQv/aAET/7wBF/9cARv/qAEf/xgBI/7sASf/qAEr/tABL//sAHQAG/+cAF//oACT/+gAy/+IAM//xADT/zAA1/+8ANv/sADf/+gA4/8wAOf/3ADr/8wA7/8kAPP/uAD3/7wA+/+wAP//rAED/yQBB//cAQv/MAEP/+ABE/9QARf/KAEb/2gBH/8EASP/EAEn/4gBK/7cAS//vAB0ABv/xABv/+QAl/+4AMv+8ADP/7wA0/9wANf/zADb/6AA3//cAOP/hADn/5gA6//MAO//aADz/6QA9//MAPv/pAD//6wBA/+MAQf/3AEL/2gBD/+kARP/rAEX/1ABG/+kAR//JAEj/zABJ/7QASv+7AEv/5wAbAAb/9gAy/6YAM//9ADT/0wA1//oANv/+ADf//QA4/9UAOf/3ADr//wA7/7kAPP/6AD3//gA+//sAP//7AED/0ABB//oAQv/XAEP/+QBE/+IARf/zAEb/9wBH/+8ASP/vAEn/6gBK/+cAS//6ABwABv/7ACQAAgAy/9UAM//7ADT/7wA1//cANv/9ADf//wA4/+4AOf/7ADr//wA7/+sAPP/+AD3//gA+//0AP//6AED/7gBB//sAQv/sAEP/+wBE/+8ARf/7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ABX/3QAx//YAMv+5ADP/+AA0/+MANf/3ADb/+AA3//kAOP/iADn/+gA6//0AO//OADz//QA9//4APv/5AD///ABA/+YAQv/jAEP/9wBE/+YARf/vAEb//gBH/+cASP/vAEn/0QBK/+YAS//9ACgAB//2AAj/4gAJ/90ACv/sAAv/4gAM/+gADf/iAA7/9QAP/+gAEP/dABH/4AAS/+YAE//OABT/4gAV/90AJP/7ADH/9gAy/8EAM//vADT/3wA2//QAN//4ADj/4wA5/+kAOv/6ADv/0QA8/+YAPf/zAD7/6QA///EAQP/qAEL/3ABD/+gARP/fAEb/+ABH/7sASP+7AEn/rwBK/68AS//jACcACP/xAAn/7AAK//gADP/2AA7/9wAP//YAEP/xABH/5wAS/+cAE//xABT/7AAV/+UAMf/2ADL/6AAz//kANP/qADX/+wA2//oAN//7ADj/6wA5//cAOv//ADv/4wA8//sAPf/+AD7/+wA///oAQP/sAEH/+gBC/+MAQ//5AET/7wBF/+oARv/7AEf/4wBI/+wASf/jAEr/6gBL//4AJgAH//sACP/7AAn/5wAK//oADP/2AA7/9gAP//YAEP/xABH/8QAS//IAE//xABT/5wAV//EAMv/nADP/+wA0//EANf/9ADb//gA3//4AOP/uADn/+wA6//4AO//oAD0AAAA+//sAP//+AED/7wBB//4AQv/qAEP//wBE//EARf/3AEb/+wBH/+YASP/3AEn/2gBK/+QAS//7ACkAB//2AAj/9gAJ/90ACv/yAAz/8QAO//EAD//wABD/6gAR/+wAEv/mABP/9AAU/+wAFf/rABf/zgAx//YAMv/OADP/7wA0/+oANf/5ADb//gA3//0AOP/oADn/+QA6//0AO//YADz//gA9//8APv/6AD//+QBA/+4AQf/5AEL/4wBD//gARP/qAEX/+QBG//oAR//pAEj/6QBJ/9UASv/rAEv/+gAqAAf/sgAI/8kACf+wAAr/ugAL/7UADP+1AA3/3QAO/+QAD/+6ABD/sgAR/7UAEv+xABP/4gAU/6sAFf+mADH/lwAy/9oAM//jADT/qwA1/+IANv/iADf/4wA4/5oAOf/XADr/7gA7/7QAPP/kAD3/6wA+/+4AP//mAED/rQBB/+8AQv+qAEP/6gBE/74ARf/XAEb/2gBH/9AASP/SAEn/1QBK/80AS//qACsAB//nAAj/8QAJ/6YACv/sAAv/nAAM/90ADf+6AA7/9gAP/+IAEP/sABH/3QAS/9oAE//sABT/3QAV/8QAJP/+ADH/pgAy/+sAM//vADT/ygA1//0ANv/zADf/+wA4/9MAOf/vADr/+wA7/9gAPP/3AD3/9wA+//EAP//7AED/1QBB//cAQv/PAEP/8wBE/+YARf+7AEb/5wBH/7UASP/JAEn/2gBK/6UAS//zACkAB//2AAn/7AAK//kAC//sAAz/9gAO//oAD//2ABD/7AAR/+cAEv/vABP/9gAU//EAFf/sABcAAQAx/+YAMv/pADP/+QA0/+oANf/zADb/+wA3//oAOP/nADn/9wA6//4AO//uADz/+QA9//oAPv/7AD//+QBA/+8AQf/3AEL/6QBD//oARP/sAEX/8wBG//gAR//pAEj/6QBJ/+MASv/nAEv//QAqAAf/9gAI//sACf/sAAr/9wAL/+wADP/7AA7/+gAP//EAEP/2ABH/7AAS//EAE//2ABT/9gAV/+QAFwABADH/8QAy/+kAM//3ADT/6QA1//kANv/5ADf/+QA4/+8AOf/6ADr//gA7/+8APP/7AD3/+gA+//oAP//4AED/7wBB//sAQv/rAEP//QBE/+8ARf/3AEb/+gBH/+4ASP/rAEn/4QBK/+wAS//5ACsAB//xAAj/4gAJ/9gACv/sAAv/2AAM//YADf/iAA7/8QAP/90AEP/iABH/0wAS/+IAE//JABT/4gAV/94AJP/7ADH/3QAy/7QAM//pADT/4QA1/+wANv/vADf/6gA4/+IAOf/qADr/+gA7/9oAPP/pAD3/6wA+/+wAP//pAED/4QBB/+sAQv/cAEP/6wBE/+IARf/JAEb/7gBH/7wASP/BAEn/pgBK/7UAS//kACwAB//iAAj/5wAJ/+IACv/OAAv/2AAM/+cADf/nAA7/8AAP/90AEP+6ABH/xAAS/9cAE//XABT/2AAV/9gAG//3ACT/+wAx/+IAMv+gADP/6QA0/+MANf/mADb/7wA3/+sAOP/aADn/6AA6//YAO/+xADz/6wA9/+4APv/oAD//7wBA/9oAQf/oAEL/1wBD/+MARP/aAEX/2ABG/+cAR//PAEj/yQBJ/7kASv/BAEv/6AApAAf/8QAI/+wACf/OAAr/6gAL/84ADP/nAA3/2AAO//YAD//fABD/4gAR/9gAEv/lABP/5wAU/+IAFf/YADH/4gAy/+cAM//3ADT/2gA1//gANv/5ADf/+wA4/9wAOf/3ADr//gA7/+MAPP/3AD3//QA+//cAP//3AED/1QBC/9UAQ//9AET/6QBF/+EARv/pAEf/ugBI/8QASf/aAEr/wgBL//sAKwAH/8kACP/YAAn/xAAK/9MAC/+/AAz/yQAN/9gADv/nAA//xAAQ/7oAEf+1ABL/wQAT/9gAFP+6ABX/vwAk//sAMf+/ADL/2gAz/+gANP/KADX/6QA2/+kAN//oADj/xgA5/+QAOv/nADv/uQA8/+wAPf/uAD7/6QA//+cAQP/GAEH/7ABC/8kAQ//mAET/2ABF/84ARv/VAEf/wQBI/7wASf/GAEr/tABL/+8AKwAH//EACP/2AAn/yQAK/+oAC//TAAz/3QAN/+cADv/sAA//4gAQ/+IAEf/YABL/3wAT/90AFP/dABX/2AAk//sAMf/nADL/xgAz//MANP/iADX/7wA2/+4AN//3ADj/4wA5/+kAOv/vADv/1wA8/+4APf/zAD7/6gA//+0AQP/kAEH/9wBC/98AQ//qAET/5wBF/9AARv/vAEf/yQBI/9AASf/PAEr/xABL/+8AKQAH/+cACP/sAAn/5wAK/+kAC//dAAz/2AAO/+wAD//XABD/qwAR/8kAEv/AABP/9gAU/9MAFf/OADH/2AAy/7AAM//5ADT/2gA1//0ANv/6ADf//gA4/98AOf/3ADr//QA7/8YAPP/7AD3//gA+//gAP//4AED/1QBB//0AQv/VAEP/+ABE/+MARf/zAEb/+QBH/+4ASP/zAEn/4gBK/+cAS//zACkACP/2AAn/5wAK//QAC//sAAz/+wAN//4ADv/2AA//5QAQ/+wAEf/nABL/8wAT//EAFP/nABX/3QAx/+QAMv/KADP/+QA0/+wANf/6ADb/+gA3//sAOP/vADn/+gA6AAAAO//hADz//wA9//0APv/5AD///gBA/+wAQf/7AEL/7ABD//sARP/vAEX/9wBG//sAR//zAEj/6gBJ/+EASv/jAEv/+wArAAf/zgAI/84ACf/YAAr/ygAL/9gADP/JAA3/+wAO/9kAD//JABD/ogAR/7oAEv+5ABP/5wAU/8QAFf+9ACT/+wAx/7oAMv+FADP/+wA0/7sANf/qADb/6wA3/+wAOP++ADn/5gA6/+8AO/+iADz/6AA9/+oAPv/sAD//7wBA/8MAQf/mAEL/uwBD/+YARP/KAEX/6QBG/+8AR//jAEj/3wBJ/9MASv/hAEv/6wApAAf/zgAI/84ACf/TAAv/2AAM/84ADv/eAA//xAAQ/7AAEf/TABL/sQAT/+wAFP/FABX/yQAk//sAMf/JADL/lQAz//MANP/BADX/+QA2//MAN//3ADj/xgA5//sAOv/3ADv/pQA8/+8APf/+AD7/7gA//+oAQP/DAEH/7gBC/8QAQ//vAET/0ABF/+4ARv/uAEf/6QBI/+QASf/aAEr/5gBL//cAKgAH/8QACP/OAAn/pgAL/7oADP+rAA3/3QAO/+cAD/+5ABD/twAR/8QAEv+zABP/0wAU/7AAFf+cACT/+wAx/6EAMv/aADP/4wA0/7cANf/4ADb/4wA3//0AOP+3ADn/7gA6/+8AO/+7ADz/7gA9//EAPv/jAD//6ABA/7oAQf/zAEL/uQBD/+sARP/OAEX/3wBG/+EAR//aAEj/2ABJ/9gASv/MAEv/7gAsAAf/yQAI/84ACf/JAAr/wgAL/8kADP/JAA3//gAO/8kAD/+6ABD/jQAR/7oAEv+gABP/4gAU/7UAFf+6AB7/8QAk//sAMf+1ADL/lwAz/+8ANP+7ADX/5gA2/+4AN//uADj/uQA5/+gAOv/3ADv/hAA8/+8APf/sAD7/7AA//+oAQP+6AEH/7ABC/7kAQ//pAET/ygBF/+8ARv/vAEf/6ABI/+kASf/fAEr/5ABL//EAJgAH//YACf/iAAr/7AAL/+cADP/iAA3//wAO//UAD//nABD/7AAR/+IAEv/gABP/7AAU/90AFf/TADH/4gAy/+sAM//+ADT/6AA1//4ANgAEADf//wA4/9wAOf/6ADv/5gA8//8APf//AD///QBA/+MAQf//AEMAAABE/+8ARf/4AEb/+wBH//cASP/rAEn/6QBK/+kAS//9AAIAAQAGAEsAAAAAAAAAAQAAAADUGBYRAAAAANmXsTQAAAAA2ZexNA==\";\n","/**\n * Functions for creating SVGs and SVG elements.\n */\n\nimport { createElement, createElementNS } from \"../../util/crossplatform\";\nimport { generate } from \"../../util/guid\";\n\n\nexport const svgElem = (type: string): SVGElement => {\n return createElementNS(\"http://www.w3.org/2000/svg\", type);\n};\n\nexport const svgRect = (height: number, width: number): SVGElement => {\n const el = svgElem(\"rect\");\n el.setAttribute(\"height\", `${height}`);\n el.setAttribute(\"width\", `${width}`);\n return el;\n};\n\nexport const svgRoot = (): SVGElement => {\n const el = svgElem(\"svg\");\n el.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\n el.setAttribute(\"xmlns:xlink\", \"http://www.w3.org/1999/xlink\");\n el.setAttribute(\"version\", \"1.1\");\n return el;\n};\n\nexport const svgUse = (link: string): SVGElement => {\n const el = svgElem(\"use\");\n el.setAttribute(\"xlink:href\", link); // For environments where plain href is not supported.\n el.setAttribute(\"href\", link); // For environments where xlink:href is deprecated.\n return el;\n};\n\n// Create SVG with height and width of supplied SVG string.\nexport function initSvgFromBackground(img: string): [SVGElement | null, number, number] {\n const svg = svgRoot();\n\n // Get dimensions\n const matches = /viewBox=\"0 0 (.+?) (.+?)\"/.exec(img) || [\"0\", \"0\"];\n const bgWidth = parseFloat(matches[1]);\n const bgHeight = parseFloat(matches[2]);\n\n svg.setAttribute(\"height\", `${bgHeight}`);\n svg.setAttribute(\"width\", `${bgWidth}`);\n return [svg, bgHeight, bgWidth];\n}\n\n// Create SVG with supplied height and width.\nexport function initSvgFromDimensions(bgHeight: number, bgWidth: number): SVGElement {\n const svg = svgRoot();\n svg.setAttribute(\"height\", `${bgHeight}`);\n svg.setAttribute(\"width\", `${bgWidth}`);\n return svg;\n}\n\n// Add a definition by setting innerHTML to defText.\nexport const addDef = (defs: SVGElement, defText: string, id: string) => {\n const elem = svgElem(\"g\");\n defs.appendChild(elem);\n elem.setAttribute(\"id\", id);\n elem.innerHTML = defText;\n};\n\n// Add background image to SVG.\nexport function addBackground(svg: SVGElement, defs: SVGElement, backgroundImg: string) {\n const uuid = generate();\n addDef(defs, backgroundImg, `bgdef-${uuid}`);\n svg.appendChild(svgUse(`#bgdef-${uuid}`));\n}\n\n// Definition for drop shadow.\nexport const dropShadow = (dx: number, dy: number, blur: number, id: string): HTMLElement => {\n const shadow = createElement(\"filter\");\n shadow.setAttribute(\"id\", id);\n shadow.setAttribute(\"height\", \"200%\");\n shadow.setAttribute(\"width\", \"200%\");\n shadow.setAttribute(\"x\", \"-50%\");\n shadow.setAttribute(\"y\", \"-50%\");\n\n const feOffset = createElement(\"feOffset\");\n shadow.appendChild(feOffset);\n feOffset.setAttribute(\"result\", \"offOut\");\n feOffset.setAttribute(\"in\", \"SourceAlpha\");\n feOffset.setAttribute(\"dx\", `${dx}`);\n feOffset.setAttribute(\"dy\", `${dy}`);\n\n const feGaussianBlur = createElement(\"feGaussianBlur\");\n shadow.appendChild(feGaussianBlur);\n feGaussianBlur.setAttribute(\"result\", \"blurOut\");\n feGaussianBlur.setAttribute(\"in\", \"offOut\");\n feGaussianBlur.setAttribute(\"stdDeviation\", `${blur}`);\n\n const feBlend = createElement(\"feBlend\");\n shadow.appendChild(feBlend);\n feBlend.setAttribute(\"in\", \"SourceGraphic\");\n feBlend.setAttribute(\"in2\", \"blurOut\");\n feBlend.setAttribute(\"mode\", \"normal\");\n\n return shadow;\n};\n","/**\n * Functions for modifying SVGs and SVG elements.\n */\n\nimport { BBox } from \"svg-path-bbox\";\n\n/**\n * The innerHTML/outerHTML properties of an element does not respect case.\n * This function restores case to case-sensitive elements.\n */\nexport const fixCase = (svg: string): string => {\n let str = svg;\n str = str.replace(/feoffset/gi, \"feOffset\");\n str = str.replace(/fegaussianblur/gi, \"feGaussianBlur\");\n str = str.replace(/feblend/gi, \"feBlend\");\n str = str.replace(/lineargradient/gi, \"linearGradient\");\n str = str.replace(/stddeviation/gi, \"stdDeviation\");\n return str;\n};\n\n// Translate and scale the group containing the text.\nexport function transformTextEnclosure(\n textEnclosure: SVGElement,\n textBbox: BBox,\n boundsHeight: number,\n boundsWidth: number,\n heightPaddingFactor?: number,\n widthPaddingFactor?: number,\n) {\n const heightPadFactor = heightPaddingFactor || 1;\n const widthPadFactor = widthPaddingFactor || 1;\n\n const textRect = {\n x: textBbox[0],\n y: textBbox[1],\n width: textBbox[2] - textBbox[0],\n height: textBbox[3] - textBbox[1],\n };\n if (textRect.width <= 0) {\n return;\n }\n const scaleFactor = boundsScaleFactor(textRect.height, textRect.width, boundsHeight*heightPadFactor, boundsWidth*widthPadFactor);\n const shiftLeft = (boundsWidth - scaleFactor * textRect.width) / 2 - scaleFactor * textRect.x;\n const shiftTop = (boundsHeight - scaleFactor * textRect.height) / 2 - scaleFactor * textRect.y;\n textEnclosure.setAttribute(\"transform\", `translate(${shiftLeft} ${shiftTop}) scale(${scaleFactor} ${scaleFactor})`);\n}\n\n// Factor to multiply text dimensions by to scale it to the supplied bounds.\nfunction boundsScaleFactor(textRectHeight: number, textRectWidth: number, boundsHeight: number, boundsWidth: number) {\n const heightRatio = boundsHeight / textRectHeight;\n const widthRatio = boundsWidth / textRectWidth;\n if (heightRatio > 1 && widthRatio > 1) {\n // Text smaller than bounds.\n return Math.min(heightRatio, widthRatio);\n } else if (heightRatio > 1 && widthRatio < 1) {\n // Text shorter but wider than bounds.\n return widthRatio;\n } else if (heightRatio < 1 && widthRatio > 1) {\n // Text narrower but taller than bounds.\n return heightRatio;\n }\n return Math.min(heightRatio, widthRatio); // Text larger than bounds.\n}\n","import { ParseError } from \"../../util/exception\";\n\ntype Coords = number[];\n\n// A function from [x, y] to [x', y'].\ntype Transformer = (coords: Coords) => Coords;\n\ninterface Path {\n pathElement: SVGPathElement;\n pathData: Segment[];\n}\n\ninterface Segment {\n type: string;\n relative: boolean;\n // Plus any data stuck in for the segment.\n}\n\nconst segmentSchemas: { [key: string]: string[] } = {\n m: [\"x\", \"y\"],\n z: [],\n l: [\"x\", \"y\"],\n h: [\"x\"],\n v: [\"y\"],\n c: [\"x1\", \"y1\", \"x2\", \"y2\", \"x\", \"y\"],\n s: [\"x2\", \"y2\", \"x\", \"y\"],\n q: [\"x1\", \"y1\", \"x\", \"y\"],\n t: [\"x\", \"y\"],\n a: [\"rx\", \"ry\", \"xRotation\", \"largeArc\", \"sweep\", \"x\", \"y\"],\n};\n\n// An object that warps an SVG element.\n// Based on Warp.js.\nexport class Warp {\n private paths: Path[];\n\n constructor(elem: SVGElement) {\n const pathElements = Array.from(elem.querySelectorAll(\"path\"));\n this.paths = pathElements.map((pathElement: SVGPathElement) => {\n const pathString = pathElement.getAttribute(\"d\") || \"\";\n const pathData: Segment[] = this.parsePath(pathString);\n return { pathElement, pathData };\n });\n }\n\n transform(transformer: Transformer): void {\n for (const path of this.paths) {\n path.pathData = this.runTransformer(path.pathData, transformer);\n }\n this.update();\n }\n\n private encodePath(pathData: Segment[]): string {\n let prevType = \"\";\n const magnitude = 10 ** 2;\n const callback = (segment: Segment) => {\n const output: string[] = [];\n const outputType = segment.relative ? segment.type : segment.type.toUpperCase();\n let first = prevType !== outputType;\n const schema: string[] = segmentSchemas[segment.type];\n if (first) {\n output.push(outputType);\n prevType = outputType;\n }\n for (const property of schema) {\n const value = (segment as any)[property];\n let outputValue;\n switch (typeof value) {\n case \"boolean\":\n {\n outputValue = (value as any) | 0;\n }\n break;\n case \"number\":\n {\n outputValue = ((value * magnitude) | 0) / magnitude;\n }\n break;\n default:\n throw new ParseError(\"Failed to encode path.\");\n }\n if (!first) {\n output.push(\" \");\n }\n output.push(outputValue);\n first = false;\n }\n return output.join(\"\");\n };\n return pathData.map(callback).join(\"\");\n }\n\n private parsePath(pathString: string): Segment[] {\n const segmentExpr = /([mzlhvcsqta])([^mzlhvcsqta]*)/gi;\n const numberExpr = /-?[0-9]*\\.?[0-9]+(?:e[-+]?\\d+)?/gi;\n\n const pathData: { type; relative }[] = [];\n let segmentMatch;\n segmentExpr.lastIndex = 0;\n\n while ((segmentMatch = segmentExpr.exec(pathString))) {\n const type = segmentMatch[1].toLowerCase();\n const numbers = (segmentMatch[2].match(numberExpr) || []).map(parseFloat);\n const relative = type === segmentMatch[1];\n const schema: string[] = segmentSchemas[type];\n if (numbers.length < schema.length) {\n throw new ParseError(\n `Path type \"${type}\" given ${numbers.length} arguments, expected ${schema.length}.`,\n );\n }\n if (schema.length > 0) {\n if (numbers.length % schema.length !== 0) {\n throw new ParseError(\n `Path type \"${type}\" given ${numbers.length} arguments, not divisible by ${schema.length}`,\n );\n }\n for (let i = 0; i < numbers.length / schema.length; i++) {\n const segmentData = { type, relative };\n for (let j = 0; j < schema.length; j++) {\n (segmentData as any)[schema[j]] = numbers[i * schema.length + j];\n }\n pathData.push(segmentData);\n }\n } else {\n pathData.push({ type, relative });\n }\n }\n\n return pathData;\n }\n\n private runTransformer(path: any, transformer: Transformer): any {\n const pointGroups = [\n [\"x1\", \"y1\"],\n [\"x2\", \"y2\"],\n [\"x\", \"y\"],\n ];\n\n const callback = (segment: Segment) => {\n for (let i = 0; i < pointGroups.length; i++) {\n const [x, y]: string[] = pointGroups[i];\n if (x in segment && y in segment) {\n const oldPoints: Coords = [(segment as any)[x], (segment as any)[y]];\n const newPoints = transformer(oldPoints);\n if (newPoints.length < 2) {\n throw new ParseError(\"Transformer must return at least 2 points.\");\n }\n (segment as any)[x] = newPoints[0];\n (segment as any)[y] = newPoints[1];\n }\n }\n return segment;\n };\n\n return this.transformPath(path, callback as any);\n }\n\n private transformPath(path: any, transformer: Transformer): any {\n const newPath: number[] = [];\n for (let i = 0; i < path.length; i++) {\n const segment = JSON.parse(JSON.stringify(path[i]));\n const result: Coords = transformer(segment);\n if (Array.isArray(result)) {\n newPath.push(...result);\n } else if (result) {\n newPath.push(result);\n }\n }\n return newPath;\n }\n\n private update(): void {\n for (const { pathElement, pathData } of this.paths) {\n const pathString = this.encodePath(pathData);\n pathElement.setAttribute(\"d\", pathString);\n }\n }\n}\n","import { ModuleProduct } from \"../../ModuleProduct\";\nimport { fontTtfDataUrl } from \"./font\";\nimport { svgElem, dropShadow, svgRect } from \"../../svg/elements\";\nimport { fixCase, transformTextEnclosure } from \"../../svg/modify\";\nimport { Warp } from \"../../svg/Warp\";\nimport svgPathBbox from \"svg-path-bbox\";\nimport { Region } from \"../../../types\";\nimport { _loadFontExternalDataURL } from \"../../../util/font\";\n\nexport class Vegemite extends ModuleProduct {\n moduleName = \"Vegemite\";\n\n svgPreview(text: string, region: Region): string {\n return this.svgElement(text, region);\n }\n\n svgPrint(text: string, region: Region): string {\n return this.svgElement(text, region);\n }\n\n private svgElement(text: string, region: Region): string {\n const font = _loadFontExternalDataURL(fontTtfDataUrl);\n const capitalise = (word: string): string => word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();\n const parsedtext = text !== \"\" ? capitalise(text) : \"\";\n const basePath = font.getPath(parsedtext, 0, 72, 72);\n const pathSvg = basePath.toSVG(2);\n\n const box = basePath.getBoundingBox();\n const pathWidth = box.x2 - box.x1;\n const pathData = basePath.toPathData(3);\n\n const textSvg = (): SVGElement => {\n const g = svgElem(\"g\");\n g.classList.add(\"module-text-group\");\n const gdefs = svgElem(\"defs\");\n g.appendChild(gdefs);\n gdefs.appendChild(dropShadow(0, 2, 2, \"shadow\"));\n\n const thick = svgElem(\"path\");\n thick.setAttribute(\"d\", pathData);\n thick.setAttribute(\"stroke\", \"black\");\n thick.setAttribute(\"stroke-width\", \"3\");\n gdefs.appendChild(thick);\n\n const layer0 = svgElem(\"g\");\n layer0.classList.add(\"module-layer0\");\n g.appendChild(layer0);\n layer0.setAttribute(\"filter\", \"url(#shadow)\");\n layer0.innerHTML = thick.outerHTML;\n\n const layer1 = svgElem(\"g\");\n layer1.classList.add(\"module-layer1\");\n g.appendChild(layer1);\n layer1.setAttribute(\"stroke-width\", \"3\");\n layer1.setAttribute(\"stroke\", \"rgb(45,41,38)\");\n layer1.setAttribute(\"fill\", \"rgb(45,41,38)\");\n layer1.setAttribute(\"transform\", \"translate(0.5,0)\");\n layer1.innerHTML = pathSvg;\n\n const layer2 = svgElem(\"g\");\n layer2.classList.add(\"module-layer2\");\n g.appendChild(layer2);\n layer2.setAttribute(\"fill\", \"rgb(255,209,0)\");\n layer2.setAttribute(\"transform\", \"translate(1,-0.1)\");\n layer2.innerHTML = pathSvg;\n\n const layer3 = svgElem(\"g\");\n layer3.classList.add(\"module-layer3\");\n g.appendChild(layer3);\n layer3.setAttribute(\"fill\", \"white\");\n layer3.innerHTML = pathSvg;\n\n const warp = new Warp(g);\n warp.transform(([x, y]) => [x, y + (pathWidth / 2 - x) ** 2 / (pathWidth * 6)]); // Curve down from center\n return g;\n };\n\n const rootElement = svgElem(\"g\");\n rootElement.classList.add(\"module-root\");\n\n const defs = svgElem(\"defs\");\n rootElement.appendChild(defs);\n\n const bounds = svgElem(\"g\");\n bounds.classList.add(\"module-bounds\");\n rootElement.appendChild(bounds);\n const boundsRect = svgRect(region.height, region.width);\n boundsRect.setAttribute(\"opacity\", \"0\");\n bounds.appendChild(boundsRect);\n\n const textEnclosure = svgElem(\"g\");\n textEnclosure.classList.add(\"module-text-enclosure\");\n rootElement.appendChild(textEnclosure);\n\n const textGroup = textSvg();\n textEnclosure.appendChild(textGroup);\n\n const textBbox = svgPathBbox(pathData);\n transformTextEnclosure(textEnclosure, textBbox, region.height, region.width, 0.35, 0.65);\n\n return fixCase(rootElement.outerHTML);\n }\n}\n","import { UnhandledBehaviorError } from \"../util/exception\";\nimport { ModuleProduct } from \"./ModuleProduct\";\nimport { Vegemite } from \"./products/Vegemite\";\n\nexport default async function moduleResolver(moduleName: string): Promise<ModuleProduct> {\n if (moduleName === \"Vegemite\") {\n return new Vegemite();\n }\n throw new UnhandledBehaviorError(`Failed to resolve Module, Module ${moduleName} not found`);\n}\n","import { toString as urlToQrString } from \"qrcode\";\nimport {\n DesignInputStep,\n DigitalContentDesignInputStepData,\n FrameDesignInputStepData,\n IllustrationDesignInputStepData,\n ModuleDesignInputStepData,\n PictureDesignInputStepData,\n ShapeDesignInputStepData,\n TextDesignInputStepData,\n} from \"./types\";\nimport moduleResolver from \"../module/resolver\";\nimport { LayoutNotFoundError, ParseError } from \"../util/exception\";\nimport { optionService } from \"../services/option\";\nimport {\n AnyStepData,\n ColorDefinition,\n DigitalContentStepData,\n FontData,\n FrameElement,\n FrameStepData,\n ILayout,\n IllustrationElement,\n IllustrationStepData,\n ImageElement,\n LayoutElement,\n LayoutElementType,\n ModuleStepData,\n PictureStepData,\n Region,\n ShapeStepData,\n SilentStepData,\n Step,\n StepSelections,\n StepType,\n TextboxElement,\n TextStepData,\n VariantResource,\n Workflow,\n} from \"../types\";\nimport { CanvasCommand, CreateElementCommand } from \"../command\";\nimport { domParser, fetchAsString, toBase64, xmlSerializer } from \"../util/crossplatform\";\nimport { generate } from \"../util/guid\";\nimport { calculateOffsets, generateFrameSVG, getFrameData, getPatternImageData, getVariant } from \"../util/frame\";\nimport { sanitizeSvgTree, traverse } from \"../util/illustration\";\nimport { applyTextTransformations } from \"../text/shared\";\nimport { determineCorrectFontSizeAndLines } from \"../text/algorithm/autosize\";\nimport { loadFont } from \"../util/font\";\n\n// SVG tags which can take a fill.\nconst fillableTagNames = [\n \"altGlyph\",\n \"circle\",\n \"ellipse\",\n \"path\",\n \"polygon\",\n \"polyline\",\n \"rect\",\n \"text\",\n \"textPath\",\n \"tref\",\n \"tspan\",\n];\n\nconst handleDigitalContentStep = async (\n layouts: ILayout[],\n step: DesignInputStep,\n digitalContentStep: Step<DigitalContentStepData>,\n): Promise<CreateElementCommand<ImageElement>[]> => {\n const designInputStepData = step.data as DigitalContentDesignInputStepData;\n const baseUrl = digitalContentStep.data.baseUrl;\n const videoSource = designInputStepData.assetUrl.replace(\"localhost\", \"localstack\");\n const protocolPrefix = baseUrl.slice(0, 4) === \"http\" ? \"\" : \"https://\";\n const urlBuilder = new URL(protocolPrefix + baseUrl);\n urlBuilder.searchParams.append(\"video\", toBase64(JSON.stringify([{ href: videoSource }])));\n //iOS does not recognise a URL without the trailing slash on the pathname,\n urlBuilder.pathname = urlBuilder.pathname + (urlBuilder.pathname.slice(-1) === \"/\" ? \"\" : \"/\");\n const finalUrl = urlBuilder.toString();\n const base64data = toBase64(await urlToQrString(finalUrl, { type: \"svg\" }));\n const dataUri = `data:image/svg+xml;base64,${base64data}`;\n\n const createElementForRegion = (region: Region): CreateElementCommand<ImageElement> => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n\n // Create a new image.\n const elementKey = generate();\n return new CreateElementCommand<ImageElement>(\n {\n id: elementKey,\n src: dataUri,\n type: LayoutElementType.Image,\n y: region.top,\n x: region.left,\n width: region.width,\n height: region.height,\n rotation: 0,\n },\n layout,\n );\n };\n const regions = digitalContentStep.data.regions;\n try {\n return regions.map(createElementForRegion);\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\nconst handleFrameStep = async (\n layouts: ILayout[],\n stepSelections: StepSelections,\n step: DesignInputStep,\n frameStep: Step<FrameStepData>,\n): Promise<CanvasCommand[]> => {\n const designInputStepData = step.data as FrameDesignInputStepData;\n\n const src = designInputStepData.assetUrl;\n const imageData = await getPatternImageData(src);\n\n try {\n const variant = await getVariant(designInputStepData, frameStep.option);\n if (variant) {\n stepSelections[frameStep.stepName] = { selectedVariants: [variant] };\n }\n\n const createFrameAndPattern = async (region: Region): Promise<CanvasCommand[]> => {\n const frameSvg = await generateFrameSVG(region, variant?.asset?.fileLink);\n const frameData = await getFrameData(frameSvg);\n const newElementId = generate();\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n const offsets = calculateOffsets(\n imageData,\n frameData,\n {\n scale: designInputStepData.scale,\n left: designInputStepData.x,\n top: designInputStepData.y,\n },\n frameStep.data.forceImageCover,\n );\n return [\n new CreateElementCommand<FrameElement>(\n {\n id: newElementId,\n path: frameData.path,\n type: LayoutElementType.Frame,\n forceImageCover: frameStep.data.forceImageCover,\n x: region.left,\n y: region.top,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n rotation: region.rotation,\n scaleX: region.width / frameData.width,\n scaleY: region.height / frameData.height,\n pattern: {\n id: `${newElementId}-pattern`,\n src: imageData.src,\n x: offsets.x,\n y: offsets.y,\n width: imageData.width,\n height: imageData.height,\n rotation: 0,\n scaleX: offsets.zoom,\n scaleY: offsets.zoom,\n svg: imageData.svg,\n colors: imageData.colors,\n },\n },\n layout,\n ),\n ];\n };\n return (await Promise.all(frameStep.data.regions.map((r) => createFrameAndPattern(r)))).flat();\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\nconst handleIllustrationStep = async (\n layouts: ILayout[],\n stepSelections: StepSelections,\n step: DesignInputStep,\n illustrationStep: Step<IllustrationStepData>,\n): Promise<CreateElementCommand<IllustrationElement>[]> => {\n const designInputStepData = step.data as IllustrationDesignInputStepData;\n\n const option = illustrationStep.option;\n if (!option) {\n console.error(`No option for step ${illustrationStep.stepName}.`);\n return [];\n }\n const variant =\n option.variants?.find((variant: VariantResource) => variant.id === designInputStepData.illustrationVariantId) ||\n (await optionService.getDefaultVariant(option, illustrationStep.overrideDefaultVariantId));\n if (!variant) {\n console.error(`No variant with ID: ${designInputStepData.illustrationVariantId}`);\n return [];\n }\n if (!variant.asset) {\n console.error(`No asset for variant with ID: ${designInputStepData.illustrationVariantId}`);\n return [];\n }\n stepSelections[illustrationStep.stepName] = { selectedVariants: [variant] };\n\n const link = variant.asset?.fileLink;\n if (!link) {\n console.error(`No asset link for variant with ID: ${designInputStepData.illustrationVariantId}`);\n return [];\n }\n const illustrationBody = await fetchAsString(link, true);\n\n // Get the raw SVG without a doctype.\n const svgRegex = /<svg.*?<\\/svg>/s;\n const svgMatches = illustrationBody.match(svgRegex) || [];\n const svg = svgMatches?.length > 0 ? svgMatches[0] : \"\";\n\n // Parse the SVG into a tree.\n const parser = domParser();\n const parsedSvg = parser.parseFromString(svg, \"image/svg+xml\");\n const root = parsedSvg.firstElementChild;\n if (!root) {\n console.error(\"Failed to read SVG.\");\n return [];\n }\n sanitizeSvgTree(root);\n\n // Annotate elements which have fills with a new class name.\n const colors: { [key: string]: ColorDefinition } = {};\n traverse(root, (node) => {\n if (fillableTagNames.includes(node.tagName) && !node.attributes.getNamedItem(\"fill\")) {\n node.setAttribute(\"fill\", \"#000000\");\n }\n\n const fill = node.attributes.getNamedItem(\"fill\");\n if (fill && fill.value !== \"none\") {\n const fillName = fill.value;\n const alphanumericFill = fillName.replace(/\\W/g, \"\");\n const className = `spiff-fill-${alphanumericFill}`;\n node.classList.add(className);\n colors[className] = { browserValue: fillName };\n }\n\n const stroke = node.attributes.getNamedItem(\"stroke\");\n if (stroke && stroke.value !== \"none\") {\n const fillName = stroke.value;\n const alphanumericFill = fillName.replace(/\\W/g, \"\");\n const className = `spiff-stroke-${alphanumericFill}`;\n node.classList.add(className);\n colors[className] = { browserValue: fillName };\n }\n });\n\n // Serialise the traversed SVG back into a string.\n const serialiser = xmlSerializer();\n const rebuiltSvg = serialiser.serializeToString(root);\n\n const replacementColors = designInputStepData.colors;\n if (replacementColors) {\n for (const [className, colorDefinition] of Object.entries(colors)) {\n for (const k of Object.keys(replacementColors)) {\n if (colorDefinition.browserValue === k) {\n colors[className] = { browserValue: replacementColors[k] };\n break;\n }\n }\n }\n }\n\n const createElementForRegion = (region: Region): CreateElementCommand<IllustrationElement> => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n const elementKey = generate();\n return new CreateElementCommand<IllustrationElement>(\n {\n colors,\n id: elementKey,\n svg: rebuiltSvg,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n },\n layout,\n );\n };\n const regions = illustrationStep.data.regions;\n try {\n return regions.map(createElementForRegion);\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\nconst handleModuleStep = async (\n layouts: ILayout[],\n step: DesignInputStep,\n moduleStep: Step<ModuleStepData>,\n): Promise<CreateElementCommand<IllustrationElement>[]> => {\n const module = await moduleResolver(moduleStep.data.module);\n const designInputStepData = step.data as ModuleDesignInputStepData;\n const createElementForRegion = (svg: string, region: Region): CreateElementCommand<IllustrationElement> => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n const elementKey = generate();\n return new CreateElementCommand<IllustrationElement>(\n {\n colors: {},\n id: elementKey,\n svg: svg,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n },\n layout,\n );\n };\n const regions = moduleStep.data.regions;\n try {\n return regions.map((region) =>\n createElementForRegion(module.svgPrint(designInputStepData.text, region), region),\n );\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\nconst handlePictureStep = async (\n layouts: ILayout[],\n stepSelections: StepSelections,\n step: DesignInputStep,\n pictureStep: Step<PictureStepData>,\n): Promise<CreateElementCommand<ImageElement>[]> => {\n const designInputStepData = step.data as PictureDesignInputStepData;\n\n const option = pictureStep.option;\n if (!option) {\n console.error(`No option for step ${pictureStep.stepName}.`);\n return [];\n }\n const variant =\n option.variants?.find((variant: VariantResource) => variant.id === designInputStepData.pictureVariantId) ||\n (await optionService.getDefaultVariant(option, pictureStep.overrideDefaultVariantId));\n if (!variant) {\n console.error(`No variant with ID: ${designInputStepData.pictureVariantId}`);\n return [];\n }\n if (!variant.asset) {\n console.error(`No asset for variant with ID: ${designInputStepData.pictureVariantId}`);\n return [];\n }\n stepSelections[pictureStep.stepName] = { selectedVariants: [variant] };\n const link = variant.asset?.fileLink;\n if (!link) {\n console.error(`No asset link for variant with ID: ${designInputStepData.pictureVariantId}`);\n return [];\n }\n\n const createElementForRegion = (region: Region): CreateElementCommand<ImageElement> => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n // Create a new image.\n const elementKey = generate();\n return new CreateElementCommand<ImageElement>(\n {\n id: elementKey,\n src: link,\n type: LayoutElementType.Image,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n preserveAspectRatio: \"none\",\n },\n layout,\n );\n };\n\n const regions = pictureStep.data.regions;\n try {\n return regions.map(createElementForRegion);\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\nconst handleShapeStep = async (\n layouts: ILayout[],\n stepSelections: StepSelections,\n step: DesignInputStep,\n shapeStep: Step<ShapeStepData>,\n): Promise<CreateElementCommand<IllustrationElement>[]> => {\n const designInputStepData = step.data as ShapeDesignInputStepData;\n const option = shapeStep.option;\n if (!option) {\n console.error(`No option for step ${shapeStep.stepName}.`);\n return [];\n }\n const variant =\n option.variants?.find((variant: VariantResource) => variant.id === designInputStepData.colorVariantId) ||\n (await optionService.getDefaultVariant(option, shapeStep.overrideDefaultVariantId));\n if (!variant) {\n console.error(`No variant with ID: ${designInputStepData.colorVariantId}`);\n return [];\n }\n stepSelections[shapeStep.stepName] = { selectedVariants: [variant] };\n\n const createElementForRegion = (region: Region): CreateElementCommand<IllustrationElement> => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n\n const svg = `\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlnsXlink=\"http://www.w3.org/1999/xlink\"\n xmlSpace=\"preserve\"\n preserveAspectRatio=\"none\"\n version=\"1.1\"\n width=\"1\"\n height=\"1\"\n viewBox=\"0 0 1 1\"\n >\n <rect\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n class=\"spiff-fill-shape\"\n fill=\"${variant?.color}\"\n />\n </svg>\n `;\n const fill: ColorDefinition = { browserValue: variant.color || \"#000000\" };\n const colors = { \"spiff-fill-shape\": fill };\n\n const elementKey = generate();\n return new CreateElementCommand<IllustrationElement>(\n {\n colors,\n id: elementKey,\n svg,\n type: LayoutElementType.Illustration,\n y: region.top,\n x: region.left,\n rotation: region.rotation,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n immutable: region.immutable,\n },\n layout,\n );\n };\n const regions = shapeStep.data.regions;\n try {\n return regions.map(createElementForRegion);\n } catch (e) {\n console.error(e);\n return [];\n }\n};\n\nconst handleSilentStep = async (\n layouts: ILayout[],\n silentStep: Step<SilentStepData>,\n productOverlayImageUrl?: string,\n): Promise<CreateElementCommand<LayoutElement>[]> => {\n const commands: CreateElementCommand<LayoutElement>[] = [];\n\n const getSource = (): string => {\n if (silentStep.type === StepType.ProductOverlay) {\n return productOverlayImageUrl || silentStep.data.asset?.fileLink || \"\";\n } else {\n return silentStep.data.asset?.fileLink || \"\";\n }\n };\n const assetSource = getSource();\n\n const evaluateAssetType = (): LayoutElementType => {\n // Try to determine the type by asset path.\n if (assetSource.endsWith(\".jpeg\") || assetSource.endsWith(\".jpg\") || assetSource.endsWith(\".png\")) {\n return LayoutElementType.Image;\n }\n if (assetSource.endsWith(\".svg\")) {\n return LayoutElementType.Illustration;\n }\n return LayoutElementType.Illustration;\n };\n const assetType = evaluateAssetType();\n const regions = silentStep.data.regions;\n\n if (assetType === \"image\") {\n try {\n regions.forEach((region) => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n const newElement = {\n id: generate(),\n src: assetSource,\n type: assetType,\n y: region.top,\n x: region.left,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n productOverlay: silentStep.type === StepType.ProductOverlay ? true : undefined,\n scaleX: 1,\n scaleY: 1,\n rotation: region.rotation,\n excludeFromExport: silentStep.data.excludeFromPrint,\n preserveAspectRatio: \"none\",\n };\n commands.push(new CreateElementCommand<ImageElement>(newElement, layout));\n });\n } catch (e) {\n console.error(e);\n }\n } else {\n const fetchedSrc = await fetchAsString(assetSource, true);\n const sanitizeSvg = (rawSvg: string): string => {\n // Get the raw SVG without a doctype.\n const svgRegex = /<svg.*?<\\/svg>/s;\n const svgMatches = rawSvg.match(svgRegex) || [];\n const svg = svgMatches?.length > 0 ? svgMatches[0] : \"\";\n\n // Parse the SVG into a tree.\n const parser = domParser();\n const parsedSvg = parser.parseFromString(svg, \"image/svg+xml\");\n const root = parsedSvg.firstElementChild;\n if (!root) {\n throw new ParseError(\"Failed to read SVG.\");\n }\n sanitizeSvgTree(root);\n const serialiser = xmlSerializer();\n return serialiser.serializeToString(root);\n };\n regions.forEach((region) => {\n const layout = layouts.find((layout: ILayout) => layout.panelId === region.panelId);\n if (!layout) {\n throw new LayoutNotFoundError(region);\n }\n const newElement = {\n id: generate(),\n src: assetSource,\n asset_key: assetSource,\n svg: sanitizeSvg(fetchedSrc),\n colors: {},\n type: assetType,\n y: region.top,\n x: region.left,\n width: region.width,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n scaleX: 1,\n scaleY: 1,\n rotation: region.rotation,\n productOverlay: silentStep.type === StepType.ProductOverlay ? true : undefined,\n excludeFromExport: silentStep.data.excludeFromPrint,\n };\n commands.push(new CreateElementCommand<IllustrationElement>(newElement, layout));\n });\n }\n return commands;\n};\n\nconst handleTextStep = async (\n layouts: ILayout[],\n stepSelections: StepSelections,\n step: DesignInputStep,\n textStep: Step<TextStepData>,\n): Promise<CreateElementCommand<TextboxElement>[]> => {\n const commands: CreateElementCommand<TextboxElement>[] = [];\n\n const designInputStepData = step.data as TextDesignInputStepData;\n\n const defaultFontSize = 30;\n const textAlign = (stepData: TextStepData) => {\n if (stepData.vertical) {\n return \"center\";\n }\n return stepData.textAlign || \"center\";\n };\n\n const getFontUrl = async (): Promise<string | undefined> => {\n const option = textStep.option;\n if (!option) {\n return undefined;\n }\n const variant =\n option.variants?.find((variant: VariantResource) => variant.id === designInputStepData.fontVariantId) ||\n (await optionService.getDefaultVariant(option, textStep.overrideDefaultVariantId));\n if (!variant) {\n return undefined;\n }\n if (!variant.asset) {\n return undefined;\n }\n stepSelections[textStep.stepName] = { selectedVariants: [variant] };\n const link = variant.asset.fileLink;\n if (!link) {\n return undefined;\n }\n return link;\n };\n\n const getFontData = async () => {\n const fontUrl = await getFontUrl();\n if (!fontUrl) {\n return undefined;\n }\n const font = await loadFont(fontUrl);\n const fontData: FontData = {\n assetUrl: fontUrl,\n name: font.names.fullName[\"en\"],\n };\n return fontData;\n };\n const fontData = await getFontData();\n\n const replacedText =\n (textStep.data.replaceableText\n ? textStep.data.replaceableText.replace(\"{{}}\", designInputStepData.text)\n : designInputStepData.text) || \"\";\n\n const text = applyTextTransformations(replacedText, {\n vertical: textStep.data.vertical,\n uppercase: textStep.data.uppercase,\n });\n\n const getDefaultColor = async (step: TextStepData): Promise<string | undefined> => {\n const colorOption = step.colorOption;\n if (!colorOption) return undefined;\n const defaultVariant = await optionService.getDefaultVariant(colorOption);\n return defaultVariant?.color;\n };\n const defaultColor = designInputStepData.color || (await getDefaultColor(textStep.data));\n\n const regions = textStep.data.regions;\n for (const region of regions) {\n const layout = layouts.find((layout) => layout.panelId === region.panelId);\n if (!layout) {\n continue;\n }\n const newBaseElement: TextboxElement = {\n stepName: step.name,\n id: generate(),\n align: textAlign(textStep.data),\n curved: textStep.data.curved,\n fill: designInputStepData.color || defaultColor || \"#000000\",\n fontData,\n fontSize: textStep.data.size || defaultFontSize,\n height: region.height,\n layer: region.layer,\n layerIndex: region.layerIndex,\n paths: textStep.data.paths,\n rotation: region.rotation,\n text,\n type: LayoutElementType.Textbox,\n vertical: textStep.data.vertical,\n verticalAlign: textStep.data.verticalAlign || \"middle\",\n width: region.width,\n x: region.left,\n y: region.top,\n };\n if (fontData) {\n const [correctFontSize, correctLines] = determineCorrectFontSizeAndLines(\n textStep.data.size || defaultFontSize,\n fontData,\n region,\n [\n applyTextTransformations(text, {\n vertical: textStep.data.vertical,\n uppercase: textStep.data.uppercase,\n }),\n ],\n {\n size: textStep.data.size,\n minSize: textStep.data.minSize,\n maxSize: textStep.data.maxSize,\n },\n );\n commands.push(\n new CreateElementCommand(\n {\n ...newBaseElement,\n fontSize: correctFontSize,\n text: newBaseElement.curved ? newBaseElement.text : (correctLines || []).join(\"\\n\"),\n },\n layout,\n ),\n );\n } else {\n commands.push(new CreateElementCommand(newBaseElement, layout));\n }\n }\n return commands;\n};\n\n// Whether all of a step's conditions have been met.\nconst stepConditionsAreSatisfied = (step: Step<AnyStepData>, stepSelections: StepSelections): boolean => {\n if (!step.conditions) {\n return true;\n }\n return step.conditions.every((condition) => {\n const originatingStepData = stepSelections[condition.targetStepName];\n if (originatingStepData && originatingStepData.selectedVariants) {\n const selectedVariants = originatingStepData.selectedVariants;\n return condition.requiredVariantSelections.some(\n (reqVariant) => selectedVariants.find((selVariant) => selVariant.id === reqVariant) !== undefined,\n );\n }\n return false;\n });\n};\n\n// Generate a set of commands corresponding to one workflow.\nconst generateCommands = async (\n designInputSteps: DesignInputStep[],\n workflow: Workflow,\n layouts: ILayout[],\n productOverlayImageUrl?: string,\n): Promise<CanvasCommand[]> => {\n const commands: CanvasCommand[] = [];\n const stepSelections = {};\n\n // Apply steps.\n for (const step of designInputSteps) {\n const workflowStep = workflow.steps.find((s) => s.stepName === step.name);\n if (!workflowStep) {\n continue;\n }\n switch (workflowStep.type) {\n case StepType.DigitalContent:\n commands.push(\n ...(await handleDigitalContentStep(layouts, step, workflowStep as Step<DigitalContentStepData>)),\n );\n break;\n case StepType.Frame:\n case StepType.Photo:\n commands.push(\n ...(await handleFrameStep(layouts, stepSelections, step, workflowStep as Step<FrameStepData>)),\n );\n break;\n case StepType.Illustration:\n commands.push(\n ...(await handleIllustrationStep(\n layouts,\n stepSelections,\n step,\n workflowStep as Step<IllustrationStepData>,\n )),\n );\n break;\n case StepType.Module:\n commands.push(...(await handleModuleStep(layouts, step, workflowStep as Step<ModuleStepData>)));\n break;\n case StepType.Picture:\n commands.push(\n ...(await handlePictureStep(layouts, stepSelections, step, workflowStep as Step<PictureStepData>)),\n );\n break;\n case StepType.Shape:\n commands.push(\n ...(await handleShapeStep(layouts, stepSelections, step, workflowStep as Step<ShapeStepData>)),\n );\n break;\n case StepType.Text:\n commands.push(\n ...(await handleTextStep(layouts, stepSelections, step, workflowStep as Step<TextStepData>)),\n );\n break;\n }\n }\n\n // Handle silent steps.\n for (const workflowStep of workflow.steps) {\n if (workflowStep.type !== StepType.SilentIllustration && workflowStep.type !== StepType.ProductOverlay) {\n continue;\n }\n if (!stepConditionsAreSatisfied(workflowStep, stepSelections)) {\n continue;\n }\n commands.push(\n ...(await handleSilentStep(layouts, workflowStep as Step<SilentStepData>, productOverlayImageUrl)),\n );\n }\n\n return commands;\n};\n\nexport { generateCommands };\n","import cloneDeep from \"lodash.clonedeep\";\nimport { PromiseQueue, QueueablePromise } from \"../../util/PromiseQueue\";\nimport { Pith } from \"pith\";\nimport { generateCommands } from \"../../generation\";\nimport { DesignInputStep } from \"../../generation/types\";\nimport type { RenderableContext, RenderableContextService } from \"@spiffcommerce/preview\";\nimport { ILayout, LayoutRenderingPurpose, LayoutsState, StepType, Workflow } from \"../../types\";\nimport { createCanvas, getDomParser, loadImage } from \"../../customCanvas\";\nimport { getSvgElement, LayoutData } from \"../../CommandContext\";\nimport { renderPapyrusComponentAsString } from \"../../util/crossplatform\";\nimport { CreateLayoutCommand, GroupCommand } from \"../../command\";\nimport { WorkflowManager } from \"../..\";\n\nexport class LayoutPreviewService implements RenderableContextService {\n private readonly layouts: ReadonlyMap<string, LayoutPreviewBridge>;\n private workflowManager?: WorkflowManager;\n private handleCompleteRender: null | ((layouts: LayoutPreviewBridge[]) => void);\n\n constructor(layouts: ILayout[]) {\n this.handleCompleteRender = null;\n const map: Map<string, LayoutPreviewBridge> = new Map();\n layouts.forEach((layout) =>\n map.set(\n layout.id,\n new LayoutPreviewBridge(\n layout.id,\n layout.name,\n this,\n { width: layout.width, height: layout.height },\n this.getWorkflowManager.bind(this),\n ),\n ),\n );\n this.layouts = map as ReadonlyMap<string, LayoutPreviewBridge>;\n }\n\n setCompleteRenderCallback(handleCompleteRender: (layouts: LayoutPreviewBridge[]) => void) {\n this.handleCompleteRender = handleCompleteRender;\n handleCompleteRender(Array.from(this.layouts.values()));\n }\n\n onCompleteRender() {\n this.handleCompleteRender && this.handleCompleteRender(Array.from(this.layouts.values()));\n }\n\n getAll(): ReadonlyMap<string, LayoutPreviewBridge> {\n return this.layouts;\n }\n\n setWorkflowManager(workflowManager: WorkflowManager) {\n this.workflowManager = workflowManager;\n }\n\n getWorkflowManager() {\n return this.workflowManager;\n }\n}\n\n/**\n * Determines wether power of two textures are supported based on\n * the availability of WebGL 2 on the target platform.\n *\n * Check WebGL2 support. Older Safari does not support WebGL2 and behaves badly when non POT textures are used.\n * If we fail to resolve a WebGL2 context we disable non power of two rendering.\n *\n * NOTE: DO NOT remove this without first testing behaviour against Safari on macOS Big Sur & mobile!!!\n */\nconst calculateNonPOTSupport = (): Promise<boolean> => {\n return new Promise((resolve, _reject) => {\n try {\n const glEl = createCanvas();\n const gl = glEl.getContext(\"webgl2\");\n resolve(!!gl);\n } catch (e) {\n resolve(false);\n }\n });\n};\nexport const nonPotTexSupport: Promise<boolean> = calculateNonPOTSupport();\n\n/**\n * The panel canvas class that stores both the main rendering canvas as well as rendering context\n * for a rendering context\n */\nexport class LayoutPreviewBridge implements RenderableContext {\n hasSetStaticContext: boolean = false;\n\n private readonly id: string;\n private readonly name: string;\n private readonly panelSize: { width: number; height: number };\n private readonly getWorkflowManager?: () => WorkflowManager | undefined;\n\n private service: LayoutPreviewService;\n\n private interactiveDirty: boolean = false;\n\n // Texture context & associated dirty flag.\n private textureCtx?: CanvasRenderingContext2D;\n private staticCtxDirty: boolean = false;\n private lastRequestedRenderArguments: LayoutData[] | undefined = undefined;\n\n // Stores a timestamp for the last static render.\n private lastCompletedStaticRender: number | undefined = undefined;\n\n // A render queue for this layout.\n // No more than 2 renders can be queued at any time.\n // Beyond this, renders will be discarded before they can execute\n private renderQueue: PromiseQueue<RenderQueuePromise> = new PromiseQueue(2);\n\n constructor(\n id: string,\n name: string,\n service: LayoutPreviewService,\n panelSize: { width: number; height: number },\n getWorkflowManager?: () => WorkflowManager | undefined,\n ) {\n this.id = id;\n this.name = name;\n this.service = service;\n this.panelSize = panelSize;\n this.getWorkflowManager = getWorkflowManager;\n }\n\n getID(): string {\n return this.id;\n }\n\n getName(): string {\n return this.name;\n }\n\n getPanelSize(): { width: number; height: number } {\n return this.panelSize;\n }\n\n getStaticContext(): CanvasRenderingContext2D | undefined {\n return this.textureCtx;\n }\n\n /**\n * Register canvas to be rendered to.\n */\n setStaticContext(ctx: CanvasRenderingContext2D) {\n this.textureCtx = ctx;\n if (this.lastRequestedRenderArguments) {\n this.render(this.lastRequestedRenderArguments);\n }\n }\n\n getStaticContextDirty(): boolean {\n return this.staticCtxDirty;\n }\n\n setStaticContextDirty(dirty: boolean): void {\n this.staticCtxDirty = dirty;\n }\n\n getInteractiveCanvasDirty() {\n return this.interactiveDirty;\n }\n\n setInteractiveCanvasDirty(dirty: boolean) {\n this.interactiveDirty = dirty;\n }\n\n markLastCompletedStaticRender() {\n this.lastCompletedStaticRender = Date.now();\n this.service.onCompleteRender();\n }\n\n /**\n * Returns a timestamp for the last time that this canvas rendered to its dynamic texture in the\n * form of Date.now(). If this panel has never rendered undefined will be returned.\n */\n getLastCompletedStaticRender() {\n return this.lastCompletedStaticRender;\n }\n\n /**\n * Actions to perform when a static render event is fired for this canvas.\n */\n async render(layouts: LayoutData[]) {\n const clonedLayouts = cloneDeep(layouts);\n\n // We store the parameters for this render so that we can re-render\n // if the static context is set later.\n this.lastRequestedRenderArguments = clonedLayouts;\n\n // Pull the static context and handle the case where it isn't available yet.\n const staticContext = this.getStaticContext();\n if (!staticContext) {\n this.markLastCompletedStaticRender();\n this.setStaticContextDirty(false);\n return;\n }\n\n // Queue the render.\n this.renderQueue.enqueue(\n new RenderQueuePromise(\n this.getID(),\n staticContext,\n await nonPotTexSupport,\n () => {\n this.markLastCompletedStaticRender();\n this.setStaticContextDirty(true);\n },\n clonedLayouts,\n this.getWorkflowManager,\n ),\n );\n }\n}\n\n/**\n * Encapsulates the behavior required to render a layout to a canvas. The promise can\n * be generated at any point in time allowing for queue systems to process the render\n * once at a time and enforce ordering rules.\n */\nclass RenderQueuePromise extends QueueablePromise {\n private readonly layoutId: string;\n private readonly ctx: CanvasRenderingContext2D;\n private readonly nonPOTSupport: boolean;\n private readonly onRender: () => void;\n private readonly layouts: LayoutData[]; // TODO: Do we need to pass this whole array in?\n private readonly getWorkflowManager?: () => WorkflowManager | undefined;\n\n constructor(\n layoutId: string,\n ctx: CanvasRenderingContext2D,\n nonPOTSupport: boolean,\n onRender: () => void,\n layouts: LayoutData[],\n getWorkflowManager?: () => WorkflowManager | undefined,\n ) {\n super();\n this.layoutId = layoutId;\n this.ctx = ctx;\n this.nonPOTSupport = nonPOTSupport;\n this.onRender = onRender;\n this.layouts = layouts;\n this.getWorkflowManager = getWorkflowManager;\n }\n\n /**\n * Returns the resolution expected for generated textures.\n * FIXME: This is reimplemented from the preview package. Can we find a way to remove this duplication.\n */\n private getDynamicTextureResolution() {\n return this.getIsMobile() || !this.offscreenRenderingSupported()\n ? {\n width: 1024,\n height: 1024,\n }\n : {\n width: 2048,\n height: 2048,\n };\n }\n\n private getIsMobile() {\n return window.innerWidth <= 480;\n }\n\n /**\n * Returns true when multithreaded rendering is supported.\n */\n private offscreenRenderingSupported(): boolean {\n // Samsung browser has broken web worker custom fonts from v14. To be\n // safe, if we detect this browser we immediately disable offscreen canvas. There\n // may be a more specific feature we can detect to be more clean about this moving forwards.\n if (navigator.userAgent.includes(\"SamsungBrowser\")) {\n return false;\n }\n // Otherwise we check for relevant required functionality\n return !!window.Worker && !!(window as any).OffscreenCanvas;\n }\n\n private resizeFit(\n originalSize: { width: number; height: number },\n maxSize = 4096,\n ): { width: number; height: number } {\n const widthRatio = maxSize / originalSize.width;\n const heightRatio = maxSize / originalSize.height;\n const minAspectRatio = Math.min(widthRatio, heightRatio);\n if (minAspectRatio > 1) {\n return originalSize;\n }\n\n return { width: originalSize.width * minAspectRatio, height: originalSize.height * minAspectRatio };\n }\n\n /**\n * Render the internally stored layout to the canvas.\n * NOTE: This function is performance critical code. Please throughly test any changes to\n * ensure performance isn't lost and that rendering behavior is preserved when modifying this logic.\n * The aim is to have this code rendering in less than 16.66ms (60fps) on modern hardware. This is\n * a loose target but should be kept in mind when making changes.\n */\n public async execute() {\n // Ensure layout is available. Cancel out of render otherwise.\n const layout = this.layouts.find((layout) => layout.layoutState.layout.id === this.layoutId);\n if (!layout) {\n return;\n }\n const elements = layout.layoutState.elements || [];\n\n const layoutWidth = layout.layoutState.layout.width;\n const layoutHeight = layout.layoutState.layout.height;\n\n const renderDims =\n layoutWidth === 1 || layoutHeight === 1 ? { width: 1, height: 1 } : this.getDynamicTextureResolution();\n\n // We need to ensure that we compute the correct width and height for the final texture\n // based on whether or not we know the platform we're running on support non power of two\n const targetWidth = renderDims.width;\n const targetHeight = renderDims.height;\n let width: number;\n let height: number;\n\n if (this.nonPOTSupport) {\n const targetRatio = targetWidth / targetHeight;\n const ratio = layoutWidth / layoutHeight;\n if (ratio < targetRatio) {\n width = targetWidth;\n height = layoutHeight * (targetWidth / layoutWidth);\n } else {\n width = layoutWidth * (targetHeight / layoutHeight);\n height = targetHeight;\n }\n\n const boundedSize = this.resizeFit({ width, height });\n width = boundedSize.width;\n height = boundedSize.height;\n } else {\n width = renderDims.width;\n height = renderDims.height;\n }\n\n // Do the render with the SVG we have now generated\n const templatingContext = this.getWorkflowManager?.()?.getTemplatingContext();\n const svgElement = getSvgElement(layout.layoutState.layout, elements, {\n renderingConfiguration: {\n purpose: LayoutRenderingPurpose.ThreeD,\n templatingContext,\n },\n });\n const svgStr = renderPapyrusComponentAsString(svgElement);\n const cvg = await Pith.from(this.ctx, svgStr, {\n anonymousCrossOrigin: true,\n ignoreDimensions: !this.nonPOTSupport,\n ignoreAnimation: true,\n ignoreClear: true,\n ignoreMouse: true,\n enableRedraw: false,\n createCanvas: createCanvas as any,\n createImage: loadImage as any,\n DOMParser: getDomParser(),\n fetch: fetch,\n });\n cvg.resize(width, height);\n await cvg.render();\n // Callback to notify the render has completed.\n this.onRender();\n }\n}\n\ninterface StepAspectValue {\n stepName: string;\n stepAspectType: string;\n value?: string;\n}\nexport const stepAspectValuesToDesignInputSteps = (\n stepAspectValues: StepAspectValue[],\n workflow: Workflow,\n): DesignInputStep[] => {\n const designInputSteps: DesignInputStep[] = [];\n stepAspectValues.forEach((stepAspectValue) => {\n const step = workflow.steps.find((step) => step.stepName === stepAspectValue.stepName);\n if (step?.type === StepType.Text && stepAspectValue.stepAspectType === \"Text\") {\n designInputSteps.push({\n name: step.stepName,\n data: {\n text: stepAspectValue.value,\n },\n });\n }\n });\n return designInputSteps;\n};\n\nexport const generateStateFromDesignInputSteps = async (\n designInputSteps: DesignInputStep[],\n workflow: Workflow,\n layouts: ILayout[],\n productOverlayImageUrl?: string,\n): Promise<LayoutsState> => {\n let state: LayoutsState = {\n serializableWorkflow: { steps: [] },\n layouts: {},\n };\n // Build base layouts.\n const layoutGroup = new GroupCommand(layouts.map((layout) => new CreateLayoutCommand(layout)));\n state = layoutGroup.apply(state);\n // Build base commands\n const commands = await generateCommands(designInputSteps, workflow, layouts, productOverlayImageUrl);\n const commandGroup = new GroupCommand(commands);\n return commandGroup.apply(state);\n};\n","import { gql } from \"@apollo/client/core\";\nimport { GlobalPropertyState } from \"../types\";\nimport { graphQlManager } from \"../services/server\";\n\nexport const globalPropertyStateAspectFragment = gql`\n fragment GlobalPropertyStateAspectFields on GlobalPropertyStateAspect {\n name\n value\n type\n channel\n storage {\n ... on GlobalPropertyStateColorOptionStorage {\n customColor\n }\n ... on GlobalPropertyStateFileUploadStorage {\n originalAssetKey\n backgroundRemovedAssetKey\n useOriginalAsset\n colors {\n key\n browserValue\n pmsValue\n }\n }\n }\n }\n`;\n\nexport const createGlobalPropertyStateMutation = gql`\n ${globalPropertyStateAspectFragment}\n mutation CreateGlobalPropertyState($bundleId: String!) {\n globalPropertyStateCreate(bundleId: $bundleId) {\n id\n aspects {\n ...GlobalPropertyStateAspectFields\n }\n }\n }\n`;\n\nexport const updateGlobalPropertyStateMutation = gql`\n ${globalPropertyStateAspectFragment}\n mutation UpdateGlobalPropertyState($id: String!, $aspects: [GlobalPropertyStateAspectInput]!) {\n globalPropertyStateUpdate(id: $id, aspects: $aspects) {\n id\n aspects {\n ...GlobalPropertyStateAspectFields\n }\n }\n }\n`;\n\nexport const getGlobalPropertyStateQuery = gql`\n ${globalPropertyStateAspectFragment}\n query GetGlobalPropertyState($bundleId: String!) {\n globalPropertyState(bundleId: $bundleId) {\n id\n aspects {\n ...GlobalPropertyStateAspectFields\n }\n }\n }\n`;\n\n/**\n * Gets the raw Global Property State for a bundle.\n */\nexport const getGlobalPropertyStateForBundle = async (bundleId: string): Promise<GlobalPropertyState | undefined> => {\n const resp = await graphQlManager.getShadowGraphqlClient().query<{ globalPropertyState: GlobalPropertyState }>({\n query: getGlobalPropertyStateQuery,\n fetchPolicy: \"cache-first\",\n errorPolicy: \"all\",\n variables: {\n bundleId,\n },\n });\n return resp.data.globalPropertyState;\n};\n","import { gql } from \"@apollo/client/core\";\nimport { additionalProductFragment } from \"../query\";\nimport { globalPropertyStateAspectFragment } from \"../GlobalPropertyStateManager/query\";\n\nconst productFields = (filterWorkflows: boolean) => gql`\n ${additionalProductFragment}\n fragment ProductFields on Product {\n id\n basePrice\n enabled\n imageUrl\n minimumOrderQuantity\n integrationProducts {\n id\n externalProductId\n externalVariantId\n additionalExternalProductId\n additionalExternalVariantId\n additionalIntegrationProduct {\n ...AdditionalIntegrationProductFields\n }\n integration {\n id\n enabled\n externalIntegrationId\n type\n isCurrent\n }\n }\n modelUrl\n name\n description\n overlayImageUrl\n preloadImageUrl\n sku\n skuCode\n workflows${filterWorkflows ? \"(filters: $productWorkflowFilters)\" : \"\"} {\n id\n index\n friendlyName\n isPresent\n workflowName\n imageUrl\n }\n productTags {\n id\n name\n }\n }\n`;\n\nconst productCollectionProductFieldsFragment = (filterWorkflows: boolean) => gql`\n ${productFields(filterWorkflows)}\n fragment ProductCollectionProductFields on ProductCollectionProduct {\n id\n productId\n workflowId\n product {\n ...ProductFields\n }\n }\n`;\n\nexport const productCollectionFieldsFragment = (eagerFetchProducts: boolean, filterWorkflows: boolean = false) => gql`\n ${eagerFetchProducts ? productCollectionProductFieldsFragment(filterWorkflows) : \"\"}\n fragment ProductCollectionFields on ProductCollection {\n id\n name\n description\n dispatchStartDate\n dispatchEndDate\n productCollectionCustomers {\n id\n customer {\n id\n }\n }\n image {\n key\n name\n fileLink\n }\n globalPropertyConfiguration {\n id\n aspects {\n name\n type\n title\n description\n entityId\n mandatory\n conditions {\n targetAspectName\n action\n requiredVariantSelections\n }\n conditionMode\n data {\n fileUpload {\n colorPickerEnabled\n pmsPickerEnabled\n colorOptionId\n }\n text {\n templatingEnabled\n }\n }\n }\n }\n ${eagerFetchProducts ? \"productCollectionProducts { ...ProductCollectionProductFields }\" : \"\"}\n }\n`;\n\n// For small things that you would expect to always have\nexport const bundleBaseFieldsFragment = gql`\n fragment BundleBaseFields on Bundle {\n id\n dispatchDate\n purchaseOrder\n createdAt\n updatedAt\n name\n completed\n template\n templateStatus\n transactionsCount\n productsCount\n totalPriceSubunits\n quoteId\n orderId\n externalOrderId\n internalOrderId\n workflowViewerLink\n workflowViewerAmendLink\n }\n`;\n\nexport const getBundleQuery = (eagerFetchProducts: boolean) => gql`\n ${globalPropertyStateAspectFragment}\n ${productCollectionFieldsFragment(eagerFetchProducts)}\n ${bundleBaseFieldsFragment}\n query GetBundle($id: String!) {\n globalPropertyState(bundleId: $id) {\n id\n aspects {\n ...GlobalPropertyStateAspectFields\n }\n }\n bundles(ids: [$id]) {\n ...BundleBaseFields\n bundleStateData\n metadata {\n key\n value\n }\n partner {\n id\n }\n productCollection {\n ...ProductCollectionFields\n }\n transactionIds\n bundleShareActions {\n id\n title\n type\n stakeholderType\n precedence\n url\n }\n }\n }\n`;\n\nexport const getBundleStakeholdersQuery = gql`\n query GetBundleStakeholders($id: String!) {\n bundles(ids: [$id]) {\n id\n dispatchDate\n purchaseOrder\n completed\n workflowViewerLink\n workflowViewerAmendLink\n currentBundleStakeholder {\n id\n authorizationStatus\n authorizationDate\n authorizationNote\n customer {\n id\n emailAddress\n firstName\n lastName\n phoneNumber\n partner {\n id\n }\n }\n type\n }\n bundleStakeholders {\n id\n authorizationStatus\n authorizationDate\n authorizationNote\n customer {\n id\n emailAddress\n firstName\n lastName\n phoneNumber\n partner {\n id\n }\n }\n type\n }\n }\n }\n`;\n\nexport const getBundlesAndStakeholdersForCustomerQuery = gql`\n query GetBundlesForCustomer($id: String!) {\n customers(ids: [$id]) {\n bundleStakeholders {\n id\n authorizationStatus\n authorizationDate\n authorizationNote\n type\n bundle {\n id\n dispatchDate\n purchaseOrder\n completed\n workflowViewerLink\n workflowViewerAmendLink\n name\n createdAt\n metadata {\n key\n value\n }\n partner {\n id\n }\n }\n }\n }\n }\n`;\n\nexport const getProductCollectionProductsQuery = gql`\n ${productCollectionProductFieldsFragment(false)}\n query GetProductCollectionProducts($id: String!, $productIds: [String!]) {\n productCollections(ids: [$id], productIds: $productIds) {\n id\n productCollectionProducts {\n ...ProductCollectionProductFields\n }\n }\n }\n`;\n\nexport const getProductCollectionProductsFilteredQuery = gql`\n query GetProductCollectionForFilteredProducts(\n $id: String!\n $filters: ProductCollectionProductFilterInput\n $tags: ProductCollectionProductTagFilterInput\n $sortKey: ProductCollectionProductSortKey\n $sortDescending: Boolean\n ) {\n productCollections(ids: [$id]) {\n id\n productCollectionProducts(\n filters: $filters\n tags: $tags\n sortKey: $sortKey\n sortDescending: $sortDescending\n ) {\n id\n product {\n id\n }\n }\n }\n }\n`;\n\nexport const getProductCollectionProductsFeedQuery = gql`\n ${productCollectionProductFieldsFragment(true)}\n query GetProductCollectionForProductsFeed(\n $id: String!\n $limit: Int\n $offset: Int\n $productFilters: ProductCollectionProductFilterInput\n $productWorkflowFilters: MetafieldFilterListInput\n $tags: ProductCollectionProductTagFilterInput\n $sortKey: ProductCollectionProductSortKey\n $sortDescending: Boolean\n $quickSearch: String\n ) {\n productCollections(ids: [$id]) {\n id\n productCollectionProductsFeed(\n filters: $productFilters\n workflowFilters: $productWorkflowFilters\n tags: $tags\n limit: $limit\n offset: $offset\n sortKey: $sortKey\n sortDescending: $sortDescending\n quickSearch: $quickSearch\n ) {\n items {\n ...ProductCollectionProductFields\n }\n total\n }\n }\n }\n`;\n\nexport const createBundleMutation = (eagerFetchProducts: boolean) => gql`\n ${productCollectionFieldsFragment(eagerFetchProducts)}\n mutation CreateBundle(\n $collectionId: String\n $initialMetadata: [MetadataInput!]\n $marketplaceThemeInstallId: String\n $marketplaceThemeInstallConfigurationId: String\n ) {\n bundleCreate(\n collectionId: $collectionId\n metadata: $initialMetadata\n marketplaceThemeInstallId: $marketplaceThemeInstallId\n marketplaceThemeInstallConfigurationId: $marketplaceThemeInstallConfigurationId\n ) {\n id\n bundleOwnerId\n metadata {\n key\n value\n }\n name\n partner {\n id\n }\n productCollection {\n ...ProductCollectionFields\n }\n }\n }\n`;\n\nexport const duplicateBundleMutation = () => gql`\n mutation DuplicateBundle(\n $id: String!\n $template: Boolean\n $marketplaceThemeInstallId: String\n $marketplaceThemeInstallConfigurationId: String\n $duplicateTransactions: Boolean\n ) {\n bundleDuplicate(\n id: $id\n template: $template\n marketplaceThemeInstallId: $marketplaceThemeInstallId\n marketplaceThemeInstallConfigurationId: $marketplaceThemeInstallConfigurationId\n duplicateTransactions: $duplicateTransactions\n ) {\n id\n bundleOwnerId\n partner {\n id\n }\n }\n }\n`;\n\nexport const updateBundleMutation = gql`\n mutation UpdateBundle(\n $id: String!\n $name: String\n $metadata: [MetadataInput!]\n $bundleStateData: String\n $dispatchDate: String\n $purchaseOrder: String\n ) {\n bundleUpdate(\n id: $id\n name: $name\n metadata: $metadata\n bundleStateData: $bundleStateData\n dispatchDate: $dispatchDate\n purchaseOrder: $purchaseOrder\n ) {\n id\n }\n }\n`;\n\nexport const bundleAddTransactionMutation = gql`\n mutation BundleAddTransaction($id: String!, $transactionId: String!) {\n bundleAddTransaction(id: $id, transactionId: $transactionId) {\n id\n }\n }\n`;\n\nexport const bundleAddTransactionsMutation = gql`\n mutation BundleAddTransactions($id: String!, $transactionIds: [String!]!, $transactionOwnerIds: [String!]) {\n bundleAddTransactions(id: $id, transactionIds: $transactionIds, transactionOwnerIds: $transactionOwnerIds) {\n id\n }\n }\n`;\n\nexport const bundleRemoveTransactionMutation = gql`\n mutation BundleRemoveTransaction(\n $id: String!\n $transactionId: String!\n $name: String\n $metadata: [MetadataInput!]\n $bundleStateData: String\n ) {\n bundleRemoveTransaction(id: $id, transactionId: $transactionId) {\n id\n }\n bundleUpdate(id: $id, name: $name, metadata: $metadata, bundleStateData: $bundleStateData) {\n id\n }\n }\n`;\n\nexport const bundleRemoveTransactionsMutation = gql`\n mutation BundleRemoveTransactions(\n $id: String!\n $transactionIds: [String!]!\n $name: String\n $metadata: [MetadataInput!]\n $bundleStateData: String\n ) {\n bundleRemoveTransactions(id: $id, transactionIds: $transactionIds) {\n id\n }\n bundleUpdate(id: $id, name: $name, metadata: $metadata, bundleStateData: $bundleStateData) {\n id\n }\n }\n`;\n\nexport const bundleAddStakeholderMutation = gql`\n mutation BundleAddStakeholder($id: String!, $details: CustomerDetailsInput!, $type: String!) {\n bundleAddStakeholder(id: $id, details: $details, type: $type) {\n id\n bundleStakeholders {\n id\n customer {\n id\n emailAddress\n firstName\n lastName\n phoneNumber\n partner {\n id\n }\n }\n type\n }\n }\n }\n`;\n\nexport const bundleRemoveStakeholderMutation = gql`\n mutation BundleAddStakeholder($id: String!, $emailAddress: String!) {\n bundleRemoveStakeholder(id: $id, emailAddress: $emailAddress) {\n id\n }\n }\n`;\n\nexport const bundleUpdateStakeholdersMutation = gql`\n mutation BundleUpdateStakeholders($id: String!, $input: [BundleStakeholderInput!]!) {\n bundleUpdateStakeholders(id: $id, input: $input) {\n id\n bundleStakeholders {\n id\n customer {\n id\n emailAddress\n firstName\n lastName\n phoneNumber\n partner {\n id\n }\n }\n type\n }\n }\n }\n`;\n\nexport const bundleUpdateTransactionOrderMutation = gql`\n mutation BundleUpdateTransactionOrder($id: String!, $transactionIds: [String!]!) {\n bundleUpdateTransactionOrder(id: $id, transactionIds: $transactionIds) {\n id\n }\n }\n`;\n\nexport const bundleAssignProductCollectionMutation = (eagerFetchProducts: boolean) => gql`\n ${productCollectionFieldsFragment(eagerFetchProducts)}\n mutation BundleAssignProductCollection($id: String!, $productCollectionId: String!) {\n bundleAssignProductCollection(id: $id, collectionId: $productCollectionId) {\n id\n productCollection {\n ...ProductCollectionFields\n }\n }\n }\n`;\n\nexport const bundleAssignGlobalPropertyConfiguration = gql`\n mutation AssignGlobalPropertyConfiguration($bundleId: String!, $globalPropertyConfigurationId: String!) {\n bundleUpdate(id: $bundleId, globalPropertyConfigurationId: $globalPropertyConfigurationId) {\n id\n }\n }\n`;\n\nexport const customerBundlesFeedQuery = (includeMetadata: boolean) => gql`\n ${bundleBaseFieldsFragment}\n query CustomerBundlesFeed($id: String!, $limit: Int!, $offset: Int!, $template: Boolean, $templateStatus: BundleTemplateStatus, $ordered: Boolean) {\n customerBundlesFeed(id: $id, limit: $limit, offset: $offset, template: $template, templateStatus: $templateStatus, ordered: $ordered) {\n items {\n ...BundleBaseFields\n productCollection {\n id\n name\n description\n dispatchStartDate\n dispatchEndDate\n image {\n key\n name\n fileLink\n }\n globalPropertyConfiguration {\n id\n }\n }\n ${includeMetadata ? \"metadata { key, value }\" : \"\"}\n }\n total\n }\n }\n`;\n\nexport const finalizeUpdateBundleMutation = gql`\n mutation FinalizeUpdateBundle($bundleId: String!) {\n bundleFinalizeUpdate(bundleId: $bundleId)\n }\n`;\n\nexport const bundleApprovalQuery = gql`\n mutation ApproveBundle($id: String!, $note: String, $stakeholderId: String) {\n bundleApprove(id: $id, note: $note, stakeholderId: $stakeholderId)\n }\n`;\n\nexport const bundleRejectionQuery = gql`\n mutation RejectBundle($id: String!, $note: String, $stakeholderId: String) {\n bundleReject(id: $id, note: $note, stakeholderId: $stakeholderId)\n }\n`;\n\nexport const transactionApprovalQuery = gql`\n mutation ApproveTransaction($id: String!, $note: String) {\n transactionApprove(id: $id, note: $note)\n }\n`;\n\nexport const transactionRejectionQuery = gql`\n mutation RejectTransaction($id: String!, $note: String) {\n transactionReject(id: $id, note: $note)\n }\n`;\n\nexport const createRecipientQuery = gql`\n mutation CreateRecipient(\n $firstName: String\n $lastName: String\n $address: String\n $suburb: String\n $state: String\n $email: String\n $postalCode: String\n $country: String\n $mobile: String\n $company: String\n $apartment: String\n $customField1: String\n $customField2: String\n $customField3: String\n $customField4: String\n $customField5: String\n $conversionConfigurationId: String\n ) {\n recipientCreate(\n firstName: $firstName\n lastName: $lastName\n address: $address\n suburb: $suburb\n state: $state\n email: $email\n postalCode: $postalCode\n country: $country\n mobile: $mobile\n company: $company\n apartment: $apartment\n customField1: $customField1\n customField2: $customField2\n customField3: $customField3\n customField4: $customField4\n customField5: $customField5\n conversionConfigurationId: $conversionConfigurationId\n ) {\n id\n }\n }\n`;\n\nexport const updateRecipientQuery = gql`\n mutation UpdateRecipient(\n $id: String!\n $firstName: String\n $lastName: String\n $address: String\n $suburb: String\n $state: String\n $email: String\n $postalCode: String\n $country: String\n $mobile: String\n $company: String\n $apartment: String\n $customField1: String\n $customField2: String\n $customField3: String\n $customField4: String\n $customField5: String\n $conversionConfigurationId: String\n $prevalidated: Boolean\n ) {\n recipientUpdate(\n id: $id\n firstName: $firstName\n lastName: $lastName\n address: $address\n suburb: $suburb\n state: $state\n email: $email\n postalCode: $postalCode\n country: $country\n mobile: $mobile\n company: $company\n apartment: $apartment\n customField1: $customField1\n customField2: $customField2\n customField3: $customField3\n customField4: $customField4\n customField5: $customField5\n conversionConfigurationId: $conversionConfigurationId\n prevalidated: $prevalidated\n ) {\n id\n }\n }\n`;\n\nexport const transactionAttachRecipientQuery = gql`\n mutation AtttachRecipient($id: String!, $recipientId: String!) {\n transactionAttachRecipient(id: $id, recipientId: $recipientId) {\n id\n }\n }\n`;\n\nexport const deleteBundleQuery = gql`\n mutation DeleteBundle($id: String!) {\n bundleDelete(id: $id)\n }\n`;\n\nexport const findBundleForTransactionsQuery = gql`\n query FindBundleForTransactions($ids: [String!]!) {\n transactions(ids: $ids) {\n id\n bundle {\n id\n }\n }\n }\n`;\n","import { FrameElement, IllustrationElement, LayoutsState } from \"../types\";\n\n/**\n * Replacer function for JSON.stringify that sorts object keys alphabetically.\n * @param key The key of the current property being processed.\n * @param value The value of the current property being processed.\n * @returns The processed value with sorted keys if it's an object, otherwise the original value.\n */\nexport const sortKeysReplacer = (key: string, value: any): any => {\n // Check if the value is a non-null object that is not an Array\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n // Create a new object with keys sorted alphabetically\n return Object.keys(value)\n .sort()\n .reduce((sorted, key) => {\n // Recursively process the value to ensure nested objects are also sorted\n sorted[key] = value[key];\n return sorted;\n }, {} as any);\n }\n // Return primitives and arrays as is\n return value;\n};\n\n/**\n * A helper to remove unwanted local cache data from the state before sending to the server.\n */\nexport const dehydrateState = (state: LayoutsState) => {\n for (const el of Object.values(state.layouts)\n .map((lay) => lay.elements)\n .flat()) {\n // FIXME:\" Can we achieve this better? Maybe non serializable fields could be removed entirely from the element.\"\n if (el.type === \"illustration\") {\n delete (el as IllustrationElement).cachedObjectURL;\n // When a src is provided for an svg let's remove the parsed data from the network request.\n if ((el as IllustrationElement).src) delete (el as IllustrationElement).svg;\n }\n if (el.type === \"frame\") {\n delete (el as FrameElement).pattern?.svg;\n }\n }\n // Ensure the __typename field used by apollo is not sent to the server.\n deleteFieldNameFromObjectRecursive(state, \"__typename\");\n return state;\n};\n\nconst deleteFieldNameFromObjectRecursive = (obj: any, fieldName: string) => {\n if (typeof obj !== \"object\" || obj === null) {\n return;\n }\n for (const key in obj) {\n if (key === fieldName) {\n delete obj[key];\n } else {\n deleteFieldNameFromObjectRecursive(obj[key], fieldName);\n }\n }\n};\n","import {\n FrameMetadata,\n IllustrationMetadata,\n ModuleMetadata,\n RegionElement,\n TextMetadata,\n StepSelections,\n Transaction,\n CommandWithFollowup,\n Product,\n Customer,\n SilentStepData,\n Placeable,\n StepStorage,\n VariantResource,\n ILayout,\n LayoutState,\n SerializableStep,\n Workflow,\n LayoutsState,\n StepType,\n ModelStepData,\n MaterialStepData,\n SerializableWorkflow,\n IllustrationElement,\n FrameElement,\n Step,\n AnyStepData,\n DigitalContentStepData,\n FrameStepData,\n IllustrationStepData,\n ModuleStepData,\n PictureStepData,\n QuestionStepData,\n ShapeStepData,\n TextStepData,\n} from \"../types\";\nimport {\n getAllScenes,\n getActiveScenes,\n getRenderableRelevantScenes,\n stepConditionsAreSatisfied,\n WorkflowScene,\n} from \"./scenes\";\nimport { PromiseQueue, QueueablePromise } from \"../util/PromiseQueue\";\nimport { FetchResult, MutationOptions } from \"@apollo/client/core\";\nimport { FrameService } from \"../services/steps/frame/Service\";\nimport { Poller } from \"../util/Poller\";\nimport cloneDeep from \"lodash.clonedeep\";\nimport isEqual from \"lodash.isequal\";\nimport { SilentStepHandler, SilentStepTriggerResult } from \"../services/SilentStepHandler\";\nimport { digitalContentStepService } from \"../services/steps/digitalContent\";\nimport { frameStepService } from \"../services/steps/frame\";\nimport { illustrationStepService } from \"../services/steps/illustration\";\nimport { materialStepService } from \"../services/steps/material\";\nimport { modelStepService } from \"../services/steps/model\";\nimport { moduleStepService } from \"../services/steps/module\";\nimport { pictureStepService } from \"../services/steps/picture\";\nimport { questionStepService } from \"../services/steps/question\";\nimport { shapeStepService } from \"../services/steps/shape\";\nimport { textStepService } from \"../services/steps/text\";\nimport { ModuleProduct } from \"../module/ModuleProduct\";\nimport moduleResolver from \"../module/resolver\";\nimport { UnhandledBehaviorError } from \"../util/exception\";\nimport { LayoutPreviewService } from \"./LayoutPreviewService\";\nimport type { ModelContainer, ThreeDPreviewService } from \"@spiffcommerce/preview\";\nimport { SpiffCommerceClient } from \"../client\";\nimport { graphQlManager } from \"../services/server\";\nimport { getConversionConfigurationQuery, getTransactionStakeholdersQuery } from \"../query\";\nimport { WorkflowExperience } from \"../WorkflowExperience\";\nimport { CanvasCommand, DeleteElementCommand, GroupCommand, UpdateWorkflowStateCommand } from \"../command\";\nimport { CommandContext, CommandState } from \"../CommandContext\";\nimport { generate } from \"../util/guid\";\nimport {\n createRecipientQuery,\n transactionApprovalQuery,\n transactionAttachRecipientQuery,\n transactionRejectionQuery,\n updateRecipientQuery,\n} from \"../Bundle/query\";\nimport {\n ConversionConfiguration,\n ConversionDataType,\n FrameStepHandle,\n optionService,\n Recipient,\n WorkflowExperienceEventType,\n WorkflowPanel,\n} from \"..\";\nimport { GraphQlClientFunc } from \"../services/graphql\";\nimport { dehydrateState, sortKeysReplacer } from \"../util/object\";\n\nexport interface SilentIllustrationStepData extends SilentStepData, Placeable {}\n\nexport interface ProductOverlayStepData extends SilentStepData, Placeable {}\n\nexport interface EditedSteps {\n [stepName: string]: boolean;\n}\n\nexport interface MandatorySteps {\n [stepName: string]: boolean;\n}\n\nexport type StepElements = {\n [key: string]: RegionElement[];\n};\n\nexport type StepInitialised = {\n [key: string]: boolean;\n};\n\nexport type StepMetadata = FrameMetadata | IllustrationMetadata | ModuleMetadata | TextMetadata;\n\n// Non-variant decisions made in each step.\nexport interface WorkflowStorage {\n [stepName: string]: StepStorage;\n}\n\nexport interface WorkflowMetadata {\n [stepName: string]: StepMetadata;\n}\n\nexport interface WorkflowSelections {\n [stepName: string]: {\n selections: VariantResource[];\n };\n}\n\nexport interface InformationResult {\n message: string;\n messageType: InformationMessageType;\n stepID: string;\n}\n\nexport enum InformationMessageType {\n Error = \"Error\",\n Warning = \"Warning\",\n Info = \"Info\",\n}\n\n/**\n * Services required for the operation of individual steps.\n */\nexport interface StepSpecificServices {\n frameService?: FrameService;\n module?: ModuleProduct;\n}\n\nexport interface ValidationErrors {\n steps: Map<string, Map<string, string>>;\n}\n\nexport type DesignCreationProgressUpdate = (message: string) => void;\nexport type ConfirmCallback = (isConfirmed: boolean) => void;\nexport type EditedCallback = (editedSteps: EditedSteps) => void;\nexport type ElementsCallback = (elements: StepElements) => void;\nexport type EnsuredInitialisedCallback = (ensuredInitialised: boolean) => void;\nexport type InformationResultCallback = (messages: InformationResult[]) => void;\nexport type InitCallback = (stepInitialised: StepInitialised) => void;\nexport type MakingAdjustmentsCallback = (makingAdjustments: string) => void;\nexport type MandatoryCallback = (mandatorySteps: MandatorySteps) => void;\nexport type MetadataCallback = (metadata: WorkflowMetadata) => void;\nexport type SelectionCallback = (callbackOptions: {\n selectionCost: number;\n selections: StepSelections;\n traversableScenes: WorkflowScene[];\n}) => void;\nexport type StepSpecificStorageCallback = (selections: StepStorage) => void;\nexport type StorageCallback = (storage: WorkflowStorage) => void;\nexport type ValidationCallback = (validationErrors: ValidationErrors) => void;\nexport type RecipientCallback = (recipient: Recipient | undefined) => void;\n\nexport type StateMutationFunc = (\n options?: Omit<MutationOptions, \"mutation\">,\n) => Promise<FetchResult<any, Record<string, any>, Record<string, any>>>;\n\nexport type GraphQlRequest = (\n options?: Omit<MutationOptions, \"mutation\">,\n) => Promise<FetchResult<any, Record<string, any>, Record<string, any>>>;\n\nexport const STATE_DEBOUNCE_TIME = 1000;\n\n/**\n * Encapsulates the behavior of updating layout state against a transaction on the server.\n */\nexport class WorkflowStatePromise extends QueueablePromise {\n private readonly update: () => Promise<any>;\n public readonly createdAt: Date = new Date();\n\n constructor(update: () => Promise<any>) {\n super();\n this.update = update;\n }\n public async execute() {\n await this.update();\n await new Promise<void>((resolve) => {\n window.setTimeout(() => {\n resolve();\n }, STATE_DEBOUNCE_TIME);\n });\n }\n}\n\nexport interface WorkflowManager {\n addPoller: (poller: Poller) => void;\n addConfirmCallback: (callback: ConfirmCallback) => void;\n addEditedCallback: (callback: EditedCallback) => void;\n addElementsCallback: (callback: ElementsCallback) => void;\n addInformationResultCallback: (callback: InformationResultCallback) => void;\n addInitCallback: (callback: InitCallback) => void;\n addMakingAdjustmentsCallback: (callback: MakingAdjustmentsCallback) => void;\n addMandatoryCallback: (callback: MandatoryCallback) => void;\n addMetadataCallback: (callback: MetadataCallback) => void;\n addSelectionCallback: (callback: SelectionCallback) => void;\n addStepSpecificStorageCallback: (callback: StepSpecificStorageCallback, stepName: string) => void;\n addStorageCallback: (callback: StorageCallback) => void;\n addValidationCallback: (callback: ValidationCallback) => void;\n addRecipientCallback: (callback: RecipientCallback) => void;\n removeRecipientCallback: (callback: RecipientCallback) => void;\n getCommandDispatcher: () => (command: CanvasCommand) => void;\n getCommandContext: () => CommandContext;\n getLayouts: () => ILayout[];\n getAllLayoutData: () => LayoutState[];\n getLayoutPreviewService: () => LayoutPreviewService | undefined;\n getPreviewService: () => ThreeDPreviewService | undefined;\n getRegionElements: (stepName: string) => RegionElement[];\n getSerializedStep: (stepName: string, serializedSteps: SerializableStep[]) => SerializableStep | undefined;\n getStepSpecificServices: (stepName: string) => StepSpecificServices | undefined;\n getStepStorage: (stepName: string) => StepStorage | undefined;\n getMetadata: (stepName: string) => StepMetadata | undefined;\n getWorkflowMetadata: () => WorkflowMetadata;\n getInformationResults(): InformationResult[];\n getTransactionCustomer: () => Customer | undefined;\n setTransactionCustomer: (customer: Customer) => void;\n\n /**\n * Sets the current workflow for this experience.\n * @param workflow The new workflow to set.\n * @returns A promise that resolves when the workflow has been set.\n */\n setWorkflow: (workflow: Workflow) => Promise<void>;\n\n /**\n * @deprecated Use setTransactionCustomer instead.\n */\n setTransactionCustomerDetails: (details: { email: string }) => void;\n getWorkflowSelections: () => WorkflowSelections;\n getStepSelections: () => StepSelections;\n /**\n * A promise resolving when the initial state of the workflow has completed loading.\n */\n getInitializationPromise: () => Promise<void>;\n /**\n * Returns true when the initial state of the workflow has been loaded and settled.\n */\n isInitialized(): boolean;\n /**\n * Returns a set of strings representing the identifiers of the minimal set of options\n * required to satisfy the default initial loaded state of the workflow.\n */\n getInitialOptionIds(existingSelections?: StepSelections): Set<string>;\n markStepsAsInitialised: (stepNames: string[]) => void;\n getUpdatesPending: () => boolean;\n markUpdateCompleted: (id: string) => void;\n markUpdatePending: () => string;\n outstandingRequestsPromise: () => Promise<void>;\n reset: () => Promise<void>;\n setCurrentAdjustingStepId: (stepId: string) => void;\n setEditedStatus: (stepName: string, status: boolean) => void;\n setInformationResults: (results: InformationResult[]) => void;\n setMandatoryFulfilled: (stepName: string, status: boolean) => void;\n getMandatoryUnfulfilledSteps: () => string[];\n setSelectionsAndElements: (\n stepName: string,\n variants: VariantResource[],\n elements: RegionElement[],\n callback?: () => Promise<void>,\n ) => Promise<void>;\n getStateHash(): Promise<string>;\n setStepError: (stepName: string, field: string, error: string | undefined) => void;\n /** Gets any validation errors for a specific step, or `undefined` if there are none. */\n getStepErrors: (stepName: string) => Map<string, string> | undefined;\n /** Gets validation errors for all steps. Only steps with errors will be present. */\n getValidationErrors: () => ValidationErrors;\n toggleDesignConfirmed: () => void;\n updateMetadata: (stepName: string, update: any) => void;\n /**\n * @deprecated State updates are being pulled internally. This function will be removed in the future.\n */\n updateStateWithServerImmediate: (getReducerState: () => CommandState) => Promise<void>;\n updateStorage: (stepName: string, update: StepStorage) => void;\n getModelContainer: () => ModelContainer | undefined;\n setModelContainer: (container: ModelContainer) => void;\n\n /**\n * Injects the model of this product into the preview service.\n * This also overwrites the internal preview service.\n * @param previewService The preview service to inject into.\n * @param refocusCamera Optional: Run camera focus Defaults to `true`.\n */\n injectIntoPreviewService(previewService: ThreeDPreviewService, refocusCamera?: boolean): Promise<void>;\n\n /**\n * Ejects the model of this product from the preview service. This also sets the internal preview service to undefined.\n */\n ejectFromPreviewService(): void;\n\n /**\n * Enables or disables uploading of workflow state to the server.\n * @param enabled When true, workflow state will be uploaded to the server.\n */\n setWorkflowStateSyncEnabled: (enabled: boolean) => void;\n\n /**\n * Returns the client that was responsible for spawning this manager.\n */\n getClient(): SpiffCommerceClient;\n\n /**\n * Returns the workflow experience that was responsible for creating this manager.\n */\n getWorkflowExperience(): WorkflowExperience;\n\n /**\n * Re-fetches the transactionShareActions for this WorkflowManager's Transaction object.\n * The updated transactionShareActions overwrite the existing values on the Transaction object returned by `getTransaction()`.\n */\n updateTransactionShareActions(): Promise<void>;\n\n /**\n * Re-fetches the stakeholders and currentStakeholder for this WorkflowManager's Transaction object.\n * The updated stakeholders and currentStakeholder overwrite the existing values on the Transaction object returned by `getTransaction()`.\n */\n updateTransactionStakeholders(): Promise<void>;\n\n /**\n * Returns the tags for a step.\n */\n getStepTags(stepId: string): string[];\n\n approveTransaction(note?: string): Promise<void>;\n\n rejectTransaction(note?: string): Promise<void>;\n\n /**\n * Create or amend the recipient fo the transaction.\n */\n updateRecipient(\n firstName?: string,\n lastName?: string,\n address?: string,\n suburb?: string,\n state?: string,\n email?: string,\n postalCode?: string,\n country?: string,\n mobile?: string,\n company?: string,\n apartment?: string,\n customField1?: string,\n customField2?: string,\n customField3?: string,\n customField4?: string,\n customField5?: string,\n conversionConfigurationId?: string,\n prevalidated?: boolean,\n ): Promise<void>;\n\n /**\n * Returns the context object used for text templating.\n */\n getTemplatingContext(): { [key: string]: any };\n\n traversableScenes(): Promise<WorkflowScene[]>;\n}\n\nconst createLayoutsFromPanels = (panels: WorkflowPanel[]): ILayout[] => {\n return panels\n .sort((a, b) => a.index - b.index)\n .map((panel: WorkflowPanel): ILayout => {\n return {\n id: generate(),\n panelId: panel.name,\n name: panel.name,\n title: panel.title,\n index: panel.index,\n createdAt: new Date(),\n updatedAt: new Date(),\n transparentBackground: panel.transparentBackground,\n height: panel.height,\n width: panel.width,\n previewRegion: panel.previewRegion,\n useEditableArea: panel.useEditableArea,\n editableArea: panel.editableArea,\n };\n });\n};\n\nconst getInitialLayouts = (transaction: Transaction, workflow: Workflow) => {\n const serializedState = transaction.workflowState;\n const initialReducerState = serializedState ? (JSON.parse(serializedState) as LayoutsState) : undefined;\n if (initialReducerState) {\n return Object.values(initialReducerState.layouts).map((state) => state.layout);\n }\n return createLayoutsFromPanels(workflow.panels);\n};\n\nexport class InternalWorkflowManager implements WorkflowManager {\n readonly client: SpiffCommerceClient;\n readonly experience: WorkflowExperience;\n\n private reloadedState?: LayoutsState;\n private ownerCustomer?: Customer;\n private updateTransaction: StateMutationFunc;\n private graphQlClient: GraphQlClientFunc;\n private confirmedDesign: boolean;\n private editedSteps: EditedSteps;\n private informationResults: InformationResult[];\n private layouts: ILayout[];\n private mandatorySteps: MandatorySteps;\n private pendingUpdates: string[];\n private selectionCost: number;\n private stepSpecificServices: { [stepName: string]: StepSpecificServices };\n private previewService: ThreeDPreviewService | undefined;\n private pollers: Poller[];\n private commandContext: CommandContext;\n private validationErrors: ValidationErrors;\n\n private stepElements: StepElements;\n private stepInitialised: StepInitialised;\n private stepMetadata: WorkflowMetadata;\n private stepSelections: StepSelections;\n private storage: WorkflowStorage;\n\n private confirmCallbacks: ConfirmCallback[];\n private editedCallbacks: EditedCallback[];\n private elementsCallbacks: ElementsCallback[];\n private informationResultCallbacks: InformationResultCallback[];\n private initCallbacks: InitCallback[];\n private makingAdjustmentsCallback: MakingAdjustmentsCallback[];\n private mandatoryCallbacks: MandatoryCallback[];\n private metadataCallbacks: MetadataCallback[];\n private selectionCallbacks: SelectionCallback[];\n private stepSpecificStorageCallbacks: {\n [stepName: string]: StepSpecificStorageCallback[];\n };\n private storageCallbacks: StorageCallback[];\n private validationCallbacks: ValidationCallback[];\n private recipientCallbacks: RecipientCallback[];\n\n private allScenes: WorkflowScene[];\n\n private currentAdjustingStepId: string;\n\n private renderableContextService?: LayoutPreviewService;\n private workflowStatePromiseQueue: PromiseQueue<WorkflowStatePromise> = new PromiseQueue<WorkflowStatePromise>(1);\n\n private initializationPromise: Promise<void>; // A promise that resolves when the initial state of the workflow has been loaded and settled.\n private initialized: boolean = false; // True when the initial state of the workflow has been loaded and settled.\n private readOnly: boolean = false;\n private modelContainer: ModelContainer | undefined;\n private isReloadedTransaction: boolean = false; // True when the transaction is being reloaded, rather than newly created.\n\n /** @deprecated This flag is made irrelevant by the introduction of step-specific silent flag */\n private singleVariantsRenderable: boolean = false;\n\n private stepTags: { [stepId: string]: string[] } = {};\n\n private recipientConversionConfiguration: ConversionConfiguration | undefined;\n\n constructor(\n experience: WorkflowExperience,\n client: SpiffCommerceClient,\n updateTransaction: StateMutationFunc,\n graphQlClient: GraphQlClientFunc,\n reloadedState?: LayoutsState,\n readOnly: boolean = false,\n modelContainer?: ModelContainer,\n /** @deprecated Should be determined via reloadedState */\n isReloadedTransaction: boolean = false,\n /** @deprecated Silent flag on steps makes this irrelevant */\n singleVariantsRenderable: boolean = false,\n /** @deprecated System should be smart enough to understand when to do this without manual instruction */\n delayWorkflowStateSync: boolean = false,\n ) {\n this.experience = experience;\n this.client = client;\n this.updateTransaction = updateTransaction;\n this.graphQlClient = graphQlClient;\n\n this.reloadedState = reloadedState;\n this.readOnly = readOnly;\n this.singleVariantsRenderable = singleVariantsRenderable;\n\n this.commandContext = new CommandContext();\n\n this.confirmCallbacks = [];\n this.editedCallbacks = [];\n this.elementsCallbacks = [];\n this.informationResultCallbacks = [];\n this.initCallbacks = [];\n this.mandatoryCallbacks = [];\n this.makingAdjustmentsCallback = [];\n this.metadataCallbacks = [];\n this.selectionCallbacks = [];\n this.stepSpecificStorageCallbacks = {};\n this.storageCallbacks = [];\n this.validationCallbacks = [];\n this.recipientCallbacks = [];\n\n this.modelContainer = modelContainer;\n\n this.confirmedDesign = false;\n this.editedSteps = {};\n this.informationResults = [];\n this.mandatorySteps = {};\n this.pendingUpdates = [];\n this.selectionCost = 0;\n this.stepSpecificServices = {};\n this.pollers = [];\n this.allScenes = [];\n\n this.stepElements = {};\n this.stepInitialised = {};\n this.stepMetadata = {};\n this.stepSelections = {};\n this.storage = {};\n this.validationErrors = { steps: new Map() };\n\n this.currentAdjustingStepId = \"\";\n\n this.isReloadedTransaction = isReloadedTransaction;\n\n if (delayWorkflowStateSync) {\n this.workflowStatePromiseQueue.enabled = false;\n }\n\n const workflow = this.experience.getWorkflow();\n if (workflow) {\n this.setWorkflow(workflow);\n }\n }\n\n /**\n * Sets the current workflow for this experience.\n * @param workflow The new workflow to set.\n * @returns A promise that resolves when the workflow has been set.\n */\n setWorkflow: (workflow: Workflow) => Promise<void> = async (workflow: Workflow) => {\n // Clear existing state\n this.confirmedDesign = false;\n this.editedSteps = {};\n this.informationResults = [];\n this.mandatorySteps = {};\n this.pendingUpdates = [];\n this.selectionCost = 0;\n this.stepSpecificServices = {};\n this.pollers = [];\n this.allScenes = [];\n this.stepElements = {};\n this.stepInitialised = {};\n this.stepMetadata = {};\n this.stepSelections = {};\n this.storage = {};\n this.validationErrors = { steps: new Map() };\n this.currentAdjustingStepId = \"\";\n\n // We either reload initial state or we create a new one.\n if (this.reloadedState) {\n // FIXME: What if reloadedState is for a different workflow?\n this.layouts = Object.values(this.reloadedState.layouts || {}).map((x) => x.layout);\n } else if (workflow) {\n this.layouts = getInitialLayouts(this.experience.getTransaction(), workflow);\n } else {\n this.layouts = [];\n }\n\n // Initialize the command context to a default state.\n this.commandContext.initialize(this.layouts, this.reloadedState);\n // Construct a renderable service for this manager.\n this.renderableContextService = new LayoutPreviewService(this.layouts);\n this.renderableContextService.setWorkflowManager(this);\n // Load step tags\n workflow.steps.forEach((step) => {\n this.stepTags[step.stepName] = step.tags ?? [];\n });\n\n const ps = this.previewService;\n this.ejectFromPreviewService();\n\n // Fire initialisation process.\n this.initializationPromise = this.initializeDefaultWorkflowState(workflow);\n this.initializationPromise.then(() => {\n this.initialized = true;\n });\n this.initializationPromise.catch((e) => {\n this.initialized = false;\n throw new Error(e);\n });\n this.initializationPromise.finally(() =>\n this.commandContext.registerStateCallback(() => {\n this.updateStateWithServer();\n this.renderLayouts();\n }),\n );\n\n if (ps) {\n await this.injectIntoPreviewService(ps, true);\n }\n };\n\n getTemplatingContext() {\n const recipient = this.experience.getTransaction().recipient;\n const c = { recipient };\n this.recipientConversionConfiguration?.requestedDataItems?.forEach((item) => {\n const id = item.uniqueIdentifier ?? item.title ?? \"\";\n if (item.type === ConversionDataType.FirstName) {\n c[id] = recipient?.firstName;\n } else if (item.type === ConversionDataType.LastName) {\n c[id] = recipient?.lastName;\n } else if (item.type === ConversionDataType.Custom) {\n if (item.customFieldIndex === 1) {\n c[id] = recipient?.customField1;\n } else if (item.customFieldIndex === 2) {\n c[id] = recipient?.customField2;\n } else if (item.customFieldIndex === 3) {\n c[id] = recipient?.customField3;\n } else if (item.customFieldIndex === 4) {\n c[id] = recipient?.customField4;\n } else if (item.customFieldIndex === 5) {\n c[id] = recipient?.customField5;\n }\n if (item.option) {\n c[id] = item.option.variants?.find((v) => v.id === c[id])?.name;\n }\n }\n });\n return c;\n }\n\n async updateRecipient(\n firstName?: string,\n lastName?: string,\n address?: string,\n suburb?: string,\n state?: string,\n email?: string,\n postalCode?: string,\n country?: string,\n mobile?: string,\n company?: string,\n apartment?: string,\n customField1?: string,\n customField2?: string,\n customField3?: string,\n customField4?: string,\n customField5?: string,\n conversionConfigurationId?: string,\n prevalidated?: boolean,\n ): Promise<void> {\n const transaction = this.experience.getTransaction();\n if (transaction.recipient?.id) {\n this.experience.getTransaction().recipient = {\n id: transaction.recipient.id,\n firstName: firstName ?? transaction.recipient.firstName,\n lastName: lastName ?? transaction.recipient.lastName,\n address: address ?? transaction.recipient.address,\n suburb: suburb ?? transaction.recipient.suburb,\n state: state ?? transaction.recipient.state,\n email: email ?? transaction.recipient.email,\n postalCode: postalCode ?? transaction.recipient.postalCode,\n country: country ?? transaction.recipient.country,\n mobile: mobile ?? transaction.recipient.mobile,\n company: company ?? transaction.recipient.company,\n apartment: apartment ?? transaction.recipient.apartment,\n customField1: customField1 ?? transaction.recipient.customField1,\n customField2: customField2 ?? transaction.recipient.customField2,\n customField3: customField3 ?? transaction.recipient.customField3,\n customField4: customField4 ?? transaction.recipient.customField4,\n customField5: customField5 ?? transaction.recipient.customField5,\n conversionConfigurationId: conversionConfigurationId || transaction.recipient.conversionConfigurationId,\n };\n this.experience.callEvent(WorkflowExperienceEventType.RecipientChanged);\n await this.graphQlClient().mutate({\n mutation: updateRecipientQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: transaction.recipient.id,\n firstName: firstName || transaction.recipient.firstName,\n lastName: lastName || transaction.recipient.lastName,\n address: address || transaction.recipient.address,\n suburb: suburb || transaction.recipient.suburb,\n state: state || transaction.recipient.state,\n email: email || transaction.recipient.email,\n postalCode: postalCode || transaction.recipient.postalCode,\n country: country || transaction.recipient.country,\n mobile: mobile || transaction.recipient.mobile,\n company: company || transaction.recipient.company,\n apartment: apartment || transaction.recipient.apartment,\n customField1: customField1 || transaction.recipient.customField1,\n customField2: customField2 || transaction.recipient.customField2,\n customField3: customField3 || transaction.recipient.customField3,\n customField4: customField4 || transaction.recipient.customField4,\n customField5: customField5 || transaction.recipient.customField5,\n conversionConfigurationId:\n conversionConfigurationId || transaction.recipient.conversionConfigurationId,\n prevalidated,\n },\n });\n } else {\n const createRecipientResult = await this.graphQlClient().mutate<{ recipientCreate: { id: string } }>({\n mutation: createRecipientQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n firstName,\n lastName,\n address,\n suburb,\n state,\n email,\n postalCode,\n country,\n mobile,\n company,\n apartment,\n customField1,\n customField2,\n customField3,\n customField4,\n customField5,\n conversionConfigurationId,\n },\n });\n transaction.recipient = {\n id: createRecipientResult?.data?.recipientCreate?.id,\n firstName,\n lastName,\n address,\n suburb,\n state,\n email,\n postalCode,\n country,\n mobile,\n company,\n apartment,\n customField1,\n customField2,\n customField3,\n customField4,\n customField5,\n conversionConfigurationId,\n };\n this.experience.callEvent(WorkflowExperienceEventType.RecipientChanged);\n await this.graphQlClient().mutate({\n mutation: transactionAttachRecipientQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.experience.getTransaction().id,\n recipientId: createRecipientResult.data?.recipientCreate?.id,\n },\n context: {\n transactionOwnerId: this.experience.getTransaction().transactionOwnerId,\n },\n });\n }\n await this.fetchConversionConfiguration();\n this.recipientCallbacks.forEach((c) => c(this.experience.getTransaction().recipient));\n }\n\n private static configurationPromiseMap = new Map<string, Promise<ConversionConfiguration | undefined>>();\n\n private async fetchConversionConfiguration() {\n const recipient = this.experience.getTransaction().recipient;\n if (recipient?.conversionConfigurationId && !this.recipientConversionConfiguration) {\n const existingPromise = InternalWorkflowManager.configurationPromiseMap.get(\n recipient.conversionConfigurationId,\n );\n if (existingPromise) {\n this.recipientConversionConfiguration = await existingPromise;\n } else {\n const getConfig = async () => {\n const response = await this.graphQlClient().query<{\n conversionConfiguration?: ConversionConfiguration;\n }>({\n query: getConversionConfigurationQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: recipient.conversionConfigurationId,\n },\n });\n return response.data.conversionConfiguration;\n };\n const promise = getConfig();\n InternalWorkflowManager.configurationPromiseMap.set(recipient.conversionConfigurationId, promise);\n this.recipientConversionConfiguration = await promise;\n }\n }\n }\n\n private async initializeDefaultWorkflowState(workflow: Workflow) {\n const fireReloadAnimation = () => {\n const finalConfig = workflow.finalizeStepConfig;\n if (!finalConfig) return;\n const lookAt = finalConfig.lookAtAnimation;\n const modelAnim = finalConfig.modelAnimation;\n if (lookAt) this.previewService?.executeCameraAnimation(lookAt);\n if (modelAnim) this.modelContainer?.executeAnimation(modelAnim);\n };\n\n // If a reloaded state exists, we want to load the state from that instead of initializing with defaults.\n if (this.reloadedState) {\n this.reloadedState.serializableWorkflow.steps.forEach((step) => {\n this.storage[step.stepName] = step.storage || {};\n });\n }\n\n const requiredInitialOptions = this.getInitialOptionIds(\n this.reloadedState?.serializableWorkflow?.steps.reduce<StepSelections>((acc, step) => {\n if (step.selectedVariants?.length) {\n acc[step.stepName] = {\n selectedVariants: step.selectedVariants.map((v) => ({ id: v.id }) as VariantResource),\n };\n }\n return acc;\n }, {}),\n );\n const initialOptionsPromise = optionService.getOptions(Array.from(requiredInitialOptions));\n const conversionConfigPromise = this.fetchConversionConfiguration();\n\n await Promise.all([initialOptionsPromise, conversionConfigPromise]);\n\n // We set the scenes the workflow should start with\n this.allScenes = getAllScenes(workflow);\n\n // Initialize any relevant starting silent steps.\n const activeScenes = getActiveScenes(this.allScenes, this.stepSelections);\n const introducedSilentSteps = activeScenes.map((scene) => scene.silentSteps).flat();\n const { stepElements: silentStepElements, commands: silentCommands } =\n await this.stepElementsForIntroducedSilentSteps(introducedSilentSteps, !!this.reloadedState);\n this.commandContext.apply(new GroupCommand(silentCommands), true);\n this.stepElements = { ...this.stepElements, ...silentStepElements };\n\n // Begin by setting the initial state of the workflow.\n await this.ensureStepsAreLoaded();\n\n // Sync the initial state\n if (!this.isReloadedTransaction) {\n this.updateStateWithServer();\n }\n\n // Initial render of the 3D scene.\n this.renderLayouts();\n\n // If we're dealing with a reloaded state, we want to fire of the initial animations at this point.\n this.reloadedState && fireReloadAnimation();\n }\n\n getWorkflowExperience() {\n return this.experience;\n }\n\n getClient() {\n return this.client;\n }\n\n setWorkflowStateSyncEnabled(enabled: boolean) {\n this.workflowStatePromiseQueue.enabled = enabled;\n }\n\n getInitializationPromise() {\n return this.initializationPromise;\n }\n\n isInitialized() {\n return this.initialized;\n }\n\n getInitialOptionIds(existingSelections?: StepSelections): Set<string> {\n const optionIds = new Set<string>();\n const workflow = this.experience.getWorkflow();\n\n if (!workflow) {\n return optionIds;\n }\n\n // Build a simulated set of step selections based on each step's default variant.\n // We iteratively expand active steps until no new steps are activated, so that\n // conditions satisfied by default selections are accounted for.\n const allScenes = getAllScenes(workflow);\n const simulatedSelections: StepSelections = { ...existingSelections };\n let previousActiveStepCount = -1;\n\n while (true) {\n const activeScenes = getActiveScenes(allScenes, simulatedSelections);\n const activeSteps = activeScenes.flatMap((scene) => scene.renderableSteps);\n\n if (activeSteps.length === previousActiveStepCount) {\n break;\n }\n previousActiveStepCount = activeSteps.length;\n\n for (const step of activeSteps) {\n if (simulatedSelections[step.stepName]) {\n continue;\n }\n const defaultVariantId = step.option?.defaultVariant?.id;\n if (defaultVariantId) {\n simulatedSelections[step.stepName] = {\n selectedVariants: [{ id: defaultVariantId } as VariantResource],\n };\n }\n }\n }\n\n // Collect the option id from every initially active step that has one.\n const activeScenes = getActiveScenes(allScenes, simulatedSelections);\n activeScenes\n .flatMap((scene) => scene.renderableSteps)\n .forEach((step) => {\n // If we have variants we can assume we have the option in full and don't need to pull data.\n if (step.option?.id && !step.option?.variants) {\n optionIds.add(step.option.id);\n }\n });\n\n return optionIds;\n }\n\n addConfirmCallback(callback: ConfirmCallback) {\n callback(this.confirmedDesign);\n this.confirmCallbacks.push(callback);\n }\n\n addEditedCallback(callback: EditedCallback) {\n callback(this.editedSteps);\n this.editedCallbacks.push(callback);\n }\n\n addElementsCallback(callback: ElementsCallback) {\n callback(this.stepElements);\n this.elementsCallbacks.push(callback);\n }\n\n addInformationResultCallback(callback: InformationResultCallback) {\n callback(this.informationResults);\n this.informationResultCallbacks.push(callback);\n }\n\n addInitCallback(callback: InitCallback) {\n callback(this.stepInitialised);\n this.initCallbacks.push(callback);\n }\n\n addMandatoryCallback(callback: MandatoryCallback) {\n callback(this.mandatorySteps);\n this.mandatoryCallbacks.push(callback);\n }\n\n addMetadataCallback(callback: MetadataCallback) {\n callback(this.stepMetadata);\n this.metadataCallbacks.push(callback);\n }\n\n async addSelectionCallback(callback: SelectionCallback) {\n callback({\n selectionCost: this.selectionCost,\n selections: this.stepSelections,\n traversableScenes: await this.traversableScenes(),\n });\n this.selectionCallbacks.push(callback);\n }\n\n addStepSpecificStorageCallback(callback: StepSpecificStorageCallback, stepName: string) {\n if (!Object.keys(this.storage).includes(stepName)) {\n this.storage[stepName] = {};\n }\n callback(this.storage[stepName]);\n if (!Object.keys(this.stepSpecificStorageCallbacks).includes(stepName)) {\n this.stepSpecificStorageCallbacks[stepName] = [];\n }\n this.stepSpecificStorageCallbacks[stepName].push(callback);\n }\n\n /**\n * @deprecated Any call to this causes all renderable steps to re-render even if they don't care about change.\n */\n addStorageCallback(callback: StorageCallback) {\n callback(this.storage);\n this.storageCallbacks.push(callback);\n }\n\n addMakingAdjustmentsCallback(callback: MakingAdjustmentsCallback) {\n callback(this.currentAdjustingStepId);\n this.makingAdjustmentsCallback.push(callback);\n }\n\n addPoller(poller: Poller) {\n this.pollers.push(poller);\n }\n\n addValidationCallback(callback: ValidationCallback) {\n this.validationCallbacks.push(callback);\n callback(this.validationErrors);\n }\n\n addRecipientCallback(callback: RecipientCallback) {\n this.recipientCallbacks.push(callback);\n callback(this.experience.getTransaction().recipient);\n }\n\n removeRecipientCallback(callback: RecipientCallback) {\n this.recipientCallbacks = this.recipientCallbacks.filter((it) => it !== callback);\n }\n\n getLayouts(): ILayout[] {\n return this.layouts;\n }\n\n getAllLayoutData(): LayoutState[] {\n return this.commandContext.getAllLayouts().map((l) => l.layoutState);\n }\n\n getLayoutPreviewService(): LayoutPreviewService | undefined {\n return this.renderableContextService;\n }\n\n getInformationResults(): InformationResult[] {\n return this.informationResults;\n }\n\n getPreviewService() {\n return this.previewService;\n }\n\n getCommandContext(): CommandContext {\n return this.commandContext;\n }\n\n getRegionElements(stepName: string): RegionElement[] {\n return this.stepElements[stepName] || [];\n }\n\n getStepSpecificServices(stepName: string): StepSpecificServices | undefined {\n return this.stepSpecificServices[stepName];\n }\n\n getTransactionCustomer(): Customer | undefined {\n return this.ownerCustomer;\n }\n\n setTransactionCustomer(customer: Customer) {\n this.ownerCustomer = customer;\n }\n\n setTransactionCustomerDetails(details: { email: string }) {\n this.ownerCustomer = { ...this.ownerCustomer, emailAddress: details.email };\n }\n\n getModelContainer(): ModelContainer | undefined {\n return this.modelContainer;\n }\n\n setModelContainer(container: ModelContainer): void {\n if (!container || (this.previewService && this.previewService.getAllModels().includes(container))) {\n this.modelContainer = container;\n if (container && container.metadata && container.metadata instanceof Map) {\n this.modelContainer.metadata.set(\"workflowManager\", this);\n }\n }\n }\n\n getCommandDispatcher() {\n return (command: CanvasCommand) => this.commandContext.apply(command, !this.initialized);\n }\n\n getWorkflowSelections(): WorkflowSelections {\n const selections: WorkflowSelections = {};\n this.experience.getWorkflow()?.steps.forEach((step) => {\n const stepStorage = this.stepSelections[step.stepName];\n if (stepStorage && stepStorage.selectedVariants && stepStorage.selectedVariants.length > 0) {\n selections[step.stepName] = {\n selections: stepStorage.selectedVariants,\n };\n }\n });\n return selections;\n }\n\n getStepSelections(): StepSelections {\n return this.stepSelections;\n }\n\n markStepsAsInitialised(stepNames: string[]) {\n const stepInitialised = { ...this.stepInitialised };\n stepNames.forEach((stepName) => {\n stepInitialised[stepName] = true;\n });\n this.stepInitialised = stepInitialised;\n this.onInitChange();\n }\n\n getUpdatesPending() {\n return this.pendingUpdates.length > 0;\n }\n\n markUpdateCompleted(id: string) {\n this.pendingUpdates = this.pendingUpdates.filter((up) => up !== id);\n }\n\n markUpdatePending() {\n const updateId = generate();\n this.pendingUpdates = [...this.pendingUpdates, updateId];\n return updateId;\n }\n\n setEditedStatus(stepName: string, status: boolean) {\n this.editedSteps = { ...this.editedSteps, [stepName]: status };\n this.onEditedChange();\n }\n\n setInformationResults(results: InformationResult[]) {\n this.informationResults = [...results];\n this.onInformationResultChange();\n }\n\n setCurrentAdjustingStepId(stepId: string) {\n this.currentAdjustingStepId = stepId;\n this.onMakingAdjustmentsChange();\n }\n\n setMandatoryFulfilled(stepName: string, status: boolean) {\n // If the value hasn't changed don't notify listeners.\n if (this.mandatorySteps[stepName] === status) {\n return;\n }\n // Otherwise update mandatory structure and notify\n this.mandatorySteps = { ...this.mandatorySteps, [stepName]: status };\n this.onMandatoryChange();\n }\n\n getMandatoryUnfulfilledSteps(): string[] {\n // Get the active mandatory steps.\n const scenes = getActiveScenes(this.allScenes, this.stepSelections);\n const steps = scenes.flatMap((scene) => scene.renderableSteps);\n const mandatorySteps = steps.filter((s) => s.mandatory);\n\n // A mandatory step is unfulfilled if its value is false or absent.\n const unfulfilledSteps = mandatorySteps.filter((s) => !this.mandatorySteps[s.stepName]);\n return unfulfilledSteps.map((s) => s.stepName);\n }\n\n setStepError(stepName: string, field: string, error: string | undefined) {\n let changed = false;\n if (!this.validationErrors.steps.has(stepName) && error) {\n // New step entry\n changed = true;\n this.validationErrors.steps.set(stepName, new Map([[field, error]]));\n } else if (this.validationErrors.steps.has(stepName)) {\n const stepErrors = this.validationErrors.steps.get(stepName)!;\n if (error && error !== stepErrors.get(field)) {\n // New or changed\n changed = true;\n stepErrors.set(field, error);\n } else if (!error) {\n // Deleted entry\n changed = true;\n stepErrors.delete(field);\n if (stepErrors.size === 0) {\n // Delete step if no errors\n this.validationErrors.steps.delete(stepName);\n }\n }\n }\n\n if (changed) {\n this.onValidationChange();\n }\n }\n\n getStepErrors(stepName: string) {\n return this.validationErrors.steps.get(stepName);\n }\n\n getValidationErrors() {\n return this.validationErrors;\n }\n\n toggleDesignConfirmed() {\n this.confirmedDesign = !this.confirmedDesign;\n this.onConfirmChange();\n }\n\n toggleMakingAdjustmentsCallback(callback: MandatoryCallback) {\n callback(this.mandatorySteps);\n this.mandatoryCallbacks.push(callback);\n }\n\n async injectIntoPreviewService(previewService: ThreeDPreviewService, refocusCamera?: boolean): Promise<void> {\n if (this.modelContainer) {\n throw new Error(\"You must eject from the preview service before injecting again.\");\n }\n this.previewService = previewService;\n const product = this.experience.getProduct();\n if (!product?.modelUrl || !this.previewService) return;\n const container = previewService.loadModel(\n {\n model: product.modelUrl,\n contextService: this.getLayoutPreviewService(),\n },\n { refocusCamera },\n );\n this.setModelContainer(container);\n const scenes = getActiveScenes(this.allScenes, this.stepSelections).filter((scene) => scene);\n const steps = scenes\n .map((scene) => scene.renderableSteps)\n .flat()\n .filter((step) => step.type === StepType.Model || step.type === StepType.Material);\n steps.forEach((step) => {\n if (!step.option?.id) {\n console.error(`Failed to read option id from step: ${step.stepName}`);\n return;\n }\n const selectedVariants = this.stepSelections[step.stepName]?.selectedVariants || [];\n if (selectedVariants.length === 0) return;\n const variant = selectedVariants[0];\n if (step.type === StepType.Model) {\n if (!this.modelContainer)\n throw new UnhandledBehaviorError(\n \"We should always have a model container when injecting a preview!\",\n );\n const modelRef = variant.asset?.fileLink;\n if (!modelRef) {\n console.error(`Failed to read model url from variant: ${variant.id} for step: ${step.stepName}`);\n return;\n }\n const data = step.data as ModelStepData;\n this.modelContainer.applyModelVariant(\n step.stepName,\n {\n model: modelRef,\n contextService: this.getLayoutPreviewService(),\n },\n data.replaceProductModel || false,\n );\n } else {\n const material = variant.material;\n if (!material) {\n console.error(`Failed to read material from variant: ${variant.id} for step: ${step.stepName}`);\n return;\n }\n const data = step.data as MaterialStepData;\n data.targetMaterials.forEach((matName) => {\n if (!this.modelContainer)\n throw new UnhandledBehaviorError(\n \"We should always have a model container when injecting a preview!\",\n );\n this.modelContainer.applyMaterialVariant(matName, step.option!.id!, material);\n });\n }\n });\n await container.getInitializationPromise();\n this.renderLayouts();\n }\n\n ejectFromPreviewService(): void {\n if (this.modelContainer) {\n if (!this.modelContainer.dispose) {\n throw new Error(\"This feature is not supported in the current preview service.\");\n }\n this.modelContainer.dispose();\n this.modelContainer = undefined;\n }\n this.previewService = undefined;\n }\n\n updateStorage(stepName: string, update: StepStorage) {\n const newStorage = {\n ...this.storage,\n [stepName]: { ...this.storage[stepName], ...update },\n };\n if (!isEqual(newStorage, this.storage)) {\n this.storage = newStorage;\n const workflowCommand = new UpdateWorkflowStateCommand(this.constructSerializableWorkflow());\n this.commandContext.apply(workflowCommand, true);\n this.onStepSpecificStorageChange(stepName);\n this.onStorageChange();\n }\n }\n\n private constructSerializableWorkflow(): SerializableWorkflow {\n const steps: SerializableStep[] = [];\n this.allScenes.forEach((scene) => {\n scene.renderableSteps.forEach((step) => {\n const stepStructure: SerializableStep = { stepName: step.stepName };\n stepStructure.storage = this.storage[step.stepName];\n stepStructure.selectedVariants = this.stepSelections[step.stepName]?.selectedVariants?.map(\n (variant) => {\n return { id: variant.id!, priceModifier: variant.priceModifier };\n },\n );\n steps.push(stepStructure);\n });\n });\n return { steps };\n }\n\n private updateStateWithServer() {\n if (this.readOnly) return;\n const workflowState = this.serialize();\n this.workflowStatePromiseQueue.enqueue(\n new WorkflowStatePromise(async () => {\n // HACK: Immediately firing a network request can block the thread when many fire at once.\n // Using setTimeout will push this promise to the end of the event loop, allowing the calling function to exit.\n await new Promise<void>((resolve) => {\n setTimeout(() => {\n resolve();\n }, 1);\n });\n await this.updateTransaction({\n variables: {\n id: this.experience.getTransaction().id,\n workflowState,\n },\n });\n }),\n );\n }\n\n private renderLayouts = () => {\n if (!this.previewService) return;\n const layouts = this.getCommandContext().getAllLayouts();\n const previewHandles = this.getLayoutPreviewService()?.getAll();\n if (!previewHandles) return;\n for (const [, previewBridge] of previewHandles) {\n previewBridge.render(layouts);\n }\n };\n\n public async updateStateWithServerImmediate() {\n if (this.readOnly) return;\n const workflowState = this.serialize();\n return new WorkflowStatePromise(async () => {\n await this.updateTransaction({\n variables: {\n id: this.experience.getTransaction().id,\n workflowState,\n },\n });\n }).execute();\n }\n\n private serialize(): string {\n const fullState = this.getCommandContext().getState();\n if (!fullState) {\n throw new UnhandledBehaviorError(\"Attempted to serialize state before it was initialized.\");\n }\n const deepClone = cloneDeep(fullState.transaction);\n const dehydrated = dehydrateState(deepClone);\n return JSON.stringify(dehydrated, sortKeysReplacer, undefined);\n }\n\n async getStateHash(): Promise<string> {\n const state = this.getCommandContext().getState();\n const modificationIds = Object.values(state?.transaction.layouts || {}).map((l) => l.modificationID ?? \"\");\n const alphabetizedModificationIds = modificationIds.sort().join(\"\");\n\n const encoder = new TextEncoder();\n const data = encoder.encode(alphabetizedModificationIds);\n\n // Browser Web Crypto API (preferred)\n if (\n typeof window !== \"undefined\" &&\n window.crypto &&\n (window.crypto as any).subtle &&\n (window.crypto as any).subtle.digest\n ) {\n const hashBuffer = await (window.crypto as any).subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hash = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n return hash;\n }\n\n // Node fallback using dynamic import of 'crypto'\n try {\n const crypto = await import(\"crypto\");\n return crypto.createHash(\"sha256\").update(alphabetizedModificationIds, \"utf8\").digest(\"hex\");\n } catch (e) {\n throw new Error(\"Unable to compute SHA-256 hash: no suitable crypto implementation available.\");\n }\n }\n\n async outstandingRequestsPromise() {\n return this.workflowStatePromiseQueue.finalize();\n }\n\n updateMetadata(stepName: string, update: any) {\n this.stepMetadata = {\n ...this.stepMetadata,\n [stepName]: { ...this.stepMetadata[stepName], ...update },\n };\n this.onMetadataChange();\n }\n\n private removeElements(elements: RegionElement[]) {\n const filterOutAllElementsFromSteps = (\n existingStepElements: StepElements,\n elements: RegionElement[],\n ): StepElements => {\n return Object.keys(existingStepElements).reduce<StepElements>((stepsWithoutOldElements, stepName) => {\n const newListOfStepElements = [...(existingStepElements[stepName] || [])];\n elements.forEach((regionElementToRemove) => {\n const index = newListOfStepElements.findIndex((currentRegionElement) => {\n return currentRegionElement.id === regionElementToRemove.id;\n });\n if (index > -1) {\n newListOfStepElements.splice(index, 1);\n }\n });\n stepsWithoutOldElements[stepName] = newListOfStepElements;\n return stepsWithoutOldElements;\n }, {});\n };\n this.stepElements = filterOutAllElementsFromSteps(this.stepElements, elements);\n }\n\n private getInvalidCanvasRegions(): RegionElement[] {\n return (\n this.experience.getWorkflow()?.steps.reduce<RegionElement[]>((selectionsToRemove, step) => {\n if (!stepConditionsAreSatisfied(step, this.stepSelections)) {\n if (this.stepElements[step.stepName]) {\n this.stepElements[step.stepName].forEach((regionElement: RegionElement) =>\n selectionsToRemove.push(regionElement),\n );\n }\n }\n return selectionsToRemove;\n }, []) || []\n );\n }\n\n private getInvalidModelVariants(): string[] {\n return (\n this.experience.getWorkflow()?.steps.reduce<string[]>((invalidVariants, step) => {\n if (step.type === StepType.Model && !stepConditionsAreSatisfied(step, this.stepSelections)) {\n invalidVariants.push(step.stepName);\n }\n return invalidVariants;\n }, []) || []\n );\n }\n\n /**\n * @deprecated This function is only relevant for silent steps that are introduced by a selection. Steps now expose a silent flag that should allow any step to achieve the same behavior without needing special handling. We should remove this function once all silent steps have been migrated to use the new flag and logic.\n */\n private async stepElementsForIntroducedSilentSteps(\n introducedSilentSteps: Step<AnyStepData>[],\n handlingReload: boolean,\n ): Promise<{ stepElements: StepElements; commands: CanvasCommand[] }> {\n const product = this.experience.getProduct();\n if (!product) {\n return Promise.resolve({ stepElements: {}, commands: [] });\n }\n\n // Trigger the given silent step.\n // Steps in completely silent scenes should trigger immediately when the step becomes relevant.\n // Steps in renderable scenes should trigger when the scene becomes active the first time.\n const executeSilentStep = async (\n step: Step<AnyStepData>,\n layouts: ILayout[],\n product: Product,\n ): Promise<{ step: Step<AnyStepData>; results: SilentStepTriggerResult[] }> => {\n if (step.type === StepType.SilentIllustration) {\n const result = await new SilentStepHandler(step as Step<SilentIllustrationStepData>, layouts).trigger();\n return { step, results: result };\n } else if (step.type === StepType.ProductOverlay) {\n const result = await new SilentStepHandler(\n step as Step<ProductOverlayStepData>,\n layouts,\n product,\n ).trigger();\n return { step, results: result };\n }\n\n return Promise.reject(\"Unknown silent step. This is a bug\");\n };\n\n const uninitializedSteps: Step<AnyStepData>[] = introducedSilentSteps.filter(\n (step) => !this.stepInitialised[step.stepName],\n );\n\n const result: { stepElements: StepElements; commands: CanvasCommand[] } = {\n stepElements: {},\n commands: [],\n };\n\n const silentStepPromises: Promise<{ step: Step<AnyStepData>; results: SilentStepTriggerResult[] }>[] = [];\n\n for (const step of uninitializedSteps) {\n this.markStepsAsInitialised([step.stepName]);\n if (!handlingReload) {\n silentStepPromises.push(executeSilentStep(step, this.layouts, product));\n }\n }\n const silentStepResults = await Promise.all(silentStepPromises);\n for (const stepResult of silentStepResults) {\n result.stepElements[stepResult.step.stepName] = stepResult.results.map((r) => r.regionElement);\n result.commands = [...result.commands, ...stepResult.results.map((r) => r.command)];\n }\n\n return result;\n }\n\n getStepStorage(stepName: string): StepStorage | undefined {\n return this.storage[stepName];\n }\n\n getMetadata(stepName: string): StepMetadata | undefined {\n return this.stepMetadata[stepName];\n }\n\n getWorkflowMetadata(): WorkflowMetadata {\n return this.stepMetadata;\n }\n\n getStepTags(stepId: string): string[] {\n return this.stepTags[stepId] || [];\n }\n\n /**\n * @deprecated Simply run serializedSteps.find((step) => step.stepName === stepName) instead.\n */\n getSerializedStep(stepName: string, serializedSteps: SerializableStep[]): SerializableStep | undefined {\n return serializedSteps.find((step) => step.stepName === stepName);\n }\n\n async updateTransactionShareActions() {\n const shareActions = await this.client.getShareActionsForTransaction(this.experience.getTransaction().id);\n this.experience.getTransaction().transactionShareActions = shareActions;\n }\n\n async updateTransactionStakeholders() {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ transactions: Transaction[] }>({\n query: getTransactionStakeholdersQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.experience.getTransaction().id,\n },\n });\n if (!response?.data?.transactions || response.data.transactions.length !== 1) {\n this.experience.getTransaction().currentStakeholder = undefined;\n this.experience.getTransaction().stakeholders = undefined;\n } else {\n this.experience.getTransaction().stakeholders = response.data.transactions[0].stakeholders;\n this.experience.getTransaction().currentStakeholder = response.data.transactions[0].currentStakeholder;\n }\n }\n\n async approveTransaction(note?: string): Promise<void> {\n await graphQlManager.getShadowGraphqlClient().mutate<{ id: string }>({\n mutation: transactionApprovalQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.experience.getTransaction().id,\n note,\n },\n });\n }\n\n async rejectTransaction(note?: string): Promise<void> {\n await graphQlManager.getShadowGraphqlClient().mutate<{ id: string }>({\n mutation: transactionRejectionQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.experience.getTransaction().id,\n note,\n },\n });\n }\n\n async reset() {\n this.stepElements = {};\n this.stepInitialised = {};\n this.stepMetadata = {};\n this.stepSelections = {};\n this.storage = {};\n await this.ensureStepsAreLoaded();\n }\n\n async setSelectionsAndElements(\n stepName: string,\n variants: VariantResource[],\n elements: RegionElement[],\n callback?: () => Promise<void>,\n ) {\n const workflow = this.experience.getWorkflow();\n if (!workflow) throw new Error(\"Attempted to set selections when no workflow is set!\");\n\n const oldSelections = this.stepSelections;\n this.stepSelections = {\n ...this.stepSelections,\n [stepName]: { selectedVariants: variants },\n };\n\n // Recursively tally the cost of all selections\n this.selectionCost = Object.values(this.stepSelections).reduce((total, current) => {\n return (\n total +\n current\n .selectedVariants!.map((vs) => vs.priceModifier || 0)\n .reduce((acc, val) => {\n return acc + val;\n }, 0)\n );\n }, 0);\n\n // Unset state of steps which have become irrelevant.\n workflow.steps.forEach((step) => {\n if (!stepConditionsAreSatisfied(step, this.stepSelections)) {\n this.stepInitialised[step.stepName] = false;\n delete this.stepMetadata[step.stepName];\n delete this.stepSelections[step.stepName];\n delete this.storage[step.stepName];\n }\n });\n\n // Find silent steps which have become relevant, cleanup any that have become irrelevant.\n const allScenes = this.allScenes;\n const oldScenes = getActiveScenes(allScenes, oldSelections);\n const newScenes = getActiveScenes(allScenes, this.stepSelections);\n const oldSilentSteps = oldScenes.map((scene) => scene.silentSteps).flat();\n const newSilentSteps = newScenes.map((scene) => scene.silentSteps).flat();\n const introducedSilentSteps = newSilentSteps.filter(\n (newStep) => !oldSilentSteps.some((oldStep) => oldStep.stepName === newStep.stepName),\n );\n oldSilentSteps.forEach((step) => {\n if (!stepConditionsAreSatisfied(step, this.stepSelections)) {\n this.stepInitialised[step.stepName] = false;\n }\n });\n\n const invalidCanvasRegions = this.getInvalidCanvasRegions();\n\n const { stepElements: silentStepElements, commands: silentCommands } =\n await this.stepElementsForIntroducedSilentSteps(introducedSilentSteps, false);\n\n // Set the new step elements\n this.stepElements = {\n ...this.stepElements,\n ...silentStepElements,\n [stepName]: elements,\n };\n\n // Remove any elements that have become invalid.\n this.removeElements(invalidCanvasRegions);\n\n // When target step is a frame, we need to notify frame service of new elements.\n const step = workflow.steps.find((step) => step.stepName === stepName);\n if (step?.type === StepType.Frame) {\n const frameService = (\n this.getWorkflowExperience().getStepById(step.stepName) as undefined | FrameStepHandle\n )?.frameService;\n frameService?.setTargetElements(elements.map((regionEl) => regionEl.id));\n }\n\n const deleteCommands = invalidCanvasRegions.map((el: RegionElement) => new DeleteElementCommand(el.id));\n const workflowCommand = new UpdateWorkflowStateCommand(this.constructSerializableWorkflow());\n const commands = [...silentCommands, ...deleteCommands, workflowCommand];\n if (commands.length > 0) {\n this.commandContext.apply(new GroupCommand(commands), true);\n }\n\n // Ensure any effects of this selection change are executed as a result.\n await this.ensureStepsAreLoaded();\n\n // Notify any listeners that the workflow has changed.\n this.onElementsChange();\n\n // When conditions change certain models may become invalid. We clean them up here.\n const invalidModelVariants = this.getInvalidModelVariants();\n const modelContainer = this.modelContainer;\n if (modelContainer) {\n const removalPromises = invalidModelVariants.map((im) =>\n modelContainer.applyModelVariant(\n im,\n {\n contextService: this.getLayoutPreviewService(),\n },\n false,\n ),\n );\n await Promise.all(removalPromises);\n }\n\n await this.onSelectionChange();\n\n // For step types except text/module/frame, setting a variant satisfies the mandatory flag.\n if (step?.type !== StepType.Frame && step?.type !== StepType.Text) {\n this.setMandatoryFulfilled(stepName, true);\n }\n\n if (callback) {\n await callback();\n }\n }\n\n /**\n * Ensures all steps for active scenes are initialized and loads them in parallel.\n *\n * This method:\n * 1. Identifies active scenes and their renderable steps\n * 2. Initializes uninitialized steps by invoking the appropriate step service based on step type\n * 3. Executes all initialization commands as a batch and processes followup actions\n * 4. Recursively handles any followup conditions that may trigger additional step loading\n * 5. Notifies listeners of initialization changes\n *\n * @throws {Error} If any step initialization fails during the settlement of promises\n * @returns {Promise<void>}\n */\n private async ensureStepsAreLoaded() {\n const activeScenes = getActiveScenes(this.allScenes, this.stepSelections);\n const stepsPerScene = activeScenes.map((scene) => scene.renderableSteps);\n\n // We create a list of steps which are not yet initialized.\n // Iterate over all required steps and run initialization, this should occur in parallel.\n const stepPromises: Promise<any>[] = [];\n const steps = stepsPerScene.flat();\n\n for (const step of steps) {\n if (!this.stepInitialised[step.stepName]) {\n this.stepInitialised[step.stepName] = true;\n switch (step.type) {\n case StepType.DigitalContent:\n stepPromises.push(\n digitalContentStepService.init(\n step as Step<DigitalContentStepData>,\n this,\n this.reloadedState,\n ),\n );\n break;\n case StepType.Frame:\n stepPromises.push(frameStepService.init(step as Step<FrameStepData>, this, this.reloadedState));\n break;\n case StepType.Illustration:\n stepPromises.push(\n illustrationStepService.init(step as Step<IllustrationStepData>, this, this.reloadedState),\n );\n break;\n case StepType.Material:\n stepPromises.push(\n materialStepService.init(step as Step<MaterialStepData>, this, this.reloadedState),\n );\n break;\n case StepType.Model:\n stepPromises.push(modelStepService.init(step as Step<ModelStepData>, this, this.reloadedState));\n break;\n case StepType.Module:\n // TODO: Mimic frame handles and scrap step specific services\n this.stepSpecificServices[step.stepName] = {\n module: await moduleResolver((step as Step<ModuleStepData>).data.module),\n };\n stepPromises.push(\n moduleStepService.init(step as Step<ModuleStepData>, this, this.reloadedState),\n );\n break;\n case StepType.Picture:\n stepPromises.push(\n pictureStepService.init(step as Step<PictureStepData>, this, this.reloadedState),\n );\n break;\n case StepType.Question:\n stepPromises.push(\n questionStepService.init(step as Step<QuestionStepData>, this, this.reloadedState),\n );\n break;\n case StepType.Shape:\n stepPromises.push(shapeStepService.init(step as Step<ShapeStepData>, this, this.reloadedState));\n break;\n case StepType.Text:\n stepPromises.push(textStepService.init(step as Step<TextStepData>, this, this.reloadedState));\n break;\n default:\n break;\n }\n }\n }\n\n // Settle all parallel logic.\n const stepCwfs = (await Promise.allSettled<CommandWithFollowup | null>(stepPromises)).map((result) => {\n if (result.status === \"rejected\") {\n throw new Error(`Step initialization failed: ${result.reason}`);\n }\n return result.value;\n });\n\n // Map all non-null commands/followups to lists.\n const commands = stepCwfs.flatMap((cwf) => (cwf?.command ? [cwf.command] : []));\n const followups = stepCwfs.flatMap((cwf) => (cwf?.followup ? [cwf.followup] : []));\n\n // Execute all commands in a single batch\n if (commands && commands.length > 0) this.commandContext.apply(new GroupCommand(commands), true);\n for (const followup of followups) await followup();\n\n // Process any followup conditions\n // A step will produce followup actions when a change has occured. To ensure\n // any conditions that have become true are actioned, we run once again.\n if (followups.length > 0) {\n await this.ensureStepsAreLoaded();\n }\n\n // Notify listeners of changes.\n this.onInitChange();\n }\n\n private onConfirmChange() {\n this.confirmCallbacks.forEach((callback) => callback(this.confirmedDesign));\n }\n\n private onEditedChange() {\n this.editedCallbacks.forEach((callback) => callback(this.editedSteps));\n }\n\n private onElementsChange() {\n this.elementsCallbacks.forEach((callback) => callback(this.stepElements));\n }\n\n private onInformationResultChange() {\n this.informationResultCallbacks.forEach((callback) => callback(this.informationResults));\n }\n\n private onInitChange() {\n this.initCallbacks.forEach((callback) => callback(this.stepInitialised));\n }\n\n private onMakingAdjustmentsChange() {\n this.makingAdjustmentsCallback.forEach((callback) => {\n callback(this.currentAdjustingStepId);\n });\n }\n\n private onMandatoryChange() {\n this.mandatoryCallbacks.forEach((callback) => callback(this.mandatorySteps));\n }\n\n private onMetadataChange() {\n this.metadataCallbacks.forEach((callback) => {\n callback(this.stepMetadata);\n });\n }\n\n private async onSelectionChange() {\n const traversableScenes = await this.traversableScenes();\n for (const cb of this.selectionCallbacks) {\n cb({\n selectionCost: this.selectionCost,\n selections: this.stepSelections,\n traversableScenes,\n });\n }\n }\n\n private onStepSpecificStorageChange(stepName: string) {\n if (!Object.keys(this.stepSpecificStorageCallbacks).includes(stepName)) {\n this.stepSpecificStorageCallbacks[stepName] = [];\n }\n this.stepSpecificStorageCallbacks[stepName].forEach((callback) => callback(this.storage[stepName]));\n }\n\n private onStorageChange() {\n this.storageCallbacks.forEach((callback) => callback(this.storage));\n }\n\n private onValidationChange() {\n this.validationCallbacks.forEach((callback) => callback(this.validationErrors));\n }\n\n traversableScenes(): Promise<WorkflowScene[]> {\n return getRenderableRelevantScenes(this.allScenes, this.stepSelections, this.singleVariantsRenderable);\n }\n}\n","import { Asset, AssetType, VariantResource } from \"../../types\";\n\n/**\n * A wrapping component that provides a simple interface for interacting with a variant.\n */\nexport class Variant {\n private readonly variantData: VariantResource;\n\n constructor(variant: VariantResource) {\n this.variantData = variant;\n }\n\n getType(): AssetType | undefined {\n return this.variantData.asset?.type;\n }\n\n /**\n * @returns The unique identifier for the variant.\n */\n getId(): string {\n return this.variantData.id!;\n }\n\n /**\n * @returns The configured name of the variant. Generally a human readable value.\n */\n getName(): string {\n return this.variantData.name;\n }\n\n /**\n * @returns The price modifier for this variant. This is the amount that will be added to the base price of the product.\n */\n getPriceFormatted(locales?: Intl.LocalesArgument, options?: Intl.NumberFormatOptions | undefined): string {\n return this.variantData.priceModifier.toLocaleString(locales ? locales : \"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n ...options,\n });\n }\n\n /**\n * @returns The price modifier for this variant. This is the amount that will be added to the base price of the product.\n * Presented in subunits of the currency of the option. For example, if the option is configured to use USD, the price modifier will be in cents.\n */\n getPrice(): number {\n return this.variantData.priceModifier;\n }\n\n /**\n * @returns The URL for the base asset resource configured on this variant\n */\n getAsset(): string | undefined {\n return this.variantData.asset?.versions?.find((v) => v.name === \"cdn\")?.link;\n }\n\n /**\n * @returns The URL for the base asset resource configured on this variant\n */\n getAssetResource(): Asset | undefined {\n return this.variantData.asset;\n }\n\n /**\n * @returns The URL for a thumbnail resource configured on this variant.\n */\n getThumbnail(): string | undefined {\n // Thumbnails are uploaded high res. We generate thumbnails internally. First we look\n // for this internally generated thumbnail. If it doesn't exist, we fall back to the original\n // thumbnail asset (Which is assumably going to be small anyway...)\n // NOTE: Certain assets such as SVG don't currently generate a thumb.\n const thumb = this.variantData.thumbnail?.versions?.find((v) => v.name === \"thumbnail\")?.link;\n const full = this.variantData.thumbnail?.fileLink;\n return thumb || full;\n }\n\n /**\n * @returns When this variant is configured to have a color, this will return the hex value for that color.\n */\n getColor(): string | undefined {\n return this.variantData.color;\n }\n\n /**\n * @returns True when the variant is the default for its containing option. False otherwise.\n */\n isDefault(): boolean {\n return !!this.variantData.default;\n }\n\n /**\n * @returns The underlying variant resource. Generally not needed but made available just incase.\n */\n getResource(): VariantResource {\n return this.variantData;\n }\n\n /**\n * @returns True when the variant is enabled. False otherwise.\n */\n isEnabled(): boolean {\n return this.variantData.enabled;\n }\n}\n","import { optionService } from \"../services/option\";\nimport { AnyStepData, AspectType, OptionResource, Step, StepType } from \"../types\";\nimport { MisconfigurationError } from \"../util/exception\";\nimport { WorkflowManager } from \"../WorkflowManager\";\nimport { Variant } from \"./resource/variant\";\n\n/**\n * Steps that support custom color variants should implement the following interface to\n * add the behavior in the way that makes sense to the step.\n */\nexport interface CustomColorSupport {\n /**\n * Allows for setting a custom color when the custom variant is selected. Will\n * throw when a non-custom variant is selected.\n */\n setCustomColor(color: string);\n /**\n * Get the custom color that is currently set on the step.\n */\n getCustomColor(): string;\n}\n\n/**\n * A StepHandle allows for managing the state of a specific step in a workflow. This class\n * abstracts away the complexities of dealing with a step directly and allows for using high level\n * concepts instead of dealing with the underlying data structures.\n */\nexport abstract class StepHandle<T extends AnyStepData> {\n /**\n * Stores whether or not the step is currently updating.\n */\n private static readonly updateState: Map<string, boolean> = new Map<string, boolean>();\n /**\n * Access to the workflow manager this step is contained by.\n */\n protected readonly manager: WorkflowManager;\n /**\n * The step metadata, useful for determining logic based on configuration.\n */\n protected readonly step: Step<T>;\n /**\n * The tags set against this step.\n */\n protected readonly tags: string[];\n\n constructor(manager: WorkflowManager, step: Step<T>, tags: string[]) {\n this.manager = manager;\n this.step = step;\n this.tags = tags;\n }\n\n /**\n * Set the current update state of this step. All step handles pointing to this step will\n * see this value.\n * @param value The new value\n */\n protected setUpdateState(value: boolean) {\n StepHandle.updateState.set(\n `${this.step.stepName}-${this.manager.getWorkflowExperience().getTransaction().id}`,\n value,\n );\n }\n\n /**\n * @returns Gets the current update state of this step. All step handles for this step will see this value.\n */\n protected getUpdateState() {\n return !!StepHandle.updateState.get(\n `${this.step.stepName}-${this.manager.getWorkflowExperience().getTransaction().id}`,\n );\n }\n\n /**\n * Gets the currently selected variant, or undefined if no variant is selected.\n */\n getCurrentVariant() {\n const selections = this.manager.getWorkflowSelections();\n const stepSelections = selections[this.step.stepName];\n const variantResource = stepSelections?.selections[0];\n if (!variantResource) return undefined;\n return new Variant(variantResource);\n }\n\n /**\n * @returns A list of valid variants for this step. Does not include disabled variants.\n */\n async getAvailableVariants(): Promise<Variant[]> {\n const variants = await this.getAllVariants();\n return variants.filter((v) => v.isEnabled()) || [];\n }\n\n /**\n * @returns A list of all variants for this step, including disabled ones.\n */\n async getAllVariants(): Promise<Variant[]> {\n if (!this.step.option?.id) return []; // If no option then zero variants.\n // If the workflow was requested with the option data included in the step, use that instead of making an API call\n if (this.step.option.variants) {\n return (this.step.option.variants || []).map((v) => new Variant(v)) || [];\n }\n // Otherwise we lazy load the the steps variants when requested\n const option = await optionService.getOption(this.step.option?.id);\n if (!option) throw new Error(\"Option not found, cannot fetch variants.\");\n return (option.variants || []).map((v) => new Variant(v)) || [];\n }\n\n /**\n * Most step types have a base option type that variants can be selected for.\n * Selects a specific variant for this step. This will execute all required changes to\n * the design and update the metadata to include the new selection. Any conditions\n * that would be triggered will also be executed.\n */\n abstract selectVariant(variant: Variant): Promise<void>;\n\n /**\n * @returns A unique identifier for this step within the workflow.\n */\n getId() {\n return this.step.stepName;\n }\n\n /**\n * @returns The name of the step\n */\n getName(): string {\n return this.step.stepTitle;\n }\n\n /**\n * @returns A message that can accompany the step name in UI components. Used to describe the purpose of the step in more detail.\n */\n getHelpText() {\n return this.step.helpText;\n }\n\n /**\n * @returns The type of the step handle.\n */\n getType(): StepType {\n return this.step.type;\n }\n\n /**\n * @returns The underlying data for this step. Favor using the step handle methods instead of this.\n */\n getRaw(): Step<T> {\n return this.step;\n }\n\n /**\n * @returns Returns all of the tags that are present on this step.\n */\n getTags(): string[] {\n return this.tags;\n }\n\n /**\n * @param tag The tag to check for.\n * @returns True if the step has the specified tag, false otherwise.\n */\n hasTag(tag: string): boolean {\n return this.tags.includes(tag) || false;\n }\n\n /**\n * @returns True if the step is required to be filled by the customer. False otherwise.\n */\n getMandatory() {\n return this.step.mandatory || false;\n }\n\n /**\n * @param type The AspectType to fetch the value for.\n * @returns A boolean indicating whether this step should override Global Properties.\n * Only relevant when the Workflow Experience is associated with a Bundle that is using Global Properties,\n * and when this step is associated with one or more Global Property Aspects.\n */\n getOverrideGlobalPropertyConfiguration(type: AspectType): boolean {\n const map = this.manager.getStepStorage(this.step.stepName)?.overrideGlobalConfigurations ?? {};\n return map[type.toString()] ?? false;\n }\n\n /**\n * Sets whether or not this step should override Global Properties.\n * Only relevant when the Workflow Experience is associated with a Bundle that is using Global Properties,\n * and when this step is associated with one or more Global Property Aspects.\n * @param type The AspectType to override.\n */\n setOverrideGlobalPropertyConfiguration(type: AspectType, value: boolean) {\n const map = this.manager.getStepStorage(this.step.stepName)?.overrideGlobalConfigurations ?? {};\n this.manager.updateStorage(this.step.stepName, {\n overrideGlobalConfigurations: { ...map, [type.toString()]: value },\n });\n }\n\n /**\n * Retrieves the identifiers of all of the configured aspects for the specified Global Property Configuration.\n * @param configurationId The ID of the Global Property Configuration. You can usually find this with `bundle.getGlobalPropertyConfiguration()?.id`\n * @returns An array of strings matching the keys of all the Global Property Aspects in the Configuration that this step is configured to use.\n */\n getGlobalPropertyAspects(configurationId: string) {\n return (\n this.step.globalPropertyAspectConfigurations\n ?.filter((c) => c.globalPropertyConfigurationId === configurationId && c.aspectName)\n .map((c) => c.aspectName!) ?? []\n );\n }\n\n /**\n * Fires any configured animations on the 3D preview for this step.\n * This includes camera & model animations. If the preview is unavailable\n * this function will do nothing.\n */\n executeAnimations(immediate?: boolean) {\n const preview = this.manager.getPreviewService();\n const modelContainer = this.manager.getModelContainer();\n const modelAnimation = (this.step.data as any).modelAnimation;\n const lookAtAnimation = (this.step.data as any).lookAtAnimation;\n if (preview) {\n lookAtAnimation && preview.executeCameraAnimation(lookAtAnimation);\n } else {\n console.warn(\"No preview service available, cannot execute camera animations.\");\n }\n if (modelContainer) {\n modelAnimation && modelContainer.executeAnimation(modelAnimation, immediate);\n } else {\n console.warn(\"No model container available, cannot execute model animations.\");\n }\n }\n}\n","import { StepHandle } from \"..\";\nimport { findElement } from \"../../LayoutsState\";\nimport { optionService } from \"../../services/option\";\nimport { illustrationStepService } from \"../../services/steps/illustration\";\nimport { ColorDefinition, IllustrationElement, IllustrationStepData, Step } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { Variant } from \"../resource/variant\";\n\nexport class IllustrationStepHandle extends StepHandle<IllustrationStepData> {\n constructor(manager: WorkflowManager, step: Step<IllustrationStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n /**\n * Allows for select a vector from the available vectors configured on this steps base option.\n * @param variant The new vector variant to use for this step.\n * @returns A promise that can be awaited to know when the new vector asset has been updated on the design.\n */\n async selectVariant(variant: Variant) {\n if (this.getUpdateState()) return; // Don't update this step if in the middle of updating it.\n if (this.getCurrentVariant() === variant) return;\n return illustrationStepService.selectVariant(\n this.step,\n variant.getResource(),\n this.manager.getRegionElements(this.step.stepName) || [],\n (v) => this.setUpdateState(v),\n this.manager,\n );\n }\n\n /**\n * Get the colors that are in the illustration.\n * @returns A list of color definitions that are currently applied to the illustration.\n */\n getColors() {\n const regionEls = this.manager.getRegionElements(this.step.stepName) || [];\n if (regionEls.length === 0) return;\n const layoutElement = findElement(regionEls[0].id, this.manager.getAllLayoutData()) as IllustrationElement;\n const elementColors = layoutElement.colors;\n\n // For illustrations with asset configs, return one color per channel.\n const asset = this.getCurrentVariant()?.getAssetResource();\n const assetConfiguration = asset?.assetConfiguration;\n const defaultColorVariants = assetConfiguration?.defaultColorVariants || [];\n if (defaultColorVariants.length !== 0) {\n const colors: { [key: string]: ColorDefinition } = {};\n defaultColorVariants.forEach((item) => {\n // Only include channel numbers that are in use.\n const cn = assetConfiguration!.channelNumbers.find((cn) => cn.number === item.channelNumber);\n if (cn) {\n const hex = cn.id.replace(/\\W/g, \"\");\n colors[item.channelNumber] = { browserValue: elementColors[hex]?.browserValue || \"\" };\n }\n });\n return colors;\n }\n\n // For the standard case, return one color per color in the illustration.\n try {\n return elementColors;\n } catch (e) {\n console.error(e);\n }\n }\n\n /**\n * Set color for the illustration.\n */\n setColor(key: string, value: string, pmsValue?: string) {\n const newFillMap = new Map<string, string | ColorDefinition>();\n\n // For illustrations with asset configs, we have to map the channel number to colors in the illustration.\n const asset = this.getCurrentVariant()?.getAssetResource();\n const assetConfiguration = asset?.assetConfiguration;\n const defaultColorVariants = assetConfiguration?.defaultColorVariants || [];\n if (defaultColorVariants.length !== 0) {\n assetConfiguration!.channelNumbers.forEach((item) => {\n if (item.number.toString() === key) {\n const hex = item.id.replace(/\\W/g, \"\");\n if (pmsValue) {\n newFillMap.set(hex, { browserValue: value, pmsValue });\n } else {\n newFillMap.set(hex, value);\n }\n }\n });\n } else {\n // The standard case.\n if (pmsValue) {\n newFillMap.set(key, { browserValue: value, pmsValue });\n } else {\n newFillMap.set(key, value);\n }\n }\n\n return illustrationStepService.changeColors(\n this.step,\n this.manager.getRegionElements(this.step.stepName),\n this.manager,\n newFillMap,\n );\n }\n\n async getColorOption() {\n return await optionService.ensureFullOption(this.step.data.colorOption);\n }\n\n getAvailableColors() {\n if (!this.step.data.colorPickerEnabled) {\n return Promise.resolve([]);\n }\n return illustrationStepService.availableColors(this.step, this.manager);\n }\n\n isColorPickerEnabled() {\n return this.step.data.colorPickerEnabled ?? false;\n }\n\n isPMSPickerEnabled() {\n return this.step.data.pmsPickerEnabled ?? false;\n }\n\n isVariantSearchEnabled(): boolean {\n return this.step.data.enableVariantSearch ?? false;\n }\n}\n","import { StepHandle } from \"..\";\nimport { materialStepService } from \"../../services/steps/material\";\nimport { MaterialStepData, Step } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { Variant } from \"../resource/variant\";\n\nexport class MaterialStepHandle extends StepHandle<MaterialStepData> {\n constructor(manager: WorkflowManager, step: Step<MaterialStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n selectVariant(variant: Variant) {\n return materialStepService.selectVariant(this.step, variant.getResource(), this.manager, (val) =>\n this.setUpdateState(val),\n );\n }\n}\n","import { StepHandle } from \"..\";\nimport { modelStepService, WorkflowManager } from \"../..\";\nimport { ModelStepData, Step } from \"../../types\";\nimport { Variant } from \"../resource/variant\";\n\nexport class ModelStepHandle extends StepHandle<ModelStepData> {\n constructor(manager: WorkflowManager, step: Step<ModelStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n selectVariant(variant: Variant) {\n return modelStepService.selectVariant(this.step, variant.getResource(), this.manager, (v) =>\n this.setUpdateState(v),\n );\n }\n}\n","import { StepHandle } from \"..\";\nimport { pictureStepService } from \"../../services/steps/picture\";\nimport { PictureStepData, Step } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { Variant } from \"../resource/variant\";\n\nexport class PictureStepHandle extends StepHandle<PictureStepData> {\n constructor(manager: WorkflowManager, step: Step<PictureStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n /**\n * Allows the user to select an image variant from the available variants configured on this steps base option.\n * @param variant The new image variant to use.\n * @returns A promise that can be awaited to ensure the new image asset has been updated on the design.\n */\n selectVariant(variant: Variant) {\n return pictureStepService.selectVariant(this.step, variant.getResource(), this.manager, (v) =>\n this.setUpdateState(v),\n );\n }\n\n isVariantSearchEnabled(): boolean {\n return this.step.data.enableVariantSearch ?? false;\n }\n}\n","import { StepHandle } from \"..\";\nimport { questionStepService } from \"../../services/steps/question\";\nimport { QuestionStepData, Step } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { Variant } from \"../resource/variant\";\n\nexport class QuestionStepHandle extends StepHandle<QuestionStepData> {\n constructor(manager: WorkflowManager, step: Step<QuestionStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n async selectVariant(variant: Variant) {\n if (!variant.getId()) {\n throw new Error(\"Unable to select variant with a null ID\");\n }\n await questionStepService.selectVariant(this.step, variant.getId(), this.manager);\n }\n\n /**\n * The way that this step expects to be rendered.\n */\n getDisplayType() {\n return (this.step.data as any).displayType || this.step.option?.displayType;\n }\n}\n","import { CustomColorSupport, StepHandle } from \"..\";\nimport { shapeStepService } from \"../../services/steps/shape\";\nimport { ColorOption, ShapeStepData, Step } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\nimport { Variant } from \"../resource/variant\";\n\nexport class ShapeStepHandle extends StepHandle<ShapeStepData> implements CustomColorSupport {\n constructor(manager: WorkflowManager, step: Step<ShapeStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n selectVariant(variant: Variant) {\n const colorVariant = variant.getResource();\n return shapeStepService.selectVariant(\n this.step,\n {\n fill: colorVariant.color,\n stroke: colorVariant.color,\n variant: colorVariant,\n },\n this.manager.getRegionElements(this.step.stepName) || [],\n this.manager,\n );\n }\n\n /**\n * Sets the color of the shape.\n * @param color The color option to use.\n * @returns A promise resolving when the color has changed in the design.\n * @deprecated The shape step can now pass through colors returned by getColors via selectVariant. Please swap setColor for selectVariant.\n */\n setColor(color: ColorOption) {\n return shapeStepService.selectVariant(\n this.step,\n color,\n this.manager.getRegionElements(this.step.stepName) || [],\n this.manager,\n );\n }\n\n /**\n * Get available colors for the shape.\n * @returns A list of color definitions that are currently applied to the illustration.\n */\n getColors() {\n return shapeStepService.availableColours(this.step);\n }\n\n /**\n * Allows for setting a custom color when the custom variant is selected. Will\n * throw when a non-custom variant is selected.\n */\n setCustomColor(color: string) {\n if (this.getCurrentVariant()?.getColor() !== \"#custom\") {\n console.warn(\n `setting custom color for step ${this.step.stepName} but color is ${this.getCurrentVariant()?.getColor()}`,\n );\n }\n return shapeStepService.setCustomColor(color, this.step, this.manager);\n }\n\n getCustomColor(): string {\n if (this.getCurrentVariant()?.getColor() !== \"#custom\") {\n console.warn(\n `setting custom color for step ${this.step.stepName} but color is ${this.getCurrentVariant()?.getColor()}`,\n );\n }\n const color = this.manager.getStepStorage(this.step.stepName)?.colour;\n if (!color)\n throw new Error(\n `Color not available on step ${this.step.stepName}. Set a default on the workflow to fix this.`,\n );\n return color;\n }\n}\n","import { CustomColorSupport, StepHandle } from \"..\";\nimport { TextErrorData, textStepService } from \"../../services/steps/text\";\nimport { ColorOption, Step, TextFillImage, TextStepData, TextStepStorage } from \"../../types\";\nimport { renderTextTemplateForWorkflow } from \"../../util/text\";\nimport { WorkflowManager, InformationMessageType } from \"../../WorkflowManager\";\nimport { Variant } from \"../resource/variant\";\n\nexport interface TextChangeResult {\n /**\n * The text of the input field.\n */\n input: string;\n\n /**\n * Data that can be used by the theme to decide what helper text should be.\n */\n helperData: {\n charactersRemaining?: number;\n };\n\n /**\n * Data that can be used by the theme to decide what error text should be.\n */\n errorData?: TextErrorData;\n}\n\nexport class TextStepHandle extends StepHandle<TextStepData> implements CustomColorSupport {\n constructor(manager: WorkflowManager, step: Step<TextStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n /**\n * Allows for select a font from the available fonts configured on this steps base option.\n * @param variant The font variant to use.\n */\n async selectVariant(variant: Variant) {\n await textStepService.selectVariant(\n this.step,\n variant.getResource(),\n this.manager,\n (error) => {\n if (error) {\n this.manager.setInformationResults([\n ...this.manager.getInformationResults(),\n {\n message: error,\n messageType: InformationMessageType.Error,\n stepID: this.step.stepName,\n },\n ]);\n } else {\n const results = this.manager.getInformationResults().filter((r) => r.stepID !== this.step.stepName);\n this.manager.setInformationResults(results);\n }\n },\n () => {\n // noop\n },\n );\n }\n\n /**\n * @returns A list of colors that can be used to fill the text.\n */\n async getAvailableFillColors(): Promise<ColorOption[]> {\n if (!this.step.data.colorPickerEnabled) {\n return [];\n }\n return textStepService.availableFillColors(this.step);\n }\n\n /**\n * Changes the fill of text related to this step to the new fill value.\n * @param fill A new fill value to use.\n */\n async setFillColor(fill: ColorOption) {\n const stepElements = this.manager.getRegionElements(this.step.stepName);\n await textStepService.changeFillColor(this.step, fill, stepElements, this.manager);\n }\n\n /**\n * Gets the color currently applied to the element.\n */\n getFillColor() {\n return this.manager.getStepStorage(this.step.stepName)?.color || \"#000000\";\n }\n\n getAvailableFillImages(): Promise<TextFillImage[]> {\n return textStepService.availableFillImages(this.step);\n }\n\n async setFillImage(fillImage: TextFillImage) {\n const stepElements = this.manager.getRegionElements(this.step.stepName);\n await textStepService.changeFillImage(this.step, fillImage, stepElements, this.manager);\n }\n\n getFillImage(): TextFillImage | undefined {\n return this.manager.getStepStorage(this.step.stepName)?.fillImage;\n }\n\n getAlignment(): string | undefined {\n const elements = textStepService.findLayoutElements(this.manager, this.step);\n return elements?.[0].align;\n }\n\n setAlignment(alignment: \"left\" | \"center\" | \"right\") {\n const stepElements = this.manager.getRegionElements(this.step.stepName);\n textStepService.changeAlignment(this.step, alignment, stepElements, this.manager);\n }\n\n /**\n * When true & the step has replaceable text configured the user will be\n * abled to edit the entire text string including the non-replaceable text.\n * @param shouldCustomizeAll When true the user can configure the entire text string.\n */\n setFullTextCustomization(shouldCustomizeAll: boolean): TextChangeResult {\n const inputText = this.manager.getStepStorage(this.step.stepName)?.inputText || \"\";\n\n const customiseableText =\n this.step.data.replaceableText !== undefined\n ? this.step.data.replaceableText.replace(\"{{}}\", inputText)\n : inputText;\n\n const text = shouldCustomizeAll ? customiseableText : this.step.data.defaultText;\n this.manager.updateStorage(this.step.stepName, {\n customiseAllText: shouldCustomizeAll,\n text,\n defaultCleared: false,\n });\n const result = this.setText(text);\n return result;\n }\n\n /**\n * Changes the text value of text related to this step to a new value.\n * @param userInput Input from the user.\n */\n setText(userInput: string): TextChangeResult {\n const result: TextChangeResult = {\n input: userInput,\n helperData: {},\n };\n\n // Find all related elements in the design and update them. Return immediately if none are found.\n const layoutElements = textStepService.findLayoutElements(this.manager, this.step);\n // Filter any unsupported characters from the input.\n const filteredUserInput = textStepService.filterUnsupportedCharacters(userInput, layoutElements[0]?.fontData);\n\n // Whilst the maximum length of user input is not exceeded, set the updated input value.\n const inputLength = renderTextTemplateForWorkflow(filteredUserInput, this.manager).length;\n const maxLengthExceeded =\n !!this.step.data && !!this.step.data.maxLength && inputLength > this.step.data.maxLength;\n if (!maxLengthExceeded) {\n result.input = filteredUserInput;\n }\n\n // Update storage.\n const regionless = layoutElements.length <= 0;\n const newStorage = regionless\n ? { inputText: filteredUserInput, text: filteredUserInput }\n : { inputText: filteredUserInput };\n this.manager.updateStorage(this.step.stepName, newStorage);\n\n // Calculate the text that will be metadata if no errors.\n const storage = this.manager.getStepStorage(this.step.stepName) as TextStepStorage;\n const candidateMetadata = textStepService.getProcessedInput(\n filteredUserInput,\n this.step.data,\n storage?.customiseAllText ?? false,\n );\n\n if (regionless) {\n // Update metadata if new text doesn't cause errors.\n if (!maxLengthExceeded) {\n this.manager.updateMetadata(this.step.stepName, {\n text: candidateMetadata,\n });\n }\n } else {\n // Request the text step service to update the text in the design.\n const { command, errorData, helperData } = textStepService.updateInputText(\n filteredUserInput,\n layoutElements,\n this.step,\n this.manager,\n );\n command && this.manager.getCommandDispatcher()(command);\n\n result.helperData = helperData;\n result.errorData = errorData;\n\n // Update metadata if new text doesn't cause errors.\n if (!maxLengthExceeded && !errorData) {\n this.manager.updateMetadata(this.step.stepName, {\n text: candidateMetadata,\n });\n }\n }\n\n return result;\n }\n\n /**\n * Gets the text currently applied to the elements of this step.\n */\n getText() {\n const defaultText = this.step.data.defaultText;\n const storage = this.manager.getStepStorage(this.step.stepName);\n if (defaultText && storage?.defaultCleared !== undefined && !storage?.defaultCleared) {\n return defaultText;\n }\n return this.manager.getStepStorage(this.step.stepName)?.text || \"\";\n }\n\n isReplaceable() {\n return this.step.data.userCanReplaceText;\n }\n\n /**\n * @returns True if the step allows new lines in the text input.\n */\n newLinesSupported() {\n return this.step.data.allowNewlines || false;\n }\n\n /**\n * Inform the step that now is the time to\n * clear default text if it should do so.\n * Returns a text change rwsult if a clear occurred.\n */\n clearDefaultTextIfNecessary(): TextChangeResult | undefined {\n const storage = this.manager.getStepStorage(this.step.stepName);\n if (!storage?.defaultCleared && this.step.data.deleteDefaultOnFocus) {\n const result = this.setText(\"\");\n this.manager.updateStorage(this.step.stepName, { defaultCleared: true, inputText: \"\" });\n const layoutElements = textStepService.findLayoutElements(this.manager, this.step);\n textStepService.updateInputText(\"\", layoutElements, this.step, this.manager);\n return result;\n }\n }\n\n hasColorPicker() {\n return this.step.data.colorPickerEnabled;\n }\n\n getRegions() {\n return this.step.data.regions;\n }\n\n /**\n * Return the maximum characters allowed for\n * this step, or undefined if there is no limit.\n */\n getCharacterLimit(): number | undefined {\n return this.step.data.maxLength;\n }\n\n /**\n * Return the remaining amount of characters that\n * the user is allowed to add, or undefined if there is no limit.\n */\n getCharactersRemaining(): number | undefined {\n const limit = this.step.data.maxLength;\n if (limit === undefined) {\n return undefined;\n }\n const text = renderTextTemplateForWorkflow(this.getText(), this.manager);\n return limit - text.length;\n }\n\n setCustomColor(_color: string) {\n throw new Error(\"Custom color support is not yet available on text. Check back soon.\");\n }\n\n getCustomColor(): string {\n throw new Error(\"Custom color support is not yet available on text. Check back soon.\");\n }\n\n /**\n * @returns A list of colors that can be used for the text's outline.\n */\n async getAvailableStrokeColors(): Promise<ColorOption[]> {\n if (!this.step.data.strokeEnabled) {\n return [];\n }\n return textStepService.availableStrokeColors(this.step);\n }\n\n getStrokeColor(): string {\n return this.manager.getStepStorage(this.step.stepName)?.strokeColor?.browserValue || \"#000000\";\n }\n\n /**\n * Changes the stroke of text related to this step to the new stroke value.\n * @param stroke A new stroke value to use.\n */\n async setStrokeColor(stroke: ColorOption | undefined) {\n const stepElements = this.manager.getRegionElements(this.step.stepName);\n await textStepService.changeStrokeColor(this.step, stroke, stepElements, this.manager);\n }\n}\n","import { StepHandle } from \"..\";\nimport { InformationStepData, Step } from \"../../types\";\nimport { WorkflowManager } from \"../../WorkflowManager\";\n\nexport class InformationStepHandle extends StepHandle<InformationStepData> {\n constructor(manager: WorkflowManager, step: Step<InformationStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n async selectVariant() {\n // Noop\n }\n\n /**\n * The way that this step expects to be rendered.\n */\n getContent() {\n return this.step.data.content;\n }\n}\n","import { StepHandle } from \"..\";\nimport { digitalContentStepService, WorkflowManager } from \"../..\";\nimport { DigitalContentStepData, Step, Asset } from \"../../types\";\n\n/**\n * The digital content step allows for associating uploaded content with a QR code. This code\n * can be displayed on the users design such as in a gift card and people can access\n * the hosted content by scanning the QR.\n */\nexport class DigitalContentStepHandle extends StepHandle<DigitalContentStepData> {\n constructor(manager: WorkflowManager, step: Step<DigitalContentStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n async selectVariant() {\n //noop\n }\n\n /**\n * Returns a preview URL used to show the generated QR code in your UI.\n */\n getPreviewURL(): string {\n return this.manager.getStepStorage(this.step.stepName)?.videoUrl || \"\";\n }\n\n /**\n * Turns an asset into a QR code that can be used to access the content.\n * @param asset The asset to use for the QR code.\n * @returns The final URL string for the QR code.\n */\n async selectVideo(asset: Asset): Promise<string> {\n return digitalContentStepService.regenerateQRCode(\n this.manager.getRegionElements(this.step.stepName),\n asset.key!,\n this.manager,\n this.step,\n );\n }\n}\n","import { StepHandle } from \"..\";\nimport { InformationMessageType, moduleStepService, WorkflowManager } from \"../..\";\nimport { ModuleStepData, Step } from \"../../types\";\nimport { renderTextTemplateForWorkflow } from \"../../util/text\";\n\nexport class ModuleStepHandle extends StepHandle<ModuleStepData> {\n constructor(manager: WorkflowManager, step: Step<ModuleStepData>, tags: string[]) {\n super(manager, step, tags);\n }\n\n async selectVariant() {\n console.info(\"Text Modules don't support variants.\");\n //noop\n }\n\n /**\n * Return the remaining amount of characters that\n * the user is allowed to add, or undefined if there is no limit.\n */\n getCharactersRemaining(): number | undefined {\n const limit = this.step.data.maxLength;\n if (limit === undefined) {\n return undefined;\n }\n const text = renderTextTemplateForWorkflow(this.getText(), this.manager);\n return limit - text.length;\n }\n\n /**\n * Return the maximum characters allowed for\n * this step, or undefined if there is no limit.\n */\n getCharacterLimit(): number | undefined {\n return this.step.data.maxLength;\n }\n\n getText(): string {\n return this.manager.getStepStorage(this.step.stepName)?.text || \"\";\n }\n\n setText(value: string) {\n moduleStepService.changeText(this.step, value, this.manager, (error) => {\n if (error) {\n const errors = [\n ...this.manager.getInformationResults(),\n {\n message: error,\n messageType: InformationMessageType.Error,\n stepID: this.step.stepName,\n },\n ];\n this.manager.setInformationResults(errors);\n } else {\n const results = this.manager.getInformationResults().filter((r) => r.stepID !== this.step.stepName);\n this.manager.setInformationResults(results);\n }\n });\n }\n}\n","import { FrameStepHandle } from \"..\";\nimport { UnhandledBehaviorError } from \"../util/exception\";\nimport { WorkflowManager } from \"../WorkflowManager\";\nimport { IllustrationStepHandle } from \"./steps/illustration\";\nimport { MaterialStepHandle } from \"./steps/material\";\nimport { ModelStepHandle } from \"./steps/model\";\nimport { PictureStepHandle } from \"./steps/picture\";\nimport { QuestionStepHandle } from \"./steps/question\";\nimport { ShapeStepHandle } from \"./steps/shape\";\nimport { TextStepHandle } from \"./steps/text\";\nimport { InformationStepHandle } from \"./steps/information\";\nimport { DigitalContentStepHandle } from \"./steps/digitalContent\";\nimport { ModuleStepHandle } from \"./steps/module\";\nimport { AnyStepData, DigitalContentStepData, FrameStepData, IllustrationStepData, InformationStepData, MaterialStepData, ModelStepData, ModuleStepData, PictureStepData, QuestionStepData, ShapeStepData, Step, StepType, TextStepData } from \"../types\";\n\n/**\n * A factory that generates the correct concrete StepHandle implementation\n * for a given step.\n */\nexport class StepHandleFactory {\n static get(manager: WorkflowManager, step: Step<AnyStepData>) {\n switch (step.type) {\n case StepType.DigitalContent:\n return new DigitalContentStepHandle(manager, step as Step<DigitalContentStepData>, manager.getStepTags(step.stepName));\n case StepType.Information:\n return new InformationStepHandle(manager, step as Step<InformationStepData>, manager.getStepTags(step.stepName));\n case StepType.Question:\n return new QuestionStepHandle(manager, step as Step<QuestionStepData>, manager.getStepTags(step.stepName));\n case StepType.Text:\n return new TextStepHandle(manager, step as Step<TextStepData>, manager.getStepTags(step.stepName));\n case StepType.Illustration:\n return new IllustrationStepHandle(manager, step as Step<IllustrationStepData>, manager.getStepTags(step.stepName));\n case StepType.Picture:\n return new PictureStepHandle(manager, step as Step<PictureStepData>, manager.getStepTags(step.stepName));\n case StepType.Shape:\n return new ShapeStepHandle(manager, step as Step<ShapeStepData>, manager.getStepTags(step.stepName));\n case StepType.Material:\n return new MaterialStepHandle(manager, step as Step<MaterialStepData>, manager.getStepTags(step.stepName));\n case StepType.Model:\n return new ModelStepHandle(manager, step as Step<ModelStepData>, manager.getStepTags(step.stepName));\n case StepType.Frame:\n return new FrameStepHandle(manager, step as Step<FrameStepData>, manager.getStepTags(step.stepName));\n case StepType.Module:\n return new ModuleStepHandle(manager, step as Step<ModuleStepData>, manager.getStepTags(step.stepName));\n default:\n throw new UnhandledBehaviorError(`Step type ${step.type} not yet supported in Core SDK`);\n }\n }\n}\n","import { confirmWorkflowStates } from \"../query\";\nimport { graphQlManager } from \"../services/server\";\nimport {\n Product,\n DesignCreationMessage,\n SelectedVariants,\n Transaction,\n DesignDetails,\n DesignWorkflowMetadata,\n ExportedData,\n FrameMetadata,\n IllustrationMetadata,\n ModuleMetadata,\n TextMetadata,\n Design,\n Workflow,\n Step,\n AnyStepData,\n FrameStepData,\n IllustrationStepData,\n ModuleStepData,\n TextStepData,\n ILayout,\n AssetType,\n} from \"../types\";\nimport { WorkflowManager, WorkflowSelections, WorkflowMetadata } from \"../WorkflowManager\";\nimport { persistenceService } from \"./persistence\";\nimport { UnhandledBehaviorError } from \"../util/exception\";\nimport { gql } from \"@apollo/client/core\";\nimport { assetService } from \"./asset\";\nimport { CommandState } from \"../CommandContext\";\nimport { fetch } from \"../util/crossplatform\";\nimport { optionService, SpiffCommerceClient } from \"..\";\nimport chunk from \"lodash.chunk\";\n\n/**\n * This file contains all the functions that contribute to the createDesign function.\n */\n\nconst createDesignTransactionFragment = gql`\n fragment CreateDesignTransaction on Transaction {\n id\n designName\n externalCartProductId\n externalCartProductVariantId\n externalDesignProductId\n externalDesignProductVariantId\n lastSyncedAt\n quantity\n previewImageLink\n priceModifierTotal\n workflowViewerLink\n workflowViewerReadOnlyLink\n integrationProduct {\n id\n additionalExternalProductId\n additionalExternalVariantId\n }\n designExternalVariants {\n id\n externalProductId\n externalProductVariantId\n }\n }\n`;\n\nconst createDesignsMutation = gql`\n ${createDesignTransactionFragment}\n mutation CreateDesigns($inputs: [DesignCreateInput]!) {\n designCreateMany(inputs: $inputs) {\n id\n sku\n transaction {\n ...CreateDesignTransaction\n }\n processExecution {\n id\n }\n }\n }\n`;\n\n// https://stackoverflow.com/a/69058154\nexport function isTokenExpired(token: string) {\n const expiry = JSON.parse(atob(token.split(\".\")[1])).exp;\n return Math.floor(new Date().getTime() / 1000) >= expiry;\n}\n\nconst createDesignsGqlCall = async (\n designDetails: DesignDetails[],\n spiffClient: SpiffCommerceClient,\n): Promise<undefined | Design[]> => {\n const extraHeaders: { [key: string]: string } = {};\n try {\n if (spiffClient) {\n const token = await spiffClient.loggedInBearerToken();\n extraHeaders[\"Authorization\"] = `Bearer ${token}`;\n } else {\n throw new Error(); // Fall back to the amplify hack.\n }\n } catch (e) {\n // Hack to get the token from editor's amplify.\n const keys = Object.entries(localStorage);\n const jwtTokenKey =\n keys.find(([k, _]) => {\n return k.startsWith(\"CognitoIdentityServiceProvider\") && k.endsWith(\"idToken\");\n })?.[0] || \"\";\n const jwtToken = localStorage.getItem(jwtTokenKey);\n if (jwtToken && !isTokenExpired(jwtToken)) {\n extraHeaders[\"Authorization\"] = `Bearer ${jwtToken}`;\n }\n }\n if (await spiffClient.getBetaEnabled()) {\n extraHeaders[\"X-Spiff-Beta\"] = \"true\";\n }\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{ designCreateMany: Design[] }>({\n mutation: createDesignsMutation,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n inputs: designDetails.map((designDetail) => ({\n name: designDetail.name,\n layouts: designDetail.layouts,\n workflowId: designDetail.workflowId,\n transactionId: designDetail.transactionId,\n previewImage: designDetail.previewImage,\n useThreeDimPreview: designDetail.useThreeDimPreview,\n metadata: designDetail.metadata,\n selectedVariants: designDetail.selectedVariants,\n })),\n },\n context: {\n headers: extraHeaders,\n },\n });\n return response.data?.designCreateMany;\n};\n\nconst formatMetadata = (\n metadata: WorkflowMetadata,\n workflow: Workflow,\n forCart: boolean,\n): { [name: string]: string } => {\n const metadataObjectForStep = (step: Step<AnyStepData>) => {\n const formattedMetadata = {} as any;\n if (step.type === \"Frame\") {\n const stepMetadata = metadata[step.stepName] as FrameMetadata;\n const stepData = step.data as FrameStepData;\n if (!stepMetadata || !stepMetadata.image || (stepData.hideImageInCart && forCart)) {\n return formattedMetadata;\n }\n // TODO: Need to replace 'image' with locize key 'exportedData.image'\n formattedMetadata[`${step.stepTitle} ${\"image\"}`] = stepMetadata.image;\n }\n if (step.type === \"Illustration\") {\n const stepMetadata = metadata[step.stepName] as IllustrationMetadata;\n const stepData = step.data as IllustrationStepData;\n if (!stepMetadata || (stepData.hideColorsInCart && forCart) || !stepMetadata.colors) {\n return formattedMetadata;\n }\n if (stepMetadata.colors.length > 0) {\n const colorString = stepMetadata.colors.join(\", \").toUpperCase();\n // TODO: Need to replace 'colors' with locize key 'exportedData.colors'\n formattedMetadata[`${step.stepTitle} ${\"colors\"}`] = colorString;\n }\n }\n if (step.type === \"Module\") {\n const stepMetadata = metadata[step.stepName] as ModuleMetadata;\n const stepData = step.data as ModuleStepData;\n if (\n !stepMetadata ||\n stepMetadata.text === undefined ||\n stepMetadata.text === null ||\n (stepData.hideTextInCart && forCart)\n ) {\n return formattedMetadata;\n }\n // TODO: Need to replace 'text' with locize key 'exportedData.text'\n formattedMetadata[`${step.stepTitle} ${\"text\"}`] = stepMetadata.text;\n }\n if (step.type === \"Text\") {\n const stepMetadata = metadata[step.stepName] as TextMetadata;\n if (!stepMetadata) {\n return formattedMetadata;\n }\n const stepData = step.data as TextStepData;\n if (\n !stepData.hideTextInCart ||\n (!forCart && stepMetadata.text !== undefined && stepMetadata.text !== null)\n ) {\n // TODO: Need to replace 'text' with locize key 'exportedData.text'\n formattedMetadata[`${step.stepTitle} ${\"text\"}`] = stepMetadata.text;\n }\n if (stepMetadata.color && (!stepData.hideColorInCart || !forCart)) {\n // TODO: Need to replace 'color' with locize key 'exportedData.color'\n formattedMetadata[`${step.stepTitle} ${\"color\"}`] = stepMetadata.color;\n }\n if (stepMetadata.strokeColor && (!stepData.hideStrokeInCart || !forCart)) {\n formattedMetadata[`${step.stepTitle} ${\"stroke\"}`] = stepMetadata.strokeColor;\n }\n }\n return formattedMetadata;\n };\n\n const formattedMetadata = {};\n workflow.steps.forEach((step) => {\n Object.assign(formattedMetadata, metadataObjectForStep(step));\n });\n return formattedMetadata;\n};\n\n// Combine selections and metadata into exported data.\n// Items should be grouped by step in workflow order.\nconst prepareExportedData = (\n selections: SelectedVariants,\n workflow: Workflow,\n metadata?: WorkflowMetadata,\n designWorkflowMetadata?: DesignWorkflowMetadata,\n): ExportedData => {\n const exportedData = {} as any;\n let formattedMetadata: DesignWorkflowMetadata = {};\n if (metadata) {\n formattedMetadata = formatMetadata(metadata, workflow, false);\n } else if (designWorkflowMetadata) {\n formattedMetadata = designWorkflowMetadata;\n }\n\n const stepTitles = workflow.steps.map((s) => s.stepTitle);\n // https://stackoverflow.com/a/39272981\n const distinctStepTitles = stepTitles.filter((x, i, a) => a.indexOf(x) == i);\n for (const stepTitle of distinctStepTitles) {\n if (Object.keys(selections).includes(stepTitle)) {\n const selection = selections[stepTitle];\n const step = workflow.steps.find((step) => step.stepTitle === stepTitle);\n // TODO: Need to replace 'selection' with locize key 'exportedData.selection'\n exportedData[`${step?.stepTitle} ${\"selection\"}`] = {\n value: selection[0].name,\n priceModifier: selection[0].priceModifier,\n };\n }\n for (const key of Object.keys(formattedMetadata)) {\n if (\n [`${stepTitle} color`, `${stepTitle} colors`, `${stepTitle} text`, `${stepTitle} image`].includes(key)\n ) {\n exportedData[key] = {\n value: formattedMetadata[key],\n priceModifier: 0,\n };\n }\n }\n }\n\n return exportedData;\n};\n\nconst createDesignMessage = (\n transaction: Transaction,\n product: Product,\n workflow: Workflow,\n selectedVariants: SelectedVariants,\n generatedSku?: string,\n metadata?: { [stepName: string]: string },\n lineItemImageLink?: string,\n processExecutionId?: string,\n): DesignCreationMessage => {\n const baseCost = product.basePrice || 0;\n const optionsCost = transaction.priceModifierTotal || 0;\n const exportedData = prepareExportedData(selectedVariants, workflow, undefined, metadata);\n\n const ownerMap = persistenceService.getMap(\"transactionOwnerIds\") || new Map();\n const ownerId = ownerMap.get(transaction.id);\n\n const msgObject: DesignCreationMessage = {\n additionalExternalProductId: transaction.integrationProduct?.additionalExternalProductId,\n additionalExternalVariantId: transaction.integrationProduct?.additionalExternalVariantId,\n baseCost,\n designExternalVariants: transaction.designExternalVariants,\n designProductId: transaction.externalDesignProductId,\n designProductVariantId: transaction.externalDesignProductVariantId,\n event: \"onComplete\",\n exportedData,\n externalCartProductId: transaction.externalCartProductId,\n externalCartProductVariantId: transaction.externalCartProductVariantId,\n lineItemImageUrl: lineItemImageLink || \"\",\n optionsCost,\n processExecutionId,\n quantity: transaction.quantity,\n transactionId: transaction.id,\n transactionOwnerId: ownerId,\n weight: product.weight,\n workflowViewerLink: transaction.workflowViewerLink || \"\",\n workflowViewerReadOnlyLink: transaction.workflowViewerReadOnlyLink || \"\",\n };\n if (metadata) {\n msgObject.metadata = metadata;\n }\n if (selectedVariants) {\n msgObject.selectedVariants = selectedVariants;\n }\n if (generatedSku) {\n msgObject.sku = generatedSku;\n }\n return msgObject;\n};\n\nexport const createDesignDetails = async (\n workflowManager: WorkflowManager,\n workflow: Workflow,\n layouts: ILayout[],\n getReducerState: () => CommandState,\n transaction: Transaction,\n workflowSelections: WorkflowSelections,\n designName: string,\n createPreviewImage: (shouldRender3D?: boolean, transactionId?: string) => Promise<string | undefined>,\n workflowMetadata?: WorkflowMetadata,\n forceFlushState?: boolean,\n): Promise<{\n designDetails: DesignDetails;\n cartSelectionsWithPrices: SelectedVariants;\n cartMetadata: { [stepName: string]: string } | undefined;\n}> => {\n if (forceFlushState) {\n console.warn(\"State mismatch detected. Uploading known state explicitly\");\n console.warn(\"State Object:\", JSON.stringify(getReducerState()));\n await workflowManager.updateStateWithServerImmediate(getReducerState);\n console.log(\"Server state is undefined @ Workflow completion\"!);\n }\n\n const previewService = workflowManager.getPreviewService();\n const cameraOrientation = workflow?.finalizeStepConfig?.lookAtAnimation;\n const shouldUploadThreeDimPreview = previewService && workflow.showModelOnFinishStep && !!cameraOrientation;\n\n const cartMetadata = workflowMetadata && formatMetadata(workflowMetadata, workflow, true);\n const designMetadata = workflowMetadata && formatMetadata(workflowMetadata, workflow, false);\n\n const getSelections = async (forCart: boolean): Promise<[SelectedVariants, number]> => {\n const selectedVariants: SelectedVariants = {};\n let optionsCost = 0;\n if (Object.keys(workflowSelections).length > 0) {\n for (const stepId of Object.keys(workflowSelections)) {\n const stepSelections = workflowSelections[stepId];\n const step = workflow.steps.find((step) => step.stepName === stepId);\n for (let i = 0; i < stepSelections.selections.length; ++i) {\n const variant = stepSelections.selections[i];\n // Attach a selection if:\n // * these selections aren't for the cart; or\n // * the selection isn't configured to be hidden and there's\n // multiple variants for the step.\n if (step) {\n const stepOption = await optionService.getOptionForStep(step);\n if (\n !forCart ||\n (stepOption &&\n (stepOption.variants || []).length > 1 &&\n !(step.data as any).hideSelectionInCart &&\n !(step.data as any).hideSelectionsInCart)\n ) {\n const stepTitle = step.stepTitle;\n if (selectedVariants[stepTitle]) {\n selectedVariants[stepTitle].push({\n id: variant.id || \"\",\n name: variant.name,\n priceModifier: variant.priceModifier,\n });\n } else {\n selectedVariants[stepTitle] = [\n {\n id: variant.id || \"\",\n name: variant.name,\n priceModifier: variant.priceModifier,\n },\n ];\n }\n }\n }\n\n optionsCost += variant.priceModifier;\n }\n }\n }\n return [selectedVariants, optionsCost];\n };\n\n const [cartSelectionsWithPrices] = await getSelections(true);\n const cartSelections: { [key: string]: string[] } = Object.fromEntries(\n Object.keys(cartSelectionsWithPrices).map((key) => [key, cartSelectionsWithPrices[key].map((item) => item.id)]),\n );\n\n const [designSelectionsWithPrices] = await getSelections(false);\n const designSelections: { [key: string]: string[] } = Object.fromEntries(\n Object.keys(designSelectionsWithPrices).map((key) => [\n key,\n designSelectionsWithPrices[key].map((item) => item.id),\n ]),\n );\n\n // We are required to upload some assets now, we'll store their upload promises here\n // and await them at the end so we can get through as much computation as possible without\n // holding up the main thread.\n let previewImageUrl = await createPreviewImage(shouldUploadThreeDimPreview, transaction.id);\n if (previewImageUrl) {\n const previewImageBlob = await (await fetch(previewImageUrl)).blob();\n const asset = await assetService.uploadAsset(\n { name: `${transaction.id}-preview-image.png`, blob: previewImageBlob },\n AssetType.Image,\n true,\n false,\n );\n previewImageUrl = asset.fileLink!;\n }\n\n const assembleDesignDetails = () => {\n const designDetails: DesignDetails = {\n name: designName,\n layouts: layouts.map((layout) => {\n return {\n index: layout.index,\n panelId: layout.panelId,\n };\n }),\n workflowId: workflow.id,\n transactionId: transaction.id,\n useThreeDimPreview: !!shouldUploadThreeDimPreview,\n previewImage: previewImageUrl,\n };\n if (designMetadata) {\n const metadataList: { key: string; value: string }[] = [];\n for (const [key, value] of Object.entries(designMetadata)) {\n metadataList.push({ key, value });\n }\n designDetails.metadata = metadataList;\n }\n if (cartSelections) {\n const selectionsList: { key: string; ids: string[] }[] = [];\n for (const [key, value] of Object.entries(designSelections)) {\n selectionsList.push({ key, ids: value });\n }\n designDetails.selectedVariants = selectionsList;\n }\n return designDetails;\n };\n return {\n designDetails: assembleDesignDetails(),\n cartSelectionsWithPrices,\n cartMetadata,\n };\n};\n\nexport const createDesigns = async (\n options: {\n workflowManager: WorkflowManager;\n workflow: Workflow;\n layouts: ILayout[];\n getReducerState: () => CommandState;\n product: Product;\n transaction: Transaction;\n workflowSelections: WorkflowSelections;\n designName: string;\n workflowMetadata?: WorkflowMetadata;\n }[],\n createPreviewImage?: (shouldRender3D?: boolean, transactionId?: string) => Promise<string | undefined>,\n): Promise<DesignCreationMessage[]> => {\n // Flush any outstanding workflow manager state updates.\n await Promise.all(\n options.map(async (option) => {\n await option.workflowManager.outstandingRequestsPromise();\n }),\n );\n\n const getFailedStates = async (): Promise<string[]> => {\n const graphQlClient = graphQlManager.getShadowGraphqlClient();\n const transactions = await Promise.all(\n options.map(async (option) => ({\n id: option.transaction.id,\n hash: await option.workflowManager.getStateHash(),\n })),\n );\n const chunkSize = 100;\n const chunkedTransactions = chunk(transactions, chunkSize);\n const failedStates: string[] = [];\n for (const items of chunkedTransactions) {\n const serverWorkflowStates = await graphQlClient.query<{ transactionConfirmWorkflowStates: string[] }>({\n query: confirmWorkflowStates,\n variables: {\n transactions: items,\n },\n fetchPolicy: \"no-cache\",\n errorPolicy: \"all\",\n });\n if (serverWorkflowStates.errors && serverWorkflowStates.errors.length > 0) {\n return transactions.map((t) => t.id);\n }\n failedStates.push(...(serverWorkflowStates.data?.transactionConfirmWorkflowStates ?? []));\n }\n return failedStates;\n };\n\n const unsyncedStates = await getFailedStates();\n\n const createDesignResults = await Promise.all(\n options.map(async (option) => {\n return await createDesignDetails(\n option.workflowManager,\n option.workflow,\n option.layouts,\n option.getReducerState,\n option.transaction,\n option.workflowSelections,\n option.designName,\n createPreviewImage ?? (() => Promise.resolve(undefined)),\n option.workflowMetadata,\n unsyncedStates.includes(option.transaction.id),\n );\n }),\n );\n const client = options[0].workflowManager.getClient();\n const createDesignsResponse = await createDesignsGqlCall(\n createDesignResults.map((result) => result.designDetails),\n client,\n );\n if (!createDesignsResponse) {\n throw new Error(\"Failed to create designs\");\n }\n return createDesignsResponse.map((design, index) => {\n const option = options[index];\n const createDesignResult = createDesignResults[index];\n const upToDateTransaction = design.transaction!;\n return createDesignMessage(\n upToDateTransaction,\n option.product,\n option.workflow,\n createDesignResult.cartSelectionsWithPrices,\n design.sku,\n createDesignResult.cartMetadata,\n upToDateTransaction.previewImageLink,\n design.processExecution?.id,\n );\n });\n};\n\nexport interface SavedDesign {\n /**\n * The user's name for this saved design.\n */\n title: string;\n /**\n * A URL pointing to an image of the design. Typically a data URL\n */\n thumbnail?: string;\n /**\n * The ID of the transaction relating to this design.\n */\n transactionId: string;\n /**\n * The product ID for this transaction.\n */\n productId: string;\n /**\n * The integration product ID related to this order.\n */\n integrationProductId: string;\n /**\n * The name of the workflow annotated at time of save (may be different from current workflow name).\n */\n workflowName: string;\n /**\n * The ID of the workflow annotated at time of save.\n */\n workflowId: string;\n /**\n * The last edit that occured on this saved design.\n */\n lastEdited: Date;\n}\n/**\n * Represents the current method of storage for saved designs.\n */\nenum StorageMethod {\n Local = \"Local\",\n Remote = \"Remote\",\n}\n\n/**\n * The design service exposes helper functionality wrapping important design management operations.\n * NOTE: In the future this interface should allow for storing/pulling designs from the server.\n */\nclass DesignService {\n public readonly localPersistenceKey = \"designTransactions\";\n private storageMethod: StorageMethod = StorageMethod.Local;\n private designSavedListeners: ((designs: SavedDesign) => void)[] = [];\n\n /**\n * @param func The function to call when a design is saved.\n */\n attachSaveListener(func: (design: SavedDesign) => void) {\n this.designSavedListeners.push(func);\n }\n\n /**\n * @param func The function to remove from the list of listeners.\n */\n detachSaveListener(func: (design: SavedDesign) => void) {\n this.designSavedListeners = this.designSavedListeners.filter((f) => f !== func);\n }\n\n /**\n * Gets the currently persisted designs.\n */\n async getSavedDesigns(): Promise<SavedDesign[]> {\n if (this.storageMethod === StorageMethod.Local) {\n const persistedString = persistenceService.get(this.localPersistenceKey);\n const savedDesigns = persistedString ? (JSON.parse(persistedString) as SavedDesign[]) : [];\n return savedDesigns;\n }\n throw new UnhandledBehaviorError(\"Unexpected storage method requested\");\n }\n\n /**\n * Search for a transaction that has been saved.\n * @param transactionId The id to search for.\n * @returns The transaction for the given id provided it has been saved. undefined if it doesn't exist.\n */\n async getSavedDesignByTransaction(transactionId: string): Promise<SavedDesign | undefined> {\n const designs = await this.getSavedDesigns();\n return designs.find((d) => d.transactionId === transactionId);\n }\n\n /**\n * Saves a design to storage.\n * @param design The design to save.\n */\n async addDesign(design: SavedDesign) {\n const designs = await this.getSavedDesigns();\n const newDesigns = designs.filter((d) => d.transactionId !== design.transactionId);\n newDesigns.unshift(design);\n await this.setDesigns(newDesigns);\n this.designSavedListeners.forEach((listener) => listener(design));\n }\n\n /**\n * Change the user's name of the given saved design.\n */\n async renameDesign(transactionId: string, title: string) {\n const designs = await this.getSavedDesigns();\n const design = designs.find((d) => d.transactionId === transactionId);\n if (!design) {\n throw new Error(`No saved design for transaction ${transactionId}.`);\n }\n design.title = title;\n await this.setDesigns(designs);\n }\n\n /**\n * Removes a given design from storage.\n * @param transactionId\n */\n async removeDesign(transactionId: string) {\n const designs = await this.getSavedDesigns();\n await this.setDesigns(designs.filter((d) => d.transactionId !== transactionId));\n }\n\n private async setDesigns(designs: SavedDesign[]) {\n if (this.storageMethod === StorageMethod.Local) {\n persistenceService.set(this.localPersistenceKey, JSON.stringify(designs));\n return;\n }\n throw new UnhandledBehaviorError(\"Unexpected storage method requested\");\n }\n}\nconst designService = new DesignService();\nexport { designService };\n","import { Pith } from \"pith\";\nimport {\n Bundle,\n CommandContext,\n FrameStepData,\n getWorkflow,\n IllustrationStepData,\n LayoutsState,\n ModuleStepData,\n optionService,\n persistenceService,\n SpiffCommerceClient,\n TextStepData,\n TextStepHandle,\n WorkflowSelections,\n} from \"../index\";\nimport { StepHandle } from \"../stepHandles\";\nimport {\n Product,\n DesignCreationMessage,\n Transaction,\n CustomerDetailsInput,\n Workflow,\n ILayout,\n AnyStepData,\n StepType,\n LayoutRenderingPurpose,\n GlobalPropertyAspectConfiguration,\n Step,\n FrameMetadata,\n IllustrationMetadata,\n ModuleMetadata,\n TextMetadata,\n} from \"../types\";\nimport { WorkflowManager, InternalWorkflowManager, StateMutationFunc } from \"../WorkflowManager\";\nimport { StepHandleFactory } from \"../stepHandles/factory\";\nimport { designService, SavedDesign, createDesigns } from \"../services/design\";\nimport cloneDeep from \"lodash.clonedeep\";\nimport { ResourceGenerationError, UnhandledBehaviorError } from \"../util/exception\";\nimport debounce from \"lodash.debounce\";\nimport { RenderableScene, stepConditionsAreSatisfied } from \"../WorkflowManager/scenes\";\nimport type { ModelContainer } from \"@spiffcommerce/preview\";\nimport { LayoutPreviewService } from \"../WorkflowManager/LayoutPreviewService\";\nimport { gql } from \"@apollo/client/core\";\nimport {\n additionalProductFragment,\n conversionConfigurationFragment,\n finalizeUpdateTransactionMutation,\n updateTransactionQuantityQuery,\n updateTransactionWorkflowQuery,\n} from \"../query\";\nimport { createCanvas, getDomParser, loadImage } from \"../customCanvas\";\nimport { getSvgElement } from \"../CommandContext\";\nimport { renderPapyrusComponentAsString } from \"../util/crossplatform\";\nimport { GraphQlClientFunc } from \"../services/graphql\";\n\nconst addTransactionStakeholderMutation = gql`\n mutation AddTransactionStakeholder($id: String!, $type: String!, $details: CustomerDetailsInput!) {\n transactionAddStakeholder(id: $id, details: $details, type: $type) {\n id\n stakeholders {\n id\n type\n customer {\n id\n emailAddress\n }\n }\n }\n }\n`;\n\nconst addAddressToTransactionMutation = gql`\n mutation AddAddressToTransaction(\n $transactionId: String!\n $streetAddress: String\n $apartment: String\n $city: String\n $country: String\n $state: String\n $postCode: String\n ) {\n addressAttachToTransaction(\n transactionId: $transactionId\n streetAddress: $streetAddress\n apartment: $apartment\n city: $city\n country: $country\n state: $state\n postCode: $postCode\n ) {\n id\n }\n }\n`;\n\nconst addOrganizationToTransactionMutation = gql`\n mutation AddOrganizationToTransaction($transactionId: String!, $organizationName: String!) {\n organizationAttachToTransaction(transactionId: $transactionId, organizationName: $organizationName) {\n id\n }\n }\n`;\n\nconst transactionUpdateIntegrationProductMutation = gql`\n ${additionalProductFragment}\n ${conversionConfigurationFragment}\n mutation TransactionUpdateIntegrationProduct($id: String!, $integrationProductId: String) {\n transactionUpdateIntegrationProduct(id: $id, integrationProductId: $integrationProductId) {\n id\n integrationProduct {\n id\n externalProductId\n externalVariantId\n additionalExternalProductId\n additionalExternalVariantId\n }\n product {\n id\n basePrice\n enabled\n minimumOrderQuantity\n name\n description\n partner {\n id\n name\n currencyCode\n customerDetailsPromptMarkdown\n }\n productImages {\n id\n precedence\n asset {\n key\n fileLink\n name\n type\n versions {\n name\n link\n }\n }\n }\n integrationProducts {\n id\n integration {\n id\n type\n }\n externalProductId\n externalVariantId\n additionalExternalProductId\n additionalExternalVariantId\n additionalIntegrationProduct {\n ...AdditionalIntegrationProductFields\n }\n }\n profanities {\n id\n word\n }\n sku\n skuCode\n weight\n workflows {\n id\n friendlyName\n isPresent\n workflowName\n imageUrl\n }\n imageUrl\n modelUrl\n overlayImageUrl\n preloadImageUrl\n promptForCustomerDetails\n conversionConfiguration {\n ...ConversionConfigurationFields\n }\n productTags {\n id\n name\n }\n priceBreaks {\n id\n minQty\n percentage\n }\n }\n }\n }\n`;\n\n/**\n * A scene is a collection of steps that can be used to group steps together.\n */\nexport interface Scene {\n /**\n * The unique identifier for the scene.\n */\n id?: string;\n /**\n * The name of the scene.\n */\n name: string;\n /**\n * The steps that are part of the scene. A list of ids. See getStepById.\n */\n stepIds: string[];\n}\n\n/**\n * State related to a workflow experience.\n */\nexport interface ExperienceOptions {\n transaction: Transaction;\n\n workflow?: Workflow;\n\n modelContainer?: ModelContainer;\n renderableContextService?: LayoutPreviewService;\n reloadedState?: LayoutsState;\n /**\n * When true the experience is intended to be immutable.\n */\n readOnly?: boolean;\n /**\n * A function that communicates state changes to the server.\n */\n stateMutationFunc: StateMutationFunc;\n /**\n * The interface for the graphql client\n */\n graphQlClient: GraphQlClientFunc;\n /**\n * Should be set to true when the experience is loaded from an existing transaction.\n * FIXME: Wouldn't we know this from existance of reloadedState\n */\n isReloadedTransaction?: boolean;\n /**\n * When true the system will treat steps with\n * a single variant as renderable. False\n * by default.\n */\n singleVariantsRenderable?: boolean;\n\n /**\n * When true, will delay syncing the workflow state until manually enabled.\n */\n delayWorkflowStateSync?: boolean;\n}\n\n/**\n * A Workflow experience encapsulates the workflow manager and command context. It\n * provides a simplified interface for interacting with the workflow manager. You\n * should get an instance of this class from a Client you have constructed previously.\n */\nexport interface WorkflowExperience {\n /**\n * Get the current transaction for this experience.\n */\n getTransaction(): Transaction;\n\n /**\n * Get the bundle this experience is part of. May be undefined.\n */\n getBundle(): Bundle | undefined;\n\n /**\n * Set the bundle this experience is part of. Can be cleared using undefined.\n */\n setBundle(bundle: Bundle | undefined);\n\n /**\n * Get the current product for this experience. May be undefined.\n */\n getProduct(): Product | undefined;\n\n /**\n * Get the current profanity list for this experience. May be empty.\n */\n getProfanityList(): string[];\n\n /**\n * Set the current product for this experience.\n * @param product The new product to set.\n */\n setProduct(integrationProductId: string): Promise<void>;\n\n /**\n * Clear the product from this experience.\n */\n clearProduct(): Promise<void>;\n\n /**\n * Get the current workflow for this experience. May be undefined.\n */\n getWorkflow(): Workflow | undefined;\n\n /**\n * Set the current workflow for this experience.\n * @param workflow The new workflow to set.\n */\n setWorkflow(workflow: Workflow): Promise<void>;\n\n /**\n * Returns the client that was responsible for spawning this experience.\n */\n getClient(): SpiffCommerceClient;\n /**\n * State related to the design of the user.\n */\n getCommandContext(): CommandContext;\n /**\n * Returns true when the user may only view the design.\n */\n getIsReadOnly(): boolean;\n /**\n * Get the low level workflow amanager instance for this experience. Don't touch this unless you're willing to break things.\n */\n getWorkflowManager(): WorkflowManager;\n\n /**\n * Returns the step matching a given name, undefined if not found.\n * @param id The id the step must match.\n */\n getStepById(id: string): StepHandle<AnyStepData> | undefined;\n\n /**\n * Returns the step matching a given name, undefined if not found.\n * @param name The name the step must match.\n */\n getStepByName(name: string): StepHandle<AnyStepData> | undefined;\n\n /**\n * Returns all steps matching a specific type in the workflow. These steps\n * may be across multiple scenes and may or may not be active based on condition state.\n */\n getStepsByType(type: StepType): StepHandle<AnyStepData>[];\n\n /**\n * Returns all steps that are children of a given scene.\n * @param scene The scene you want the steps for.\n */\n getStepsByScene(scene: Scene): StepHandle<AnyStepData>[];\n\n /**\n * Returns all steps in the workflow. Ordered by scene and appearance within their respective scenes.\n */\n getSteps(): StepHandle<AnyStepData>[];\n\n /**\n * Returns all steps in the workflow that are conditionally active. Ordered by scene and appearance within their respective scenes.\n */\n getStepsConditionallyActive(): StepHandle<AnyStepData>[];\n\n /**\n * Returns a list of scenes that are configured in the workflow. Each scene\n * contains a list of steps. See getStepsByScene to access these.\n */\n getScenes(): Scene[];\n\n /**\n * Returns the total cost in subunits for all selections made on the design.\n * @param disablePriceBreaks Whether to exclude price breaks from the calculation.\n */\n getSelectionPriceSubunits(disablePriceBreaks?: boolean): number;\n\n /**\n * Returns the total cost in subunits for the base product.\n * @param includeAdditionalProduct When true the additional product cost will be included in the total (if configured).\n * @param disablePriceBreaks Whether to exclude price breaks from the calculation.\n */\n getBasePriceSubunits(includeAdditionalProduct?: boolean, disablePriceBreaks?: boolean): number;\n\n /**\n * If an additional product is configured, returns the base price of that product. Returns undefined otherwise.\n * @param disablePriceBreaks Whether to exclude price breaks from the calculation.\n */\n getAdditionalProductPriceSubunits(disablePriceBreaks?: boolean): number | undefined;\n\n /**\n * A convenience function returning the sum of the selection and base price values.\n * @param disablePriceBreaks Whether to exclude price breaks from the calculation.\n */\n getTotalPriceSubunits(disablePriceBreaks?: boolean): number;\n\n /**\n * The price break percentage that is expected to be applied in price calculations.\n */\n priceBreakToBeApplied(): number;\n\n /**\n * Calculates the price break and fires the \"PriceBreakChanged\" event if required.\n * This function is primarily intended for internal use.\n */\n checkForPriceBreakChanges(): void;\n\n /**\n * Takes selections made by the user in another workflow and applies them to this workflow. For\n * selections to be copied they must both have a matching global property configuration.\n * @param experience The experience to take selections from.\n * @param filter A list of steps to apply the selections to. If undefined all steps will be updated.\n */\n copySelectionsViaGlobalConfiguration(\n bundle: Bundle,\n experience: WorkflowExperience,\n filter?: StepHandle<AnyStepData>[],\n ): Promise<void>;\n\n /**\n * Attach specific details about the customer to the experience. This is useful for things like retargeting. Currently only\n * email is supported. From SpiffCommerce hosted experiences these details will be attached whenever the customer has provided & given permission.\n * @param details The new customer details. Only email is supported.\n * @deprecated Use assignCustomerDetails instead.\n */\n attachCustomerDetails(details: {\n /**\n * An email used for things like sending a design to the user.\n */\n email: string;\n }): Promise<void>;\n\n /**\n * Attach specific details about the customer to the experience. This is useful for things like retargeting.\n * From SpiffCommerce hosted experiences these details will be attached whenever the customer has provided & given permission.\n * @param details The new customer details.\n */\n assignCustomerDetails(details: CustomerDetailsInput): Promise<void>;\n\n /**\n * Attaches a listener to the scenes on a workflow experience. The scenes returned are a subset of the scenes configured in the\n * workflow and are based on the current state of the experience. This is useful for building a navigation menu.\n * @param cb The callback to be called when the scenes change. The new scenes are passed as an argument.\n */\n attachRenderableSceneListener(cb: (scenes: RenderableScene[]) => void): void;\n\n /**\n * Detaches a listener from the scenes on a workflow experience.\n */\n detachRenderableSceneListener(cb: (scenes: RenderableScene[]) => void): void;\n\n /**\n * Saves this experience to storage. This may be local or remote depending\n * on configuration.\n * @param title The title for the saved design.\n */\n save(title: string): Promise<SavedDesign>;\n\n /**\n * Returns a copy of the currently loaded design as a new, seperated workflow experience with\n * a fresh transaction.\n */\n copy(): Promise<WorkflowExperience>;\n\n /**\n * Creates a data URL preview for the current design.\n */\n createPreviewImage(isThreeD?: boolean, resolution?: number): Promise<string>;\n\n /**\n * To be called when the workflow experience is considered completed by the user.\n * @param onProgressUpdate Progress callback for finalizing the design. Optional\n * @param capturePreviewImage When true a preview image will be generated for the design. Defaults to true.\n */\n onDesignFinished(capturePreviewImage?: boolean): Promise<DesignCreationMessage>;\n\n /**\n * Returns the metadata associated with this workflow experience.\n * This is a combination of the metadata from the workflow, and the selections made by the user.\n * @returns An array of ExportedStepData objects, each containing the step ID, title, and properties.\n */\n getExportedStepData(): Promise<ExportedStepData[]>;\n\n /**\n * Get the quantity of this WorkflowExperience's Transaction.\n * @returns The amount that was, or will be, ordered.\n */\n getQuantity(): number;\n\n /**\n * Sets the quantity of this WorkflowExperience's Transaction.\n * @throws {Error} if the WorkflowExperience is read-only.\n * @throws {RangeError} if the value is below 1.\n * @param quantity The amount that was, or will be, ordered.\n * @returns A promise that resolves when the Transaction has been updated on the server.\n */\n setQuantity(quantity: number): Promise<void>;\n\n /**\n * Registers a callback function to be called when the specified event is raised.\n * TODO: We should include a second param to pass information about the event?\n * @param type The type of event to listen for.\n * @param callback The function to call when the event occurs.\n */\n addEventListener(\n type: WorkflowExperienceEventType,\n callback: (workflowExperience: WorkflowExperience) => void,\n ): void;\n\n /**\n * Removes a previously registered callback.\n * @param type The type of event.\n * @param callback The function to remove.\n */\n removeEventListener(\n type: WorkflowExperienceEventType,\n callback: (workflowExperience: WorkflowExperience) => void,\n ): void;\n\n attachAddress(\n streetAddress?: string,\n apartment?: string,\n city?: string,\n country?: string,\n state?: string,\n postCode?: string,\n ): Promise<void>;\n\n attachOrganization(name: string): Promise<void>;\n\n // TODO: merge this with fireEvent\n callEvent(type: WorkflowExperienceEventType);\n}\n\nexport type ExportedStepDataPropertyType = \"selection\" | \"color\" | \"image\" | \"text\";\n\nexport interface ExportedStepDataProperty {\n type: ExportedStepDataPropertyType;\n value: string;\n priceModifier: number;\n}\n\n// The metadata and variant selections of a step.\nexport interface ExportedStepData {\n stepId: string;\n title: string;\n properties: ExportedStepDataProperty[];\n}\n\n// The variant selections of a completed step.\nexport interface SelectedVariants {\n [stepName: string]: {\n id: string;\n name: string;\n priceModifier: number;\n }[];\n}\n\nexport enum WorkflowExperienceEventType {\n PriceBreakChanged = \"PriceBreakChanged\",\n ProductChanged = \"ProductChanged\",\n QuantityChanged = \"QuantityChanged\",\n RecipientChanged = \"RecipientChanged\",\n SelectionChanged = \"SelectionChanged\",\n}\n\n/**\n * Different types of aspect of a step that can be configured to be the target of global properties\n */\nenum AspectType {\n FileUpload = \"FileUpload\",\n Option = \"Option\",\n Text = \"Text\",\n}\n\nexport class WorkflowExperienceImpl implements WorkflowExperience {\n readonly client: SpiffCommerceClient;\n readonly transaction: Transaction;\n\n readonly graphQlClient: GraphQlClientFunc;\n readonly workflowManager: WorkflowManager;\n readonly isReadOnly: boolean;\n readonly cachedStepHandles: Map<string, StepHandle<any>> = new Map();\n\n /**\n * Bundle this experience has been added to.\n */\n private bundle?: Bundle;\n private profanityList: string[] = [];\n private workflow?: Workflow;\n private currentPriceBreak = 1;\n\n // A list of scenes that currently available to the user. This is a subset of the scenes available in the workflow.\n // The steps contained within are also a subset.\n private renderableScenes: RenderableScene[] = [];\n private renderableSceneCallbacks: ((scenes: RenderableScene[]) => void)[] = [];\n\n private eventCallbacks: Map<WorkflowExperienceEventType, ((workflowExperience: WorkflowExperience) => void)[]> =\n new Map();\n\n constructor(client: SpiffCommerceClient, experienceOptions: ExperienceOptions) {\n this.client = client;\n this.transaction = experienceOptions.transaction;\n this.workflow = experienceOptions.workflow;\n this.profanityList = this.transaction.product?.profanities?.map((x) => x.word) || [];\n\n this.isReadOnly = experienceOptions.transaction.isOrdered || !!experienceOptions.readOnly;\n this.graphQlClient = experienceOptions.graphQlClient;\n\n this.workflowManager = new InternalWorkflowManager(\n this,\n client,\n (request) => {\n try {\n this.debouncedSavedDesignUpdate();\n } catch {\n console.error(\"Failed to update saved design details.\");\n }\n return experienceOptions.stateMutationFunc(request);\n },\n experienceOptions.graphQlClient,\n experienceOptions.reloadedState,\n experienceOptions.readOnly,\n experienceOptions.modelContainer,\n experienceOptions.isReloadedTransaction,\n experienceOptions.singleVariantsRenderable,\n experienceOptions.delayWorkflowStateSync,\n );\n\n // We attach a listener to the manager and update the available scenes when they change. We store simplified information about the scenes\n // instead of the full complex structure. Internal scene state/configuration should be considered private & exposed through handles instead.\n // The user can get reference to a handle via the step ID returned here.\n this.workflowManager.addSelectionCallback((callbackOptions) => {\n const newScenes = callbackOptions.traversableScenes.map((workflowScene) => {\n const newSteps = workflowScene.renderableSteps.map((step) => step.stepName);\n return {\n id: workflowScene.name,\n title: workflowScene.title,\n renderableSteps: newSteps,\n workflowScene,\n } as RenderableScene;\n });\n this.renderableScenes = newScenes;\n this.renderableSceneCallbacks.forEach((cb) => cb(newScenes));\n this.callEvent(WorkflowExperienceEventType.SelectionChanged);\n });\n\n this.currentPriceBreak = this.priceBreakToBeApplied();\n }\n\n getTransaction(): Transaction {\n return this.transaction;\n }\n\n getProduct(): Product | undefined {\n return this.transaction.product;\n }\n\n getProfanityList(): string[] {\n return this.profanityList;\n }\n\n async setProduct(integrationProductId: string): Promise<void> {\n this.workflow = undefined;\n const response = await this.graphQlClient().mutate({\n mutation: transactionUpdateIntegrationProductMutation,\n variables: {\n id: this.getTransaction().id,\n integrationProductId,\n },\n });\n const newProduct = response.data?.transactionUpdateIntegrationProduct.product;\n if (!newProduct) {\n throw new UnhandledBehaviorError(\"Failed to set product. No product returned from server.\");\n }\n if (!this.bundle) {\n throw new UnhandledBehaviorError(\"Cannot set product on experience that is not part of a bundle.\");\n }\n\n this.transaction.product = {\n ...this.transaction.product,\n ...response.data?.transactionUpdateIntegrationProduct.product,\n };\n\n this.transaction.integrationProduct = {\n ...this.transaction.integrationProduct,\n ...response.data?.transactionUpdateIntegrationProduct.integrationProduct,\n };\n\n this.transaction.workflowState = undefined;\n\n this.currentPriceBreak = this.priceBreakToBeApplied();\n\n this.callEvent(WorkflowExperienceEventType.ProductChanged);\n\n const collectionProduct = (await this.bundle.getProductCollection()!.fetchProducts()).find(\n (p) => p.getId() === newProduct.id,\n );\n try {\n const defaultWorkflow = collectionProduct?.getDefaultWorkflow();\n if (defaultWorkflow) {\n const workflow = await getWorkflow(defaultWorkflow.getId());\n await this.setWorkflow(workflow);\n console.log(\"Setting Product - Workflow set to default for product.\");\n }\n } catch (e) {\n console.log(\"Setting Product - No default workflow available, must be set manually.\");\n }\n }\n\n async clearProduct(): Promise<void> {\n if (!this.bundle) {\n throw new UnhandledBehaviorError(\"Cannot clear product on experience that is not part of a bundle.\");\n }\n this.workflow = undefined;\n this.transaction.workflowState = undefined;\n this.transaction.product = undefined;\n this.transaction.integrationProduct = undefined;\n this.currentPriceBreak = this.priceBreakToBeApplied();\n this.callEvent(WorkflowExperienceEventType.ProductChanged);\n await this.graphQlClient().mutate({\n mutation: transactionUpdateIntegrationProductMutation,\n variables: {\n id: this.getTransaction().id,\n },\n });\n }\n\n getWorkflow(): Workflow | undefined {\n return this.workflow;\n }\n\n async setWorkflow(workflow: Workflow): Promise<void> {\n this.workflow = workflow;\n await this.graphQlClient().mutate({\n mutation: updateTransactionWorkflowQuery,\n variables: {\n id: this.getTransaction().id,\n workflowId: workflow.id,\n },\n });\n return this.workflowManager.setWorkflow(workflow);\n }\n\n async attachAddress(\n streetAddress?: string,\n apartment?: string,\n city?: string,\n country?: string,\n state?: string,\n postCode?: string,\n ): Promise<void> {\n await this.graphQlClient().mutate({\n mutation: addAddressToTransactionMutation,\n variables: {\n transactionId: this.getTransaction().id,\n streetAddress: streetAddress || undefined,\n apartment: apartment || undefined,\n city: city || undefined,\n country: country || undefined,\n state: state || undefined,\n postCode: postCode || undefined,\n },\n });\n }\n\n async attachOrganization(name: string): Promise<void> {\n await this.graphQlClient().mutate({\n mutation: addOrganizationToTransactionMutation,\n variables: {\n transactionId: this.getTransaction().id,\n organizationName: name,\n },\n });\n }\n\n getBundle() {\n return this.bundle;\n }\n\n setBundle(bundle: Bundle) {\n this.bundle = bundle;\n }\n\n getClient() {\n return this.client;\n }\n\n getIsReadOnly() {\n return this.isReadOnly;\n }\n\n getCommandContext() {\n return this.workflowManager.getCommandContext();\n }\n\n getWorkflowManager() {\n return this.workflowManager;\n }\n\n async createPreviewImage(isThreeD?: boolean, resolution?: number): Promise<string> {\n const workflow = this.getWorkflow();\n const cameraOrientation = workflow?.finalizeStepConfig?.lookAtAnimation;\n\n if (!workflow) {\n throw new Error(\"Failed to generate cart preview image! No workflow is set.\");\n }\n\n if (isThreeD) {\n if (!cameraOrientation) {\n throw new Error(\"Failed to generate cart preview image! No camera orientation configured.\");\n }\n const data = await this.workflowManager\n .getPreviewService()\n ?.renderSceneScreenshot(resolution ?? 512, cameraOrientation);\n return data || \"\";\n }\n\n let res = 2048;\n if (resolution && resolution <= 2048) {\n res = resolution;\n }\n\n const canvas = createCanvas(res, res);\n\n // Resolve default layout for rendering.\n const layouts = this.workflowManager.getCommandContext().getAllLayouts();\n const defaultPanelIndex = workflow.defaultPreviewPanelIndex || 0;\n const targetPanel = workflow.panels[defaultPanelIndex];\n const defaultLayout = layouts.find((l) => l.layoutState?.layout.panelId === targetPanel?.name) || layouts[0];\n const region = defaultLayout.layoutState.layout.previewRegion\n ? {\n x: defaultLayout.layoutState.layout.previewRegion.left,\n y: defaultLayout.layoutState.layout.previewRegion.top,\n width: defaultLayout.layoutState.layout.previewRegion.width,\n height: defaultLayout.layoutState.layout.previewRegion.height,\n }\n : {\n x: 0,\n y: 0,\n width: defaultLayout.layoutState.layout.width,\n height: defaultLayout.layoutState.layout.height,\n };\n\n // Render the SVG for the target layout to a data URL for return.\n const layout = this.workflowManager.getCommandContext().getLayoutById(defaultLayout.layoutState.layout.id);\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new ResourceGenerationError(\"Failed to obtain 2D context for preview image creation\");\n }\n const templatingContext = this.workflowManager.getTemplatingContext();\n const svgElement = getSvgElement(layout.layoutState.layout, layout.layoutState.elements, {\n renderingConfiguration: {\n purpose: LayoutRenderingPurpose.Print,\n region: { left: region.x, top: region.y, width: region.width, height: region.height },\n templatingContext,\n },\n });\n const svgString = renderPapyrusComponentAsString(svgElement);\n const pith = await Pith.from(ctx as any, svgString, {\n anonymousCrossOrigin: true,\n ignoreDimensions: false,\n createCanvas: createCanvas as any,\n createImage: loadImage as any,\n DOMParser: getDomParser(),\n fetch: fetch,\n });\n await pith.render();\n const objectUrl = await this.getCanvasObjectURLAsync(canvas as any);\n return canvas.toDataURL(objectUrl as any);\n }\n\n getStepById(id: string) {\n const stepData = this.getWorkflow()?.steps.find((step) => step.stepName === id);\n if (!stepData || !this.stepHasHandle(stepData)) return undefined;\n const cachedHandle = this.cachedStepHandles.get(stepData.stepName);\n if (cachedHandle) {\n return cachedHandle;\n }\n const createdHandle = StepHandleFactory.get(this.getWorkflowManager(), stepData);\n this.cachedStepHandles.set(stepData.stepName, createdHandle);\n return createdHandle;\n }\n\n getSteps(): StepHandle<AnyStepData>[] {\n return this.getScenes().flatMap((scene) => this.getStepsByScene(scene));\n }\n\n getStepsConditionallyActive(): StepHandle<AnyStepData>[] {\n return this.getScenes().flatMap((scene) =>\n this.getStepsByScene(scene).filter((step) =>\n stepConditionsAreSatisfied(step.getRaw(), this.getWorkflowManager().getStepSelections()),\n ),\n );\n }\n\n getScenes(): Scene[] {\n // Internally scenes are called step groups, but we expose them to the user as 'scenes'.\n const stepGroups = this.getWorkflow()?.stepGroups || [];\n return stepGroups.map((sg) => {\n return {\n id: sg.id,\n name: sg.name,\n stepIds: sg.stepNames,\n } as Scene;\n });\n }\n\n getSelectionPriceSubunits(disablePriceBreaks?: boolean): number {\n const selections = this.getWorkflowManager().getWorkflowSelections();\n let totalSelectionCost = 0;\n Object.values(selections).forEach((step) => {\n totalSelectionCost += step.selections.reduce((acc, variant) => acc + (variant.priceModifier || 0), 0);\n });\n return this.getPriceSubUnitsAfterPriceBreaks(totalSelectionCost, disablePriceBreaks);\n }\n\n getBasePriceSubunits(includeAdditionalProduct?: boolean, disablePriceBreaks?: boolean): number {\n const basePrice = this.getPriceSubUnitsAfterPriceBreaks(this.getProduct()?.basePrice || 0, disablePriceBreaks);\n if (includeAdditionalProduct) {\n const additionalPrice = this.getAdditionalProductPriceSubunits(disablePriceBreaks) || 0;\n return basePrice + additionalPrice;\n }\n return basePrice;\n }\n\n getAdditionalProductPriceSubunits(disablePriceBreaks?: boolean): number | undefined {\n const integrationProduct = this.getTransaction().integrationProduct;\n if (integrationProduct?.additionalIntegrationProduct?.product) {\n const additionalProductPrice = integrationProduct.additionalIntegrationProduct.product.basePrice || 0;\n return this.getPriceSubUnitsAfterPriceBreaks(additionalProductPrice, disablePriceBreaks);\n }\n return undefined;\n }\n\n getTotalPriceSubunits(disablePriceBreaks?: boolean): number {\n return (\n this.getBasePriceSubunits(false, disablePriceBreaks) + this.getSelectionPriceSubunits(disablePriceBreaks)\n );\n }\n\n private getPriceSubUnitsAfterPriceBreaks(subUnits: number, disablePriceBreaks?: boolean): number {\n const percentage = disablePriceBreaks ? 1 : this.priceBreakToBeApplied();\n const finalPrice = subUnits * percentage;\n return Math.ceil(finalPrice);\n }\n\n priceBreakToBeApplied(): number {\n // Sort price breaks from largest minQty to smallest.\n const priceBreaks = (this.getProduct()?.priceBreaks || []).sort((a, b) => -(a.minQty - b.minQty));\n const matchingExperiences = [...this.getMatchingExperiencesFromBundle(), this];\n const totalQuantity = matchingExperiences.reduce((acc, exp) => acc + exp.getQuantity(), 0);\n for (const pb of priceBreaks) {\n if (pb.minQty <= totalQuantity) {\n return pb.percentage;\n }\n }\n return 1;\n }\n\n checkForPriceBreakChanges(): void {\n const updatedPriceBreak = this.priceBreakToBeApplied();\n if (this.currentPriceBreak !== updatedPriceBreak) {\n this.updatePriceBreak(updatedPriceBreak);\n this.getMatchingExperiencesFromBundle().forEach((wfe: WorkflowExperienceImpl) =>\n wfe.updatePriceBreak(updatedPriceBreak),\n );\n }\n }\n\n private getMatchingExperiencesFromBundle(): WorkflowExperience[] {\n return (this.bundle?.getWorkflowExperiences() || []).filter((exp) => {\n const transactionIdA = exp.getTransaction().id;\n const transactionIdB = this.getTransaction().id;\n const productIdA = exp.getProduct()?.id;\n const productIdB = this.getProduct()?.id;\n return transactionIdA !== transactionIdB && productIdA === productIdB;\n });\n }\n\n private updatePriceBreak(value: number) {\n this.currentPriceBreak = value;\n this.callEvent(WorkflowExperienceEventType.PriceBreakChanged);\n }\n\n async copySelectionsViaGlobalConfiguration(\n bundle: Bundle,\n experience: WorkflowExperience,\n filter?: StepHandle<AnyStepData>[],\n ) {\n const bundleProperties = await bundle.getGlobalProperties();\n const filterIds = filter?.map((s) => s.getId());\n const targetSteps = this.getSteps().filter((s) => filterIds === undefined || filterIds.includes(s.getId()));\n const originatingSteps = experience.getSteps();\n\n const getGlobalPropertyFromConfig = (config: GlobalPropertyAspectConfiguration) => {\n return bundleProperties.find((p) => p.getRawProperty().name === config.aspectName);\n };\n\n targetSteps.forEach((targetStep) => {\n // Grab the properties of the step, stringify them for easier comparison\n const uniqueProperties = new Set<string>();\n const propertyConfigurations = targetStep.getRaw().globalPropertyAspectConfigurations;\n if (propertyConfigurations === undefined) return;\n propertyConfigurations.forEach((p) => uniqueProperties.add(JSON.stringify(p)));\n // Go through properties of originating experience and search for matches\n originatingSteps.forEach((originatingStep) => {\n const properties = originatingStep.getRaw().globalPropertyAspectConfigurations;\n if (properties === undefined) return;\n properties.forEach((p) => {\n const actualProperty = getGlobalPropertyFromConfig(p);\n const requiredProperty = uniqueProperties.has(JSON.stringify(p));\n if (requiredProperty && actualProperty?.getType() === AspectType.Option) {\n const curVariant = originatingStep.getCurrentVariant();\n if (!curVariant) return;\n targetStep.selectVariant(curVariant);\n uniqueProperties.delete(JSON.stringify(p));\n } else if (requiredProperty && actualProperty?.getType() === AspectType.Text) {\n const text = (originatingStep as TextStepHandle).getText();\n (targetStep as TextStepHandle).setText(text);\n uniqueProperties.delete(JSON.stringify(p));\n }\n // TODO: File Upload, not required now.\n });\n });\n });\n }\n\n getStepByName(name: string) {\n const stepData = this.getWorkflow()?.steps.find((step) => step.stepTitle === name);\n if (!stepData || !this.stepHasHandle(stepData)) return undefined;\n return StepHandleFactory.get(this.getWorkflowManager(), stepData);\n }\n\n getStepsByType(type: StepType): StepHandle<AnyStepData>[] {\n return (\n this.getWorkflow()\n ?.steps.filter((step) => step.type === type)\n .map((step) => StepHandleFactory.get(this.getWorkflowManager(), step)) || []\n );\n }\n\n getStepsByScene(scene: Scene): StepHandle<AnyStepData>[] {\n const workflow = this.getWorkflow();\n // Enforce scene existence.\n if (!workflow?.stepGroups.find((s) => s.name === scene.name)) {\n throw new Error(\n \"Given scene is not present on workflow! Be careful when persisting scenes that you only use them with the relevant workflow.\",\n );\n }\n const steps = scene.stepIds\n .map((id) => workflow.steps.find((step) => step.stepName === id))\n .filter((s): s is Step<AnyStepData> => !!s && this.stepHasHandle(s));\n return steps.map((step) => StepHandleFactory.get(this.getWorkflowManager(), step));\n }\n\n async attachCustomerDetails(details: { email: string }): Promise<void> {\n return this.assignCustomerDetails({ emailAddress: details.email });\n }\n\n async assignCustomerDetails(details: CustomerDetailsInput): Promise<void> {\n const response = await this.graphQlClient().mutate<{ transactionAddStakeholder: Transaction }>({\n mutation: addTransactionStakeholderMutation,\n variables: {\n id: this.getTransaction().id,\n details,\n type: \"Owner\",\n },\n });\n const stakeholder = response.data?.transactionAddStakeholder?.stakeholders?.find(\n (s) => s.customer?.emailAddress === details.emailAddress,\n );\n if (stakeholder?.customer) {\n this.getWorkflowManager().setTransactionCustomer(stakeholder.customer);\n // Persist the customer ID for this transaction so that we can retrieve it when authenticating on reload.\n const transactionCustomerIds = persistenceService.getMap(\"transactionCustomerIds\") || new Map();\n transactionCustomerIds.set(this.getTransaction().id, stakeholder.customer.id);\n persistenceService.setMap(\"transactionCustomerIds\", transactionCustomerIds);\n }\n }\n\n attachRenderableSceneListener(cb: (scenes: RenderableScene[]) => void): void {\n this.renderableSceneCallbacks.push(cb);\n cb(this.renderableScenes);\n }\n\n detachRenderableSceneListener(cb: (scenes: RenderableScene[]) => void): void {\n this.renderableSceneCallbacks = this.renderableSceneCallbacks.filter((x) => x !== cb);\n }\n\n debouncedSavedDesignUpdate = debounce(async () => {\n const existingDesign = await designService.getSavedDesignByTransaction(this.getTransaction().id);\n if (existingDesign) this.save();\n }, 2500);\n\n async save(title?: string) {\n const product = this.getProduct();\n const workflow = this.getWorkflow();\n const state = this.getCommandContext().getState();\n\n if (!product) throw new UnhandledBehaviorError(\"Product undefined!\");\n if (!workflow) throw new UnhandledBehaviorError(\"Workflow undefined!\");\n if (!state) throw new UnhandledBehaviorError(\"State undefined!\");\n\n const getTitle = async () => {\n if (title) return title;\n const transactionId = this.getTransaction().id;\n const ds = await designService.getSavedDesigns();\n const existingTitle = ds.find((d) => d.transactionId === transactionId)?.title;\n return existingTitle ? existingTitle : `My design`;\n };\n const saveData: SavedDesign = {\n title: await getTitle(),\n thumbnail: await this.createPreviewImage(false, 256),\n transactionId: this.getTransaction().id,\n productId: product.id,\n integrationProductId: this.getTransaction().integrationProduct!.id,\n workflowName: workflow.name,\n workflowId: workflow.id,\n lastEdited: new Date(),\n };\n await designService.addDesign(saveData);\n return saveData;\n }\n\n async copy() {\n const state = cloneDeep(this.getCommandContext().getState());\n if (!state) throw new UnhandledBehaviorError(\"Internal state is undefined! Cannot copy experience!\");\n const savedWorkflowState = JSON.stringify(state.transaction);\n const workflow = this.getWorkflow();\n if (!workflow) throw new UnhandledBehaviorError(\"Workflow is undefined! Cannot copy experience!\");\n const integrationProductId = this.getTransaction().integrationProduct?.id;\n if (!integrationProductId) throw new UnhandledBehaviorError(\"Integration product id is undefined!\");\n const experience = await this.getClient().getWorkflowExperience({\n type: \"integration\",\n integrationProductId,\n workflowId: workflow.id,\n workflowState: savedWorkflowState,\n });\n return experience;\n }\n\n async onDesignFinished(capturePreviewImage: boolean = true): Promise<DesignCreationMessage> {\n const transaction = this.getTransaction();\n const product = this.getProduct();\n const workflow = this.getWorkflow();\n\n if (!product)\n throw new UnhandledBehaviorError(\"Product undefined! Cannot finish an experience without a product.\");\n if (!workflow)\n throw new UnhandledBehaviorError(\"Workflow undefined! Cannot finish an experience without a workflow.\");\n\n // Break out if the transaction is ordered. We don't want to allow anything here.\n if (transaction.isOrdered) {\n return {\n event: \"\",\n exportedData: {},\n lineItemImageUrl: \"\",\n optionsCost: 0,\n transactionId: transaction.id,\n workflowViewerLink: \"\",\n workflowViewerReadOnlyLink: \"\",\n };\n }\n\n const result = await createDesigns(\n [\n {\n workflowManager: this.workflowManager,\n workflow,\n layouts: this.workflowManager.getLayouts(),\n getReducerState: () => this.workflowManager.getCommandContext().getState()!, // Handle case where undefined (create a default state)\n product,\n transaction,\n workflowSelections: this.workflowManager.getWorkflowSelections(),\n workflowMetadata: this.workflowManager.getWorkflowMetadata(),\n designName: workflow.name,\n },\n ],\n (show3D?: boolean) => {\n if (capturePreviewImage) {\n return this.createPreviewImage(show3D, 1024);\n }\n return Promise.resolve(undefined);\n },\n );\n\n // If the transaction is marked as completed we need to run an update transaction flow.\n if (transaction.completed) {\n await this.graphQlClient().mutate({\n mutation: finalizeUpdateTransactionMutation,\n variables: {\n transactionId: transaction.id,\n },\n });\n }\n\n return result[0];\n }\n\n /**\n * @param step The step to test against.\n * @returns Returns true when a valid handle is implemented for a given step type. Certain steps don't support handles, such as silent illustrations.\n */\n private stepHasHandle(step: Step<AnyStepData>): boolean {\n return step.type !== StepType.SilentIllustration && step.type !== StepType.ProductOverlay;\n }\n\n private getCanvasObjectURLAsync = async (canvas: HTMLCanvasElement): Promise<string> => {\n return new Promise((resolve, reject) => {\n try {\n canvas.toBlob((blob) => {\n if (blob) {\n const objectURL = URL.createObjectURL(blob);\n resolve(objectURL);\n }\n });\n } catch (e: any) {\n reject(e);\n }\n });\n };\n\n async getExportedStepData(): Promise<ExportedStepData[]> {\n const workflow = this.getWorkflow();\n const metadata = this.getWorkflowManager().getWorkflowMetadata();\n const selections = this.getWorkflowManager().getWorkflowSelections();\n const exportedData: ExportedStepData[] = [];\n\n for (const step of workflow?.steps || []) {\n const stepId = step.stepName;\n const stepMetadata = metadata[stepId];\n const stepSelection = selections[stepId]?.selections[0]; // Legacy: Multi selection was deprecated and removed years ago. Selections as an array on a step is a legacy concept.\n\n const curStepExportedData: ExportedStepData = {\n stepId: stepId,\n title: step.stepTitle,\n properties: [],\n };\n\n // First we pull the selected variant for the step. This is the most common piece of metadata\n if (stepSelection && (await stepHasExportableSelection(step, selections))) {\n curStepExportedData.properties.push({\n type: \"selection\",\n value: stepSelection.name,\n priceModifier: stepSelection.priceModifier,\n });\n }\n\n // We can skip the remaining logic if metadata isn't present for this step.\n if (!stepMetadata) {\n exportedData.push(curStepExportedData);\n continue;\n }\n\n switch (step.type) {\n case StepType.Frame:\n {\n const stepData = step.data as FrameStepData;\n const stepmd = stepMetadata as FrameMetadata;\n if (stepmd.image && stepData.displayImageOnFinishStep) {\n curStepExportedData.properties.push({\n type: \"image\",\n value: stepmd.image,\n priceModifier: 0,\n });\n }\n }\n break;\n case StepType.Illustration:\n {\n const stepData = step.data as IllustrationStepData;\n const stepmd = stepMetadata as IllustrationMetadata;\n if (stepmd && stepmd.colors && stepmd.colors.length > 0 && stepData.displayColorsOnFinishStep) {\n const colorString = stepmd.colors.join(\", \").toUpperCase();\n curStepExportedData.properties.push({\n type: \"color\",\n value: colorString,\n priceModifier: 0,\n });\n }\n }\n break;\n case StepType.Module:\n {\n const stepData = step.data as ModuleStepData;\n const stepmd = stepMetadata as ModuleMetadata;\n if (stepmd && stepmd.text && stepData.displayTextOnFinishStep) {\n curStepExportedData.properties.push({\n type: \"text\",\n value: stepmd.text,\n priceModifier: 0,\n });\n }\n }\n break;\n case StepType.Text: {\n const stepData = step.data as TextStepData;\n const stepmd = stepMetadata as TextMetadata;\n if (stepmd && stepmd.text && stepData.displayTextOnFinishStep) {\n curStepExportedData.properties.push({\n type: \"text\",\n value: stepmd.text,\n priceModifier: 0,\n });\n }\n if (stepmd && stepmd.color && stepData.displayColorOnFinishStep) {\n curStepExportedData.properties.push({\n type: \"color\",\n value: stepmd.color,\n priceModifier: 0,\n });\n }\n }\n }\n\n exportedData.push(curStepExportedData);\n }\n\n return exportedData.filter((step) => step.properties && step.properties.length > 0);\n }\n\n getQuantity(): number {\n return this.getTransaction().quantity || 1;\n }\n\n async setQuantity(quantity: number): Promise<void> {\n if (quantity < 1) {\n throw new RangeError(\"WorkflowExperience quantity must be greater than zero.\");\n }\n if (this.isReadOnly) {\n throw new Error(\"Cannot update quantity on a read-only WorkflowExperience\");\n }\n this.getTransaction().quantity = quantity;\n this.callEvent(WorkflowExperienceEventType.QuantityChanged);\n this.checkForPriceBreakChanges();\n const transaction = this.getTransaction();\n await this.graphQlClient().mutate({\n mutation: updateTransactionQuantityQuery,\n variables: {\n id: transaction.id,\n quantity,\n },\n });\n }\n\n addEventListener(\n type: WorkflowExperienceEventType,\n callback: (workflowExperience: WorkflowExperience) => void,\n ): void {\n const events = this.eventCallbacks.get(type) || [];\n events.push(callback);\n this.eventCallbacks.set(type, events);\n }\n\n removeEventListener(\n type: WorkflowExperienceEventType,\n callback: (workflowExperience: WorkflowExperience) => void,\n ): void {\n const events = this.eventCallbacks.get(type) || [];\n this.eventCallbacks.set(\n type,\n events.filter((evt) => evt !== callback),\n );\n }\n\n callEvent(type: WorkflowExperienceEventType): void {\n (this.eventCallbacks.get(type) || []).forEach((cb) => cb(this));\n }\n}\n\n/**\n * Returns true when a step supports display of data in the finish step and\n * the step is configured to do so in the workflow configuration.\n * @param step The step to check.\n * @returns True when the step supports display of data in the finish step and false otherwise.\n */\nconst selectionConfiguredToExport = (step: Step): boolean => {\n const validStepsForDisplay = [\n StepType.Question,\n StepType.Frame,\n StepType.Illustration,\n StepType.Material,\n StepType.Model,\n StepType.Picture,\n StepType.Shape,\n StepType.Text,\n ];\n if (validStepsForDisplay.includes(step.type)) {\n const data = step.data as { displaySelectionOnFinishStep?: boolean; displaySelectionsOnFinishStep?: boolean };\n return !!data.displaySelectionOnFinishStep || !!data.displaySelectionsOnFinishStep;\n }\n return false;\n};\n\n/**\n * Checks if a step has selections that are valid for the finish step.\n * @param step The step to check.\n * @param workflowSelections The current workflow selection object.\n * @returns True when a valid selection is found, false otherwise.\n */\nconst stepHasExportableSelection = async (step: Step, workflowSelections: WorkflowSelections): Promise<boolean> => {\n if (!selectionConfiguredToExport(step)) return false;\n const stepOption = await optionService.getOptionForStep(step);\n if (stepOption && (stepOption.variants || []).length > 1) {\n const stepSelections = workflowSelections[step.stepName];\n if (stepSelections && stepSelections.selections.length > 0) {\n return true;\n }\n return false;\n }\n return false;\n};\n","import { Bundle } from \"../Bundle\";\nimport { Variant } from \"../stepHandles/resource/variant\";\nimport { FrameStepHandle } from \"../stepHandles/steps/frame\";\nimport { assetService } from \"../services/asset\";\nimport {\n AnyStepData,\n ColorDefinition,\n ColorOption,\n fetchAsString,\n generateSVGWithUnknownColors,\n IllustrationStepHandle,\n optionService,\n ShapeStepHandle,\n StepHandle,\n svgToDataUrl,\n TextStepHandle,\n VariantResource,\n WorkflowExperience,\n} from \"..\";\nimport {\n AddonHandle,\n AspectType,\n Asset,\n GlobalPropertyConfigurationAspect,\n GlobalPropertyConfigurationConditionMode,\n GlobalPropertyState,\n GlobalPropertyStateColorOptionStorage,\n GlobalPropertyStateFileUploadStorage,\n OptionResource,\n PatternImageData,\n StepType,\n} from \"../types\";\nimport { GetSVGDimensions, patternImageDataCache } from \"../util/frame\";\nimport { modifySVGColors } from \"../util/illustration\";\n\n/**\n * TODO: Optimize workflow experience state updates.\n */\n\nexport class GlobalPropertyHandleService {\n private readonly bundle: Bundle;\n private handleCache: { [key: string]: GlobalPropertyHandle } = {};\n\n constructor(bundle: Bundle) {\n this.bundle = bundle;\n }\n\n /**\n * Gets a handle for the given global property. Fetches from cache if available.\n * @param property The property to get a handle for.\n * @returns A promise resolving to the handle.\n */\n async getHandle(property: GlobalPropertyConfigurationAspect): Promise<GlobalPropertyHandle> {\n if (this.handleCache[property.name]) return this.handleCache[property.name];\n const handle = await this.createHandle(property);\n this.handleCache[property.name] = handle;\n return handle;\n }\n\n /**\n * Gets a list of handles for all global properties. Fetches from cache if available.\n * @returns A promise resolving to the handles.\n */\n async getHandles(): Promise<GlobalPropertyHandle[]> {\n if (!this.bundle.getProductCollection()?.getResource().globalPropertyConfiguration) return [];\n await this.bundle.getGlobalPropertyStateManager().getInitializationPromise();\n const configuration = this.bundle.getProductCollection()?.getResource().globalPropertyConfiguration;\n if (!configuration) return [];\n return Promise.all(configuration.aspects.map((p) => this.getHandle(p)));\n }\n\n /**\n * Applies the global state to all handles, if the state is set.\n * @param handles The handles to apply the state to.\n * @param state\n * @returns\n */\n applyConditionsFromState(\n handles: GlobalPropertyHandle[],\n state: GlobalPropertyState | undefined,\n ): GlobalPropertyHandle[] {\n if (!state) return handles;\n return handles.filter((h) => {\n return this.aspectConditionsSatisfied(h.getRawProperty(), state);\n });\n }\n\n private aspectConditionsSatisfied(aspect: GlobalPropertyConfigurationAspect, state: GlobalPropertyState): boolean {\n if (!aspect.conditions || aspect.conditions.length === 0) return true;\n const operation =\n aspect.conditionMode === GlobalPropertyConfigurationConditionMode.AND\n ? Array.prototype.every.bind(aspect.conditions)\n : Array.prototype.some.bind(aspect.conditions); // Default is OR\n return operation((c) => {\n const targetAspect = state.aspects.find((a) => a.name === c.targetAspectName);\n if (!targetAspect) return false;\n return c.requiredVariantSelections.some((v) => v === targetAspect.value);\n });\n }\n\n private async createHandle(property: GlobalPropertyConfigurationAspect): Promise<GlobalPropertyHandle> {\n switch (property.type) {\n case AspectType.FileUpload:\n return new FileUploadGlobalPropertyHandle(this.bundle, property).initialize();\n case AspectType.ColorOption:\n return new ColorOptionGlobalPropertyHandle(\n this.bundle,\n property,\n property.entityId ? await optionService.getOption(property.entityId) : undefined,\n );\n case AspectType.Option: {\n const option = property.entityId ? await optionService.getOption(property.entityId) : undefined;\n if (option?.type === \"Color\") {\n return new ColorOptionGlobalPropertyHandle(this.bundle, property, option);\n } else {\n return new OptionGlobalPropertyHandle(this.bundle, property, option);\n }\n }\n case AspectType.Text:\n return new TextGlobalPropertyHandle(this.bundle, property);\n default:\n throw new Error(\"Unhandled Global Property Aspect Type\");\n }\n }\n}\n\n/**\n * A GlobalPropertyHandle acts as an interface to global properties on our platform. Currently\n * bundles can return a handle for any global properties associated to the collection.\n */\nexport abstract class GlobalPropertyHandle {\n protected readonly bundle: Bundle;\n protected readonly property: GlobalPropertyConfigurationAspect;\n\n constructor(bundle: Bundle, property: GlobalPropertyConfigurationAspect) {\n this.bundle = bundle;\n this.property = property;\n }\n\n /**\n * @returns The name of the global property. This is the key used to store the property in the state.\n */\n getName() {\n return this.property.name;\n }\n\n /**\n * @returns A human-friendly title.\n */\n getTitle() {\n return this.property.title;\n }\n\n /**\n * @returns A human-friendly description.\n */\n getDescription() {\n return this.property.description;\n }\n\n /**\n * @returns The type of the global property. Use this to determine how to render the property.\n */\n getType(): AspectType {\n return this.property.type;\n }\n\n /**\n * @returns The underlying property data object.\n */\n getRawProperty(): GlobalPropertyConfigurationAspect {\n return this.property;\n }\n\n /**\n * @returns Whether this aspect has been marked as required to be completed before the user can continue.\n */\n isMandatory(): boolean {\n return !!this.property.mandatory;\n }\n\n /**\n * @returns Whether this aspect has been marked as `completed` for mandatory checks. Note that this function always returns `true` if the aspect has not been marked as mandatory.\n */\n isMandatoryFulfilled(): boolean {\n return (\n !this.property.mandatory ||\n !!this.bundle.getGlobalPropertyStateManager().getAspectMandatoryFulfilled(this.property.name)\n );\n }\n\n /**\n * Applies the global state to all shared steps, if the state is set.\n * @param targetExperiences Optionally filter the workflow experiences it should be applied to.\n */\n abstract applyGlobalState(targetExperiences?: WorkflowExperience[]): Promise<void>;\n\n /**\n * Returns all steps that share this property.\n * @param targetExperiences Optionally filter the steps to only those in the given experiences.\n */\n protected getSharedSteps(targetExperiences?: WorkflowExperience[]) {\n const experiences = targetExperiences ?? this.bundle.getWorkflowExperiences();\n const sharedSteps = experiences.flatMap((e) =>\n e.getStepsConditionallyActive().filter((s) => {\n if (s.getOverrideGlobalPropertyConfiguration(this.property.type)) {\n return false;\n }\n return s\n .getRaw()\n .globalPropertyAspectConfigurations?.some(\n (c) =>\n c.globalPropertyConfigurationId ===\n this.bundle.getProductCollection()?.getResource().globalPropertyConfiguration?.id &&\n c.aspectName === this.property.name,\n );\n }),\n );\n return sharedSteps;\n }\n\n protected getStateValue(): string | undefined {\n return this.bundle.getGlobalPropertyStateManager().getAspect(this.property.name);\n }\n}\n\n/**\n * A file upload global property allows for setting a frame image against all shared steps.\n */\nexport class FileUploadGlobalPropertyHandle extends GlobalPropertyHandle {\n private colorOption?: OptionResource;\n private imageData?: PatternImageData;\n\n constructor(bundle: Bundle, property: GlobalPropertyConfigurationAspect) {\n super(bundle, property);\n }\n\n async initialize(): Promise<FileUploadGlobalPropertyHandle> {\n if (this.property.data?.fileUpload?.colorOptionId) {\n this.colorOption = await optionService.getOption(this.property.data?.fileUpload?.colorOptionId);\n }\n await this.loadImageData();\n return this;\n }\n\n private async loadImageData() {\n const img = await this.getImage();\n if (img?.fileLink) {\n if (img?.fileLink.endsWith(\".svg\")) {\n const originalSvg = await fetchAsString(img?.fileLink);\n const svgData = await GetSVGDimensions(img?.fileLink);\n const width = svgData.width;\n const height = svgData.height;\n const svgAndColors = await generateSVGWithUnknownColors(originalSvg);\n const storage = this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name);\n storage?.colors?.forEach((it) => {\n svgAndColors.colors[it.key] = {\n browserValue: it.browserValue,\n pmsValue: it.pmsValue,\n };\n });\n const data = {\n src: img?.fileLink,\n width,\n height,\n aspect: width / height,\n svg: svgAndColors.svg,\n colors: svgAndColors.colors,\n };\n patternImageDataCache.set(img?.fileLink, data);\n this.imageData = data;\n } else {\n this.imageData = undefined;\n }\n }\n }\n\n /**\n * Select an image to be used for all shared steps.\n * @param asset The asset to use.\n * @returns A promise resolving when all affected steps have been updated.\n */\n async selectImage(asset: Asset) {\n const stateManager = this.bundle.getGlobalPropertyStateManager();\n await Promise.all([\n stateManager.setAspect(\n this.property.name,\n asset.key!,\n {\n ...(stateManager.getAspectStorage(this.property.name) || {}),\n originalAssetKey: asset.key,\n backgroundRemovedAssetKey: undefined,\n useOriginalAsset: undefined,\n },\n undefined,\n ),\n this.applyImageSelection(asset),\n this.loadImageData(),\n ]);\n }\n\n async canUseBackgroundRemover(): Promise<boolean> {\n return this.bundle.getClient().canUseAddon(AddonHandle.BackgroundRemover);\n }\n\n /**\n * Removes the background from an image, stores it in the state, and returns the new asset.\n * @param applyNewAsset Optionally applies the new asset to all shared steps. Default: `true`.\n * @returns A promise that resolves with the newly generated Asset.\n */\n async removeBackgroundFromImage(applyNewAsset = true): Promise<Asset> {\n if (!(await this.canUseBackgroundRemover())) {\n throw new Error(\n \"The current Integration does not have access to the Background Remover. Please call canUseBackgroundRemover to ensure you disable this feature when appropriate.\",\n );\n }\n const image = await this.getOriginalImage();\n if (!image) {\n throw new Error(\"You must supply an image selection before attempting to remove the background.\");\n }\n const stateManager = this.bundle.getGlobalPropertyStateManager();\n const bgRemoved = await assetService.removeBackgroundFromAsset(image);\n const existingStorage = stateManager.getAspectStorage(this.property.name);\n const updatedStorage: GlobalPropertyStateFileUploadStorage = {\n ...existingStorage,\n backgroundRemovedAssetKey: bgRemoved.key,\n useOriginalAsset: !applyNewAsset,\n };\n const updatePromise = applyNewAsset\n ? stateManager.setAspect(this.property.name, bgRemoved.key!, updatedStorage)\n : stateManager.setAspectStorage(this.property.name, updatedStorage);\n const promises = [updatePromise];\n if (applyNewAsset) {\n promises.push(this.applyImageSelection(bgRemoved, undefined, false, false));\n promises.push(this.loadImageData());\n }\n await Promise.all(promises);\n this.updateSharedStepStorage(updatedStorage);\n return bgRemoved;\n }\n\n /**\n * Returns `true` if the state has an image assigned, otherwise `false`.\n */\n hasImage(): boolean {\n return !!this.getStateValue();\n }\n\n /**\n * Retrieves the current image selection, if one exists.\n * @returns A promise that resolves with an `Asset` object if one is assigned to the state, otherwise `undefined`.\n */\n async getImage(): Promise<Asset | undefined> {\n const stateValue = this.getStateValue();\n if (!stateValue) {\n return undefined;\n }\n return assetService.getLocalOrFromServer(stateValue);\n }\n\n async getImageWithColors(): Promise<string | undefined> {\n await this.loadImageData();\n if (!this.imageData?.svg) {\n return this.imageData?.src;\n }\n return svgToDataUrl(modifySVGColors(this.imageData.svg, this.imageData.colors ?? {}, false));\n }\n\n /**\n * Retrieves the original, unmodified image selection, if one exists.\n * @returns A promise that resolves with an `Asset` object if one is assigned to the state, otherwise `undefined`.\n */\n async getOriginalImage(): Promise<Asset | undefined> {\n const storage = this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name);\n if (!storage?.originalAssetKey) {\n return undefined;\n }\n return assetService.getLocalOrFromServer(storage.originalAssetKey);\n }\n\n /**\n * Retrieves the version of the image selection that has the background removed, if one exists.\n * @returns A promise that resolves with an `Asset` object if one is assigned to the state, otherwise `undefined`.\n */\n async getBackgroundRemovedImage(): Promise<Asset | undefined> {\n const storage = this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name);\n if (!storage?.backgroundRemovedAssetKey) {\n return undefined;\n }\n return assetService.getLocalOrFromServer(storage.backgroundRemovedAssetKey);\n }\n\n getUseOriginalImage(): boolean {\n return (\n this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name)?.useOriginalAsset ?? false\n );\n }\n\n async setUseOriginalImage(value: boolean): Promise<void> {\n const originalImage = await this.getOriginalImage();\n if (!originalImage) {\n throw new Error(\"You must select an image before calling setUseOriginalImage\");\n }\n const stateManager = this.bundle.getGlobalPropertyStateManager();\n const existingStorage = stateManager.getAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name);\n if (existingStorage?.useOriginalAsset === value) {\n return;\n }\n const updatedStorage = {\n ...existingStorage,\n useOriginalAsset: value,\n };\n const targetKey = value ? existingStorage?.originalAssetKey : existingStorage?.backgroundRemovedAssetKey;\n const promises = [stateManager.setAspect(this.property.name, targetKey || \"\", updatedStorage)];\n if (value) {\n promises.push(this.applyImageSelection(originalImage, undefined, false, false));\n } else {\n const updateUsingBg = async () => {\n const bgRemovedImage = await this.getBackgroundRemovedImage();\n if (!bgRemovedImage) {\n throw new Error(\n \"You must call removeBackgroundFromImage before attempting to use that version of the image.\",\n );\n }\n this.applyImageSelection(bgRemovedImage, undefined, false, false);\n };\n promises.push(updateUsingBg());\n }\n promises.push(this.loadImageData());\n await Promise.all(promises);\n this.updateSharedStepStorage(updatedStorage);\n }\n\n async applyGlobalState(targetExperiences?: WorkflowExperience[]) {\n const aspect = this.getStateValue();\n if (!aspect) return;\n const asset = await assetService.getLocalOrFromServer(aspect);\n if (!asset) return;\n await this.applyImageSelection(asset, targetExperiences, false, true);\n const storage = this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name);\n if (storage) {\n this.updateSharedStepStorage({ ...storage });\n if (storage.colors) {\n const colorMap = new Map(\n storage.colors!.map((it) => [it.key, { browserValue: it.browserValue, pmsValue: it.pmsValue }]) ??\n [],\n );\n await Promise.all(\n this.getSharedSteps(targetExperiences).map(async (step) => {\n await (step as FrameStepHandle).changeColors(colorMap);\n }),\n );\n }\n } else {\n this.updateSharedStepStorage({ originalAssetKey: aspect });\n await this.bundle\n .getGlobalPropertyStateManager()\n .setAspectStorage(this.property.name, { originalAssetKey: aspect });\n }\n }\n\n getAvailableColors(): ColorOption[] {\n if (!this.property.data?.fileUpload?.colorPickerEnabled) {\n return [];\n }\n return (\n this.colorOption?.variants?.map((variant: VariantResource) => {\n return {\n fill: variant.color,\n stroke: variant.color,\n variant,\n pmsValue: variant.name,\n };\n }) ?? []\n );\n }\n\n getCurrentColors():\n | {\n [key: string]: ColorDefinition;\n }\n | undefined {\n return this.imageData?.colors;\n }\n\n isColorPickerEnabled() {\n return this.property.data?.fileUpload?.colorPickerEnabled ?? false;\n }\n\n isPmsPickerEnabled() {\n return this.property.data?.fileUpload?.pmsPickerEnabled ?? false;\n }\n\n async getOriginalColors(): Promise<\n | {\n [key: string]: ColorDefinition;\n }\n | undefined\n > {\n if (!this.imageData?.svg) {\n return undefined;\n }\n const svgData = await generateSVGWithUnknownColors(this.imageData.svg);\n return svgData.colors;\n }\n\n async changeColors(newFills: { [key: string]: ColorDefinition }): Promise<void> {\n if (!this.imageData?.svg) {\n return;\n }\n const sharedSteps = this.getSharedSteps();\n const fills = new Map(Object.entries(newFills));\n await Promise.all(\n sharedSteps.map(async (step) => {\n const frameStep = step as FrameStepHandle;\n await frameStep.changeColors(fills);\n }),\n );\n const storage = this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name);\n await Promise.all([\n this.bundle\n .getGlobalPropertyStateManager()\n .setAspectStorage<GlobalPropertyStateFileUploadStorage>(this.property.name, {\n ...storage,\n colors: Object.entries(newFills).map(([key, color]) => ({\n key: key,\n browserValue: color.browserValue,\n pmsValue: color.pmsValue,\n })),\n }),\n await this.loadImageData(),\n ]);\n }\n\n private async applyImageSelection(\n asset: Asset,\n targetExperiences?: WorkflowExperience[],\n useAsOriginalImage = true,\n updateFrameOffsets = true,\n ) {\n const sharedSteps = this.getSharedSteps(targetExperiences);\n const experiencesUpdates = sharedSteps.map((step) => {\n const frameStep = step as FrameStepHandle;\n if (!frameStep.getFrameService()) return;\n return frameStep.selectImage(asset, useAsOriginalImage, updateFrameOffsets);\n });\n await Promise.all(experiencesUpdates);\n }\n\n private updateSharedStepStorage(storage: GlobalPropertyStateFileUploadStorage) {\n const experiences = this.bundle.getWorkflowExperiences();\n experiences.forEach((e) =>\n e.getSteps().forEach((s) => {\n if (s.getOverrideGlobalPropertyConfiguration(this.property.type)) {\n return;\n }\n const shouldUpdateStep = s\n .getRaw()\n .globalPropertyAspectConfigurations?.some(\n (c) =>\n c.globalPropertyConfigurationId ===\n this.bundle.getProductCollection()?.getResource().globalPropertyConfiguration?.id &&\n c.aspectName === this.property.name,\n );\n if (shouldUpdateStep) {\n e.getWorkflowManager().updateStorage(s.getId(), {\n framePatternData: {\n originalAssetKey: storage.originalAssetKey,\n backgroundRemovedAssetKey: storage.backgroundRemovedAssetKey,\n useOriginalAsset: storage.useOriginalAsset,\n },\n });\n }\n }),\n );\n }\n}\n\nexport class TextGlobalPropertyHandle extends GlobalPropertyHandle {\n constructor(bundle: Bundle, property: GlobalPropertyConfigurationAspect) {\n super(bundle, property);\n }\n\n /**\n * If this returns false, you should not display any templating tools.\n * Note: Templates will currently still be rendered, regardless of what this function returns.\n */\n isTemplatingEnabled(): boolean {\n return this.property.data?.text?.templatingEnabled || false;\n }\n\n /**\n * Gets the current text\n */\n getText(): string {\n const aspectValue = this.getStateValue();\n if (!aspectValue) return \"\";\n return aspectValue;\n }\n\n /**\n * Set the text.\n */\n async setText(text: string) {\n await Promise.all([\n this.bundle.getGlobalPropertyStateManager().setAspect(this.property.name, text, undefined, undefined),\n this.applyTextSelection(text),\n ]);\n }\n\n async applyGlobalState(targetExperiences?: WorkflowExperience[]) {\n const value = this.getStateValue();\n if (!value) return Promise.resolve();\n await this.applyTextSelection(value, targetExperiences);\n }\n\n private async applyTextSelection(text: string, targetExperiences?: WorkflowExperience[]) {\n const sharedSteps = this.getSharedSteps(targetExperiences);\n const experiencesUpdates = sharedSteps.map((step) => {\n const textStep = step as TextStepHandle;\n textStep.setText(text);\n });\n await Promise.all(experiencesUpdates);\n }\n}\n\n/**\n * An option property handle represents a property that can\n * affect the option of steps across multiple transactions.\n */\nexport class OptionGlobalPropertyHandle extends GlobalPropertyHandle {\n protected optionResource?: OptionResource;\n\n constructor(\n bundle: Bundle,\n property: GlobalPropertyConfigurationAspect,\n optionResource: OptionResource | undefined,\n ) {\n super(bundle, property);\n this.optionResource = optionResource;\n }\n\n /**\n * Ensures the option resource has its variants loaded. If the option was loaded\n * with minimal fields (e.g., lazy loading), this will re-fetch the full option.\n */\n protected async ensureOptionLoaded(): Promise<OptionResource | undefined> {\n if (this.optionResource?.variants) return this.optionResource;\n if (!this.property.entityId) return this.optionResource;\n const option = await optionService.getOption(this.property.entityId);\n if (option) this.optionResource = option;\n return this.optionResource;\n }\n\n /**\n * If the option has a default variant, select it.\n */\n async initDefaultVariant() {\n await this.ensureOptionLoaded();\n const defaultVariant = this.optionResource?.variants?.find(\n (v) => v.id === this.optionResource?.defaultVariant?.id,\n );\n if (defaultVariant) {\n await this.selectVariant(new Variant(defaultVariant));\n }\n }\n\n /**\n * Gets the currently selected variant, or undefined if no variant is selected.\n */\n getCurrentVariant() {\n if (!this.optionResource) return undefined;\n const aspectValue = this.getStateValue();\n if (!aspectValue) {\n const defaultVariant = this.optionResource.variants?.find(\n (v) => v.id === this.optionResource?.defaultVariant?.id,\n );\n if (!defaultVariant) return undefined;\n return new Variant(defaultVariant);\n } else {\n const variantResource = this.optionResource.variants?.find((v) => v.id === aspectValue);\n if (!variantResource) return undefined;\n return new Variant(variantResource);\n }\n }\n\n /**\n * @returns A list of valid variants for this step. Does not include disabled variants.\n */\n async getAvailableVariants() {\n await this.ensureOptionLoaded();\n const variants = this.optionResource?.variants?.filter((v) => v.enabled) || [];\n return variants.map((v) => new Variant(v));\n }\n\n /**\n * @returns A list of all variants for this step, including disabled ones.\n */\n async getAllVariants() {\n await this.ensureOptionLoaded();\n const variants = this.optionResource?.variants || [];\n return variants.map((v) => new Variant(v));\n }\n\n /**\n * Select a given variant on the option for all shared steps.\n * @param variant The variant to select.\n */\n async selectVariant(variant: Variant, channel?: number) {\n await Promise.all([\n this.bundle\n .getGlobalPropertyStateManager()\n .setAspect(this.property.name, variant.getId(), undefined, channel),\n this.applyVariantSelection(variant),\n ]);\n }\n\n async applyGlobalState(targetExperiences?: WorkflowExperience[]) {\n const aspect = this.getStateValue();\n if (!aspect) return;\n await this.ensureOptionLoaded();\n const variant = this.optionResource?.variants?.find((v) => v.id === aspect);\n if (!variant) return;\n return this.applyVariantSelection(new Variant(variant), targetExperiences);\n }\n\n private async applyVariantSelection(variant: Variant, targetExperiences?: WorkflowExperience[]) {\n const sharedSteps = this.getSharedSteps(targetExperiences);\n const promises = sharedSteps.map((step) => {\n return step.selectVariant(variant);\n });\n await Promise.all(promises);\n }\n}\n\n/**\n * A color option property handle represents a property that can\n * affect the option of steps across multiple transactions. This class is a specialization of the OptionGlobalPropertyHandle which includes functionality for\n * setting custom color values when a custom color variant is selected.\n */\nexport class ColorOptionGlobalPropertyHandle extends OptionGlobalPropertyHandle {\n constructor(\n bundle: Bundle,\n property: GlobalPropertyConfigurationAspect,\n optionResource: OptionResource | undefined,\n ) {\n super(bundle, property, optionResource);\n }\n\n /**\n * Select a given variant on the option for all shared steps.\n * @param variant The variant to select.\n */\n override async selectVariant(variant: Variant, channel?: number) {\n await this.bundle\n .getGlobalPropertyStateManager()\n .setAspect(this.property.name, variant.getId(), undefined, channel);\n await this.applyColorVariant(variant, undefined, channel);\n }\n\n override async applyGlobalState(targetExperiences?: WorkflowExperience[]) {\n const aspect = this.getStateValue();\n if (!aspect) return;\n await this.ensureOptionLoaded();\n const variant = this.optionResource?.variants?.find((v) => v.id === aspect);\n if (!variant) return;\n await this.applyColorVariant(new Variant(variant), targetExperiences);\n const customColor = this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateColorOptionStorage>(this.property.name)?.customColor;\n if (customColor) this.setCustomColor(customColor);\n }\n\n private async applyColorVariant(variant: Variant, targetExperiences?: WorkflowExperience[], channel?: number) {\n const sharedSteps = this.getSharedSteps(targetExperiences);\n const promises = sharedSteps.map((step) => {\n switch (step.getType()) {\n case StepType.Shape:\n return step.selectVariant(variant);\n case StepType.Text:\n return (step as TextStepHandle).setFillColor({\n fill: variant.getColor(),\n stroke: variant.getColor(),\n variant: variant.getResource(),\n });\n case StepType.Illustration: {\n const illustrationStep = step as IllustrationStepHandle;\n return illustrationStep.setColor(channel?.toString() || \"\", variant.getColor() || \"\");\n }\n }\n });\n await Promise.all(promises);\n }\n\n /**\n * Sets a custom color on the global state.\n */\n setCustomColor(color: string) {\n const currentColor = this.getCurrentVariant()?.getColor();\n if (currentColor && currentColor.toLowerCase() === \"#custom\") {\n // Only apply to workflows when the variant is custom\n const sharedSteps = this.getSharedSteps() as ShapeStepHandle[];\n sharedSteps.forEach((step) => step.setCustomColor(color));\n }\n this.bundle\n .getGlobalPropertyStateManager()\n .setAspectStorage<GlobalPropertyStateColorOptionStorage>(this.property.name, { customColor: color });\n }\n\n /**\n * Gets the custom color used by the global state.\n */\n getCustomColor(): string {\n return (\n this.bundle\n .getGlobalPropertyStateManager()\n .getAspectStorage<GlobalPropertyStateColorOptionStorage>(this.property.name)?.customColor ||\n this.getCurrentVariant()?.getColor() ||\n \"#ffffff\"\n );\n }\n}\n\nconst getStepsForAspect = (bundle: Bundle, aspectName: string, stepType: StepType): StepHandle<AnyStepData>[] => {\n const experiences = bundle.getWorkflowExperiences();\n const globalConfig = bundle.getGlobalPropertyConfiguration();\n if (!globalConfig) {\n return [];\n }\n const steps = experiences\n .flatMap((ex) => ex.getSteps())\n .filter((s) => s.getGlobalPropertyAspects(globalConfig.id).includes(aspectName) && s.getType() === stepType);\n return steps;\n};\n\n/**\n * Get the amount of channels needed to cover illustration steps of the given aspect name.\n * @param bundle\n * @param aspectName\n * @returns\n */\nexport const amtChannelsForAspect = (bundle: Bundle, aspectName: string): number => {\n const steps = getStepsForAspect(bundle, aspectName, StepType.Illustration) as IllustrationStepHandle[];\n const channelAmts = steps.map((s) => {\n const asset = s.getCurrentVariant()?.getAssetResource();\n if (!asset?.assetConfiguration) {\n return 0;\n }\n const colors = s.getColors();\n if (!colors) {\n return 0;\n }\n return Object.getOwnPropertyNames(colors).length;\n });\n return Math.max(...channelAmts);\n};\n","import omit from \"lodash.omit\";\n\n/**\n * Omits any object key that is in the provided blacklist.\n */\nexport default function omitDeep(input: any, blacklist: string[]) {\n function omitDeepOnOwnProps(obj: any) {\n if (typeof obj === \"undefined\") {\n return obj;\n }\n\n if (!Array.isArray(obj) && !isObject(obj)) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return omitDeep(obj, blacklist);\n }\n\n let o = {};\n for (const [key, value] of Object.entries(obj)) {\n o[key] = !isNil(value) ? omitDeep(value, blacklist) : value;\n }\n return omit(o, blacklist);\n }\n\n if (Array.isArray(input)) {\n return input.map(omitDeepOnOwnProps);\n }\n return omitDeepOnOwnProps(input);\n}\n\nfunction isNil(value: any) {\n return value === null || value === undefined;\n}\n\nfunction isObject(obj: any) {\n return typeof obj == \"object\" && !Array.isArray(obj) && obj !== null;\n}\n","import isEqual from \"lodash.isequal\";\nimport { graphQlManager } from \"../services/server\";\nimport {\n AspectType,\n GlobalPropertyConfiguration,\n GlobalPropertyState,\n GlobalPropertyStateAspectStorage,\n} from \"../types\";\nimport { createGlobalPropertyStateMutation, updateGlobalPropertyStateMutation } from \"./query\";\nimport cloneDeep from \"lodash.clonedeep\";\nimport omitDeep from \"../util/omitDeep\";\n\nexport function calculateMandatoryStates(globalPropertyState: GlobalPropertyState | undefined) {\n const mandatoryFulfilledAspects = new Map<string, boolean>();\n globalPropertyState?.aspects?.forEach((aspect) => {\n // TODO: may need to validate differently for each type of aspect\n if (aspect.value !== \"\") {\n mandatoryFulfilledAspects.set(aspect.name, true);\n }\n // No need to add incomplete aspects\n });\n return mandatoryFulfilledAspects;\n}\n\nexport interface GlobalPropertyStateManager {\n getInitializationPromise(): Promise<void>;\n getGlobalPropertyState(): GlobalPropertyState | undefined;\n setGlobalPropertyState(state: GlobalPropertyState): Promise<void>;\n getAspect(name: string, channel?: number): string | undefined;\n getAspectStorage<S extends GlobalPropertyStateAspectStorage>(name: string, channel?: number): S | undefined;\n getAspectMandatoryFulfilled(name: string): boolean | undefined;\n /**\n * Updates the value of a named aspect in the state.\n * @param name The name (key) of the aspect. This must match the key in the associated Global Property Config\n * @param value The value, represented as a string.\n * @param storage Optional: Additional data storage for the aspect. Not specifying this parameter, or providing `undefined`, will not update the\n * storage (if it already exists). Providing `null` will clear the existing storage.\n * @param channel Optional: Additional sub-identifier.\n */\n setAspect(\n name: string,\n value: string,\n storage?: GlobalPropertyStateAspectStorage | null,\n channel?: number,\n ): Promise<void>;\n setAspectStorage<S extends GlobalPropertyStateAspectStorage>(\n name: string,\n storage: S | null,\n channel?: number,\n ): Promise<void>;\n setBundleOptions(bundleOptions?: BundleOptions): void;\n getBundleOptions(): BundleOptions | undefined;\n setConfiguration(configuration: GlobalPropertyConfiguration | undefined): void;\n clearAspects(names: string[]): Promise<void>;\n}\n\nexport interface BundleOptions {\n additionalHeaders?: { [key: string]: string };\n /**\n * If set to true, the products associated with the bundle will be eagerly fetched.\n */\n eagerFetchProducts?: boolean;\n\n bundleOwnerId?: string;\n\n /**\n * When reloading a bundle we may have an existing state to pull with it.\n */\n existingGlobalPropertyState?: GlobalPropertyState;\n\n readonly?: boolean;\n}\n\n// Omits __typename from state fetched from the network.\n// Need to guarantee this is never present, since the isEqual check appears to fail\n// on this from time to time.\nfunction cloneStateFromNetwork(state: GlobalPropertyState): GlobalPropertyState {\n return omitDeep(state, [\"__typename\"]) as GlobalPropertyState;\n}\n\nexport class GlobalPropertyStateManagerImpl implements GlobalPropertyStateManager {\n private readonly bundleId: string;\n private readonly bundleOwnerId?: string;\n private readonly initPromise: Promise<void>;\n private globalPropertyState?: GlobalPropertyState;\n private readonly onGlobalPropertyStateChange: (\n previousState: GlobalPropertyState,\n newState: GlobalPropertyState,\n ) => Promise<void>;\n private bundleOptions?: BundleOptions;\n private configuration?: GlobalPropertyConfiguration;\n private mandatoryFulfilledAspects = new Map<string, boolean>();\n\n constructor(\n bundleId: string,\n bundleOwnerId: string | undefined,\n configuration: GlobalPropertyConfiguration | undefined,\n onGlobalPropertyStateChange: (\n previousState: GlobalPropertyState,\n newState: GlobalPropertyState,\n ) => Promise<void>,\n bundleOptions?: BundleOptions,\n ) {\n this.bundleId = bundleId;\n this.bundleOwnerId = bundleOwnerId;\n this.configuration = configuration;\n this.bundleOptions = bundleOptions;\n\n const existingState = bundleOptions?.existingGlobalPropertyState;\n this.initPromise = existingState\n ? Promise.resolve(existingState).then(() => {\n console.log(`Setting global property state to existing state.`);\n this.globalPropertyState = cloneStateFromNetwork(existingState);\n this.recalculateMandatoryStates();\n return undefined;\n })\n : this.createGlobalPropertyState().then((state) => {\n console.log(`Setting global property state to new state.`);\n this.globalPropertyState = cloneStateFromNetwork(state);\n this.recalculateMandatoryStates();\n return undefined;\n });\n\n this.onGlobalPropertyStateChange = onGlobalPropertyStateChange;\n }\n\n async clearAspects(names: string[]): Promise<void> {\n if (!this.globalPropertyState) {\n throw new Error(\"Global property state not initialized\");\n }\n const aspects = this.globalPropertyState.aspects;\n this.globalPropertyState.aspects = aspects.filter((a) => !names.includes(a.name));\n\n // clearAspects is currently only used in onGlobalPropertiesChanged, which means\n // we don't have to end this function with the sort of cleanup that setAspect needs.\n }\n\n private recalculateMandatoryStates() {\n this.mandatoryFulfilledAspects = calculateMandatoryStates(this.globalPropertyState);\n }\n\n setBundleOptions(bundleOptions?: BundleOptions) {\n this.bundleOptions = bundleOptions;\n }\n\n getBundleOptions() {\n return this.bundleOptions;\n }\n\n setConfiguration(configuration: GlobalPropertyConfiguration) {\n this.configuration = configuration;\n }\n\n getInitializationPromise(): Promise<void> {\n return this.initPromise;\n }\n\n getGlobalPropertyState(): GlobalPropertyState | undefined {\n return this.globalPropertyState;\n }\n\n async setGlobalPropertyState(state: GlobalPropertyState): Promise<void> {\n if (!this.globalPropertyState) {\n await this.initPromise;\n }\n const previousState = cloneDeep(this.globalPropertyState!);\n this.globalPropertyState = { ...cloneStateFromNetwork(state), id: previousState.id };\n this.recalculateMandatoryStates();\n await this.updateGlobalPropertyState();\n await this.onGlobalPropertyStateChange(previousState, this.globalPropertyState!);\n }\n\n getAspectMandatoryFulfilled(name: string): boolean | undefined {\n return this.mandatoryFulfilledAspects.get(name);\n }\n\n getAspect(name: string, channel?: number): string | undefined {\n if (!this.globalPropertyState) {\n throw new Error(\"Global property state not initialized\");\n }\n const aspect = this.globalPropertyState.aspects.find((a) => a.name === name && a.channel === channel);\n if (aspect) {\n return aspect.value;\n }\n return undefined;\n }\n\n getAspectStorage<S extends GlobalPropertyStateAspectStorage>(name: string, channel?: number): S | undefined {\n if (!this.globalPropertyState) {\n throw new Error(\"Global property state not initialized\");\n }\n return this.globalPropertyState.aspects.find((a) => a.name === name && a.channel === channel)?.storage as\n | S\n | undefined;\n }\n\n async setAspect(\n name: string,\n value: string,\n storage?: GlobalPropertyStateAspectStorage | null,\n channel?: number,\n ): Promise<void> {\n if (!this.globalPropertyState) {\n throw new Error(\"Global property state not initialized\");\n }\n if (!this.configuration) {\n throw new Error(\"Global property configuration not linked to the state manager.\");\n }\n const configAspect = this.configuration.aspects.find((a) => a.name === name);\n if (!configAspect) {\n throw new Error(`Failed to find configuration aspect with name: ${name}`);\n }\n // Update mandatory state\n // Some future steps may need custom logic for this\n this.mandatoryFulfilledAspects.set(name, value !== \"\");\n\n const previousState = cloneDeep(this.globalPropertyState);\n const aspects = this.globalPropertyState.aspects.filter((a) => a.name === name);\n if (aspects.length > 0) {\n if (channel) {\n const aspect = aspects.find((a) => a.channel === channel);\n if (aspect) {\n aspect.value = value;\n aspect.type = configAspect.type;\n aspect.channel = channel;\n if (storage !== undefined) {\n aspect.storage = storage !== null ? storage : undefined;\n }\n } else {\n // We don't have an aspect for that channel.\n if (channel === 1) {\n // Find the aspect with undefined channel so that we can remove it because\n // the aspect with channel 1 will serve that purpose.\n const aspectIndex = this.globalPropertyState.aspects.findIndex(\n (a) => !a.channel && a.name === name,\n );\n if (aspectIndex && aspectIndex > 0) {\n this.globalPropertyState.aspects.splice(aspectIndex, 1);\n }\n }\n this.globalPropertyState.aspects.push({\n name,\n value,\n type: configAspect.type,\n storage: storage !== null ? storage : undefined,\n channel,\n });\n }\n } else {\n const aspect = aspects[0];\n aspect.value = value;\n aspect.type = configAspect.type;\n if (storage !== undefined) {\n aspect.storage = storage !== null ? storage : undefined;\n }\n }\n } else {\n this.globalPropertyState.aspects.push({\n name,\n value,\n type: configAspect.type,\n storage: storage !== null ? storage : undefined,\n channel,\n });\n }\n if (isEqual(previousState, this.globalPropertyState)) {\n return; // No-op\n }\n await this.updateGlobalPropertyState();\n await this.onGlobalPropertyStateChange(previousState, this.globalPropertyState);\n }\n\n async setAspectStorage(\n name: string,\n storage: GlobalPropertyStateAspectStorage | null,\n channel?: number,\n ): Promise<void> {\n if (!this.globalPropertyState) {\n throw new Error(\"Global property state not initialized\");\n }\n if (!this.configuration) {\n throw new Error(\"Global property configuration not linked to the state manager.\");\n }\n const configAspect = this.configuration.aspects.find((a) => a.name === name);\n if (!configAspect) {\n throw new Error(`Failed to find configuration aspect with name: ${name}`);\n }\n const previousState = cloneDeep(this.globalPropertyState);\n const aspects = this.globalPropertyState.aspects.filter((a) => a.name === name);\n if (aspects.length > 0) {\n if (channel) {\n const aspect = aspects.find((a) => a.channel === channel);\n if (aspect) {\n aspect.storage = storage !== null ? storage : undefined;\n aspect.type = configAspect.type;\n }\n } else {\n const aspect = aspects[0];\n aspect.storage = storage !== null ? storage : undefined;\n aspect.type = configAspect.type;\n }\n } else {\n this.globalPropertyState.aspects.push({\n name,\n value: \"\",\n type: configAspect.type,\n storage: storage !== null ? storage : undefined,\n channel,\n });\n }\n if (isEqual(previousState, this.globalPropertyState)) {\n return; // No-op\n }\n await this.updateGlobalPropertyState();\n await this.onGlobalPropertyStateChange(previousState, this.globalPropertyState);\n }\n\n private async updateGlobalPropertyState(): Promise<void> {\n if (!this.globalPropertyState) {\n throw new Error(\"Global property state not initialized\");\n }\n const response = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ globalPropertyStateUpdate: GlobalPropertyState }>({\n mutation: updateGlobalPropertyStateMutation,\n variables: {\n id: this.globalPropertyState.id,\n aspects: this.globalPropertyState.aspects.map((aspect) => {\n let storageInput = !!aspect.type && !!aspect.storage ? {} : undefined;\n if (storageInput) {\n switch (aspect.type) {\n case AspectType.FileUpload: {\n storageInput[\"fileUpload\"] = aspect.storage;\n break;\n }\n case AspectType.Option: {\n storageInput[\"option\"] = aspect.storage;\n break;\n }\n case AspectType.ColorOption: {\n storageInput = aspect.storage;\n break;\n }\n }\n }\n return {\n name: aspect.name,\n value: aspect.value,\n type: aspect.type,\n storage: storageInput,\n channel: aspect.channel,\n };\n }),\n },\n context: {\n headers: {\n bundleOwnerId: this.bundleOwnerId,\n ...this.bundleOptions?.additionalHeaders,\n },\n },\n });\n if (response.data?.globalPropertyStateUpdate) {\n this.globalPropertyState = cloneStateFromNetwork(response.data.globalPropertyStateUpdate);\n } else {\n throw new Error(\"Unable to update global property state\");\n }\n }\n\n private async createGlobalPropertyState(): Promise<GlobalPropertyState> {\n const createResponse = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ globalPropertyStateCreate: GlobalPropertyState }>({\n mutation: createGlobalPropertyStateMutation,\n variables: {\n bundleId: this.bundleId,\n },\n context: {\n headers: {\n bundleOwnerId: this.bundleOwnerId,\n ...this.bundleOptions?.additionalHeaders,\n },\n },\n });\n if (createResponse.data?.globalPropertyStateCreate && createResponse.data.globalPropertyStateCreate.id) {\n return createResponse.data.globalPropertyStateCreate;\n }\n throw new Error(`Unable to create global property state for bundle: ${this.bundleId}`);\n }\n}\n","import { BundleStateData } from \"../types\";\n\n/**\n * Helpful state serialization and deserialization for bundle state, which can be used to persist and restore information related to a bundle.\n */\nexport class BundleStateManager {\n private state: BundleStateData;\n\n constructor(stateData?: string) {\n this.setState(stateData || `{\"transactions\": []}`);\n }\n\n setState(stateData?: string) {\n if (!stateData) {\n return;\n }\n this.state = JSON.parse(stateData);\n }\n\n getState() {\n return this.state;\n }\n\n removeStateForTransaction(transactionId: string) {\n if (!this.state || !this.state.transactions) {\n return;\n }\n const index = this.state.transactions.findIndex((t) => t.transactionId === transactionId);\n if (index !== -1) {\n this.state.transactions.splice(index, 1);\n }\n }\n\n getSerializedState() {\n if (!this.state) {\n return undefined;\n }\n this.deleteFieldNameFromObjectRecursive(this.state, \"__typename\");\n return JSON.stringify(this.state);\n }\n\n private deleteFieldNameFromObjectRecursive(obj: any, fieldName: string) {\n if (typeof obj !== \"object\" || obj === null) {\n return;\n }\n for (const key in obj) {\n if (key === fieldName) {\n delete obj[key];\n } else {\n this.deleteFieldNameFromObjectRecursive(obj[key], fieldName);\n }\n }\n }\n}\n","import { gql } from \"@apollo/client/core\";\nimport { graphQlManager } from \"./server\";\n\n/** For fetching metafields on many entities at once */\nconst metafieldsQuery = gql`\n query GetManyMetafields($entityIds: [String!]!) {\n metafieldsMany(entityIds: $entityIds) {\n id\n value\n metafieldConfiguration {\n id\n name\n }\n }\n }\n`;\n\n// This is a helper class that can be used to load metafields for a given entity.\n// It will load the metafields for the entity and store them in a map.\n// TODO: There are a number of areas in the code that request metafields in manual ways. Update each to use this service.\nclass MetafieldManager {\n readonly internalMap = new Map<string, { key: string; value: string }[]>();\n\n /**\n * Given a specific entity, request the given keys for that entity.\n * This will first check if the keys are already present in the internal map, and if not, it will fetch them from the server.\n * @param entityId The entity to check.\n * @param keys The keys to look for.\n * @returns Returns map of keys and values for the given entity. Missing keys will not be present. Use map.has() to check if a key was present.\n */\n async requestKeysForEntity(entityId: string, keys: string[]): Promise<Map<string, string>> {\n const loadedKeys = new Map<string, string>();\n await this.ensureIdsArePresent([entityId]);\n keys.forEach((key) => {\n const value = this.requestKeyForEntityIfAvailable(entityId, key);\n if (value) {\n loadedKeys.set(key, value);\n }\n });\n return loadedKeys;\n }\n\n async ensureIdsArePresent(entityIds: string[]) {\n // If ids are already present we bust out, we already have what we need\n if (entityIds.every((id) => this.internalMap.has(id))) return;\n // Request the metafields for required entities.\n const queryResponse = await graphQlManager.getShadowGraphqlClient().query<{\n metafieldsMany: { id: string; value: string; metafieldConfiguration: { id: string; name: string } }[][];\n }>({\n query: metafieldsQuery,\n errorPolicy: \"all\",\n variables: {\n entityIds: entityIds.filter((id) => !this.internalMap.has(id)),\n },\n });\n // Map the data to a better representation for retrieval.\n entityIds.forEach((id, idx) => {\n const entityFields = queryResponse.data.metafieldsMany[idx];\n this.internalMap.set(\n id,\n entityFields.map((lf) => {\n return { key: lf.metafieldConfiguration.name, value: lf.value };\n }),\n );\n });\n }\n\n /**\n * Returns a metafield for this product if available. Fetching from the server if not available locally.\n * @param entityId The entity to request a field for.\n * @param key The field name to request\n * @returns A promise resolving to the field if available or undefined if not.\n */\n async requestKeyForEntity(entityId: string, key: string): Promise<string | undefined> {\n if (!this.internalMap.has(entityId)) {\n return undefined;\n }\n let entityFields = this.internalMap.get(entityId)!;\n const field = entityFields.find((ef) => ef.key === key);\n if (!field) {\n await this.ensureIdsArePresent([entityId]);\n entityFields = this.internalMap.get(entityId)!;\n }\n return field ? JSON.parse(field.value) : undefined;\n }\n\n /**\n * Returns a metafield for this product if available. Checks locally only, use ensureIdsArePresent to fetch first from the server.\n * @param entityId The entity to request a field for.\n * @param key The field name to request\n * @returns A promise resolving to the field if available or undefined if not.\n */\n requestKeyForEntityIfAvailable(entityId: string, key: string): string | undefined {\n if (!this.internalMap.has(entityId)) {\n return undefined;\n }\n const entityFields = this.internalMap.get(entityId)!;\n const field = entityFields.find((ef) => ef.key === key);\n if (!field) {\n return undefined;\n }\n return JSON.parse(field.value);\n }\n}\n\nconst metafieldManager = new MetafieldManager();\n\nexport { metafieldManager };\n","import { gql } from \"@apollo/client/core\";\nimport {\n getProductCollectionProductsQuery,\n getProductCollectionProductsFilteredQuery,\n getProductCollectionProductsFeedQuery,\n productCollectionFieldsFragment,\n} from \"./Bundle/query\";\nimport { metafieldManager } from \"./services/metafield\";\nimport { graphQlManager } from \"./services/server\";\nimport {\n IntegrationProductResource,\n IntegrationType,\n ProductCollectionResource,\n Product,\n ProductWorkflow as ProductWorkflowInterface,\n ProductCollectionProductResource,\n Asset,\n} from \"./types\";\nimport { ClientError } from \"./util/exception\";\nimport cloneDeep from \"lodash.clonedeep\";\n\ninterface MetafieldFilter {\n operator: \"Equals\" | \"IsEmpty\";\n invert?: boolean;\n metafieldConfigurationId: string;\n value?: string;\n}\n\ninterface ProductTagFilter {\n /** Only products with tags matching all entries in this array will be included. */\n include: string[];\n /** Only products that have no tags matching any entry in this array will be included. */\n exclude: string[];\n}\n\nexport enum ProductCollectionProductSortKey {\n Default = \"Default\",\n Name = \"Name\",\n Price = \"Price\",\n}\n\ninterface FilteredProductCollectionQueryResponse {\n productCollections: {\n id: string;\n productCollectionProducts: { id: string; product: { id: string } }[];\n }[];\n}\n\n/**\n * A collection of products that can be used to form a bundle.\n */\nexport class ProductCollection {\n private readonly collection: ProductCollectionResource;\n private fullFetched = false;\n\n constructor(collection: ProductCollectionResource) {\n this.collection = collection;\n // When the collection passed in as the basis for this class\n // contains products we know the products were eagerly fetched.\n const products = this.collection.productCollectionProducts;\n if (products && products.length > 0) {\n this.fullFetched = true;\n }\n }\n\n /**\n * The ID of the product collection.\n */\n getId(): string {\n return this.collection.id;\n }\n\n /**\n * The name of the collection.\n */\n getName(): string {\n return this.collection.name;\n }\n\n /**\n * The description of the collection.\n */\n getDescription(): string {\n return this.collection.description || \"\";\n }\n\n /**\n * The start date of the dispatch.\n * @returns The start date of the dispatch or undefined if not set.\n */\n getDispatchStartDate(): Date | undefined {\n if (!this.collection.dispatchStartDate) return undefined;\n return new Date(this.collection.dispatchStartDate);\n }\n\n /**\n * The end date of the dispatch.\n * @returns The end date of the dispatch or undefined if not set.\n */\n getDispatchEndDate(): Date | undefined {\n if (!this.collection.dispatchEndDate) return undefined;\n return new Date(this.collection.dispatchEndDate);\n }\n\n /**\n * The image of the collection.\n */\n getImage(): undefined | Asset {\n return this.collection.image;\n }\n\n /**\n * A list of products in this collections with useful helpers for interacting with them.\n */\n getProducts(): CollectionProduct[] {\n if (!this.collection.productCollectionProducts) {\n throw new Error(\"Failed to find products on collection. Ensure you fetch them first!\");\n }\n return this.collection.productCollectionProducts\n .filter((pcp) => !!pcp.product)\n .map((pcp) => {\n return new CollectionProduct(pcp);\n });\n }\n\n /**\n * A list of products in this collections with useful helpers for interacting with them.\n */\n async fetchProducts(productIds?: string[]): Promise<CollectionProduct[]> {\n if (this.fullFetched) {\n return (this.collection.productCollectionProducts ?? []).filter((pcp) => !!pcp.product).map((pcp) => {\n return new CollectionProduct(pcp);\n });\n }\n const response = await graphQlManager\n .getShadowGraphqlClient()\n .query<{ productCollections: ProductCollectionResource[] }>({\n query: getProductCollectionProductsQuery,\n variables: {\n id: this.getId(),\n productIds,\n },\n errorPolicy: \"all\",\n });\n if (!productIds) {\n this.fullFetched = true;\n }\n this.collection.productCollectionProducts = response.data.productCollections[0].productCollectionProducts || [];\n return this.collection.productCollectionProducts\n .filter((pcp) => !!pcp.product)\n .map((pcp) => {\n return new CollectionProduct(pcp);\n });\n }\n\n /**\n * Returns a list of collections products matching the associated metafield/tag filters.\n * @param filters A list of metafield filters to apply.\n * @param tags An object of tag filters to apply.\n */\n async filterProducts(\n filters?: MetafieldFilter[],\n tags?: ProductTagFilter,\n sortKey?: ProductCollectionProductSortKey,\n sortDescending?: boolean,\n ) {\n const response = await graphQlManager.getShadowGraphqlClient().query<FilteredProductCollectionQueryResponse>({\n query: getProductCollectionProductsFilteredQuery,\n errorPolicy: \"all\",\n variables: {\n id: this.getId(),\n filters: filters\n ? {\n link: \"And\",\n metafields: filters,\n }\n : undefined,\n tags: tags\n ? {\n include: tags.include ?? [],\n exclude: tags.exclude ?? [],\n }\n : undefined,\n sortKey: sortKey,\n sortDescending: sortDescending,\n },\n });\n if (!response.data?.productCollections || response.data?.productCollections.length === 0) {\n throw new Error(\"Failed to filter product collection products.\");\n }\n const currentProducts = this.getProducts();\n const filteredResults = response.data.productCollections[0].productCollectionProducts.map(\n (it) => it.product.id,\n );\n return currentProducts.filter((it) => filteredResults.includes(it.getId()));\n }\n\n /**\n * Fetches a paginated feed of products.\n * @param offset The zero-based start index.\n * @param limit The maximum number of products to return.\n * @param productFilters Optional product metafields to filter the products by.\n * @param tags Optional object of tag filters to apply.\n * @param sortKey Optional field of the products to sort by.\n * @param sortDescending Optional boolean to indicate if the sort should be in descending order.\n * @param quickSearch Optional string to filter products by name.\n * @param workflowFilters Optional workflow metafields to filter the products and their workflows by.\n * @returns\n */\n async fetchProductsFeed(\n offset: number,\n limit: number,\n productFilters?: MetafieldFilter[],\n tags?: ProductTagFilter,\n sortKey?: ProductCollectionProductSortKey,\n sortDescending?: boolean,\n quickSearch?: string,\n workflowFilters?: MetafieldFilter[],\n ): Promise<{\n items: CollectionProduct[];\n total: number;\n }> {\n if (this.fullFetched) {\n // Local pagination\n const filteredProducts = await (productFilters\n ? this.filterProducts(productFilters)\n : this.fetchProducts());\n return {\n total: filteredProducts.length,\n items: filteredProducts.slice(offset, offset + limit),\n };\n }\n const abortController = new AbortController();\n const { signal } = abortController;\n const observable = graphQlManager\n .getShadowGraphqlClient()\n .watchQuery<{ productCollections: ProductCollectionResource[] }>({\n query: getProductCollectionProductsFeedQuery,\n variables: {\n id: this.getId(),\n limit,\n offset,\n productFilters: productFilters\n ? {\n link: \"And\",\n metafields: productFilters,\n }\n : undefined,\n productWorkflowFilters: workflowFilters\n ? {\n link: \"And\",\n metafields: workflowFilters,\n }\n : undefined,\n tags: tags\n ? {\n include: tags.include ?? [],\n exclude: tags.exclude ?? [],\n }\n : undefined,\n sortKey: sortKey,\n sortDescending: sortDescending,\n quickSearch,\n },\n errorPolicy: \"all\",\n fetchPolicy: \"cache-first\",\n returnPartialData: true,\n context: {\n fetchOptions: {\n signal,\n },\n },\n });\n // HACK: Apollo's query caching doesn't play nicely with nullable fields, so instead we're using a watchQuery which can resolve data that Apollo\n // believes it needs to refetch, and then cancelling the query once we have what we want.\n // Some cleaner alternatives include:\n // - Marking the nullable fields as intentionally nullable in Apollo's cache config\n // - Replacing Apollo with something that handles caching better\n return new Promise((resolve) => {\n let fetched = false;\n const subscription = observable.subscribe({\n next(value) {\n if (fetched) {\n return;\n }\n if (\n value.partial &&\n (!value.data.productCollections ||\n value.data.productCollections.length === 0 ||\n !value.data.productCollections[0].productCollectionProductsFeed?.items ||\n value.data.productCollections[0].productCollectionProductsFeed?.items.length === 0)\n ) {\n return; // Wait for full data\n }\n abortController.abort();\n fetched = true;\n subscription.unsubscribe();\n const items =\n value.data.productCollections?.[0].productCollectionProductsFeed?.items\n .filter((pcp) => !!pcp.product)\n .map((pcp) => {\n return new CollectionProduct(cloneDeep(pcp));\n }) || [];\n resolve({\n items: items, // Clone items because it could be cached data (immutable)\n total: value.data.productCollections?.[0].productCollectionProductsFeed?.total ?? 0,\n });\n },\n error() {\n if (fetched) {\n return;\n }\n fetched = true;\n subscription.unsubscribe();\n resolve({ items: [], total: 0 });\n },\n });\n });\n }\n\n /**\n * The raw collection resource. This is generally not needed and should be avoided.\n */\n getResource(): ProductCollectionResource {\n return this.collection;\n }\n}\n\n/**\n * A collection product is a product within a ProductCollection. It provides a simple interface for interacting with the product.\n */\nexport class CollectionProduct {\n private readonly product: Product;\n private readonly productResource: ProductCollectionProductResource;\n\n constructor(productCollectionProduct: ProductCollectionProductResource) {\n this.product = productCollectionProduct.product; // Code should not attempt to use the CollectionProduct() constructor on PCPs with a null product.\n this.productResource = productCollectionProduct;\n }\n\n /**\n * The ID of the product in SpiffCommerce.\n * @returns\n */\n getId(): string {\n return this.product.id;\n }\n\n /**\n * The name of the product. Human readable.\n */\n getName(): string {\n return this.product.name;\n }\n\n /**\n * A helper function for getting integrations\n * @param type The type of integration you want.\n * @param externalId An external integration ID to further filter by. Otherwise we return the first encountered.\n * @returns The integration if found. Throws an error if not found as this data is typically a neccesity.\n */\n getIntegrationByType(type: IntegrationType, externalId?: string): IntegrationProductResource {\n const ips = this.product.integrationProducts || [];\n const ip = ips.find((ip) => {\n const hasType = ip.integration?.type;\n const typeMatches = ip.integration?.type === type;\n const externalIdMatches = externalId ? ip.integration?.externalIntegrationId === externalId : true;\n return hasType && typeMatches && externalIdMatches;\n });\n if (!ip) {\n throw new Error(\n \"Failed to find requested integration type on product. This is generally due to a configuration error\",\n );\n }\n return ip;\n }\n\n getCurrentIntegration(): IntegrationProductResource {\n const ips = this.product.integrationProducts || [];\n const ip = ips.find((ip) => ip.integration?.isCurrent);\n if (!ip) {\n throw new Error(\n `Product: ${this.productResource.id} is not linked to this current integration. This is generally due to a configuration error.`,\n );\n }\n return ip;\n }\n\n /**\n * A helper function for pulling the default workflow.\n */\n getDefaultWorkflow(): ProductWorkflow {\n const workflows = this.product.workflows;\n\n if (workflows === undefined) {\n throw new ClientError(\n \"Called getDefaultWorkflow() before fetching collection products. Use collection.fetchProducts() first to ensure the data is available.\",\n );\n }\n\n if (workflows.length === 0) {\n throw new ClientError(\n \"Called getDefaultWorkflow() but no workflows on requested product. Ensure at least 1 workflow is assigned to this product.\",\n );\n }\n\n // Check for a default configured on the collection\n const configuredDefault = this.productResource.workflowId;\n if (configuredDefault) {\n const found = workflows.find((w) => w.workflowName === configuredDefault);\n if (found) return new ProductWorkflow(found);\n }\n\n if (workflows.length === 1) {\n return new ProductWorkflow(workflows[0]);\n }\n\n throw new ClientError(\n \"Called getDefaultWorkflow() but no default workflow is configured for the requested product. Multiple workflows exist so we can't assume!\",\n );\n }\n\n /**\n * @returns All workflows associated with this Product.\n */\n getAllWorkflows(): ProductWorkflow[] {\n const workflows = this.product.workflows || [];\n\n if (workflows.length === 0) {\n throw new ClientError(\n \"No workflows on configured product. Ensure at least 1 workflow is assigned to this product.\",\n );\n }\n return this.product\n .workflows!.sort((a, b) => (a.index ?? 0) - (b.index ?? 0))\n .map((workflow) => new ProductWorkflow(workflow));\n }\n\n /**\n * A list of all integrations this product is connected to.\n */\n getIntegrations(): IntegrationProductResource[] {\n return this.product.integrationProducts || [];\n }\n\n /**\n * The raw product resource. This is generally not needed and should be avoided.\n */\n getResource(): Product {\n return this.product;\n }\n\n /**\n * Gets the base price of the product. Optionally include additional product pricing.\n * @param includeAdditionalProduct Optionally include additional product pricing. You must provide at least one of the fields on this object.\n * @returns\n */\n getBasePrice(includeAdditionalProduct?: {\n /**\n * The integration type to locate the additional product on.\n */\n integrationType?: IntegrationType;\n /**\n * The external ID of the integration to locate the additional product on.\n */\n externalId?: string;\n /**\n * The internal Spiff integration ID to locate the additional product on.\n */\n integrationId?: string;\n }): number {\n const price = this.product.basePrice || 0;\n if (!includeAdditionalProduct) return price;\n if (\n !includeAdditionalProduct.integrationType &&\n !includeAdditionalProduct.externalId &&\n !includeAdditionalProduct.integrationId\n ) {\n throw new Error(\n \"You must provide at least one of the following fields on the includeAdditionalProduct object: integrationType, externalId, integrationId\",\n );\n }\n let ip: IntegrationProductResource | undefined;\n if (includeAdditionalProduct.integrationId) {\n ip = this.product.integrationProducts?.find(\n (ip) => ip.integration?.id === includeAdditionalProduct.integrationId,\n );\n } else if (includeAdditionalProduct.externalId) {\n ip = this.product.integrationProducts?.find(\n (ip) => ip.integration?.externalIntegrationId === includeAdditionalProduct.externalId,\n );\n } else {\n ip = this.product.integrationProducts?.find(\n (ip) => ip.integration?.type === includeAdditionalProduct.integrationType,\n );\n }\n if (!ip?.additionalIntegrationProduct?.product) return price;\n return price + (ip.additionalIntegrationProduct.product.basePrice || 0);\n }\n\n /**\n * Requests a set of metafields for this product. Metafields that are not available locally will be fetched from the server.\n * @param keys The set of metafield keys to request.\n * @returns A map of metafield key to value. Any unavailable keys will not be present in the map. use map.has() to check if a key is present.\n */\n async requestMetafields(keys: string[]): Promise<Map<string, string>> {\n return metafieldManager.requestKeysForEntity(this.product.id, keys);\n }\n}\n\n/**\n * Represents a the relationship between a workflow and a product.\n */\nexport class ProductWorkflow {\n private readonly workflow: ProductWorkflowInterface;\n\n constructor(workflow: ProductWorkflowInterface) {\n this.workflow = workflow;\n }\n\n /**\n * @returns The ID of this workflow, to be used when starting an experience.\n */\n getId(): string {\n return this.workflow.workflowName;\n }\n\n /**\n * @returns The name of the workflow.\n */\n getName(): string {\n return this.workflow.friendlyName;\n }\n\n /**\n * An image to be used to display this workflow in a UI to the customer.\n * @returns A resource URL.\n */\n getThumbnail(): string {\n return this.workflow.imageUrl;\n }\n}\n\nconst getCollectionsQuery = gql`\n ${productCollectionFieldsFragment(false)}\n query GetProductCollections($ids: [String!]!) {\n productCollections(ids: $ids) {\n ...ProductCollectionFields\n }\n }\n`;\n\nexport const getProductCollections = async (ids: string[]): Promise<ProductCollection[] | undefined> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n productCollections: ProductCollectionResource[];\n }>({\n query: getCollectionsQuery,\n errorPolicy: \"all\",\n variables: {\n ids: ids,\n },\n });\n return response.data?.productCollections?.map((it) => new ProductCollection(it));\n};\n","// An EventMap specifies the types of events and what payload they expect.\n// This allows for type-safe event handling in TypeScript.\ntype EventMap = {\n [event: string]: any;\n};\n\n// A generic event emitter which can be used anywhere with customizable event shapes & naming.\n// TODO: 'once' listeners\nexport class EventEmitter<T extends EventMap> {\n private listeners: {\n [K in keyof T]?: Array<(payload: T[K]) => void>;\n } = {};\n\n // Add a listener for a specific event type\n on<K extends keyof T>(event: K, listener: (payload: T[K]) => void): void {\n if (!this.listeners[event]) {\n this.listeners[event] = [];\n }\n this.listeners[event]!.push(listener);\n }\n\n // Remove a listener for a specific event type\n off<K extends keyof T>(event: K, listener: (payload: T[K]) => void): void {\n if (!this.listeners[event]) return;\n this.listeners[event] = this.listeners[event]!.filter((l) => l !== listener);\n }\n\n // Emit an event with the given payload\n emit<K extends keyof T>(event: K, payload: T[K]): void {\n if (!this.listeners[event]) return;\n for (const listener of this.listeners[event]!) {\n listener(payload);\n }\n }\n\n // Clear all listeners for a specific event or all events\n clear<K extends keyof T>(event?: K): void {\n if (event) {\n delete this.listeners[event];\n } else {\n for (const key in this.listeners) {\n delete this.listeners[key as keyof T];\n }\n }\n }\n}\n","import { WorkflowExperience } from \"../WorkflowExperience\";\nimport { GetWorkflowGraphqlOptions, SpiffCommerceClient } from \"../client\";\nimport { graphQlManager } from \"../services/server\";\nimport {\n AspectType,\n BundleDesignCreationMessage,\n Bundle as BundleEntity,\n BundleStakeholder,\n BundleStakeholderInput,\n CustomerDetailsInput,\n GlobalPropertyConfiguration,\n GlobalPropertyState,\n GlobalPropertyStateColorOptionStorage,\n GlobalPropertyStateFileUploadStorage,\n Order,\n ProductCollectionResource,\n ShareAction,\n StakeholderType,\n StepType,\n Transaction,\n} from \"../types\";\nimport {\n bundleAddStakeholderMutation,\n bundleAddTransactionMutation,\n bundleAddTransactionsMutation,\n bundleApprovalQuery,\n bundleAssignGlobalPropertyConfiguration,\n bundleAssignProductCollectionMutation,\n bundleRejectionQuery,\n bundleRemoveStakeholderMutation,\n bundleRemoveTransactionMutation,\n bundleRemoveTransactionsMutation,\n bundleUpdateStakeholdersMutation,\n bundleUpdateTransactionOrderMutation,\n finalizeUpdateBundleMutation,\n getBundleStakeholdersQuery,\n updateBundleMutation,\n} from \"./query\";\nimport {\n amtChannelsForAspect,\n GlobalPropertyHandle,\n GlobalPropertyHandleService,\n OptionGlobalPropertyHandle,\n ColorOptionGlobalPropertyHandle,\n FileUploadGlobalPropertyHandle,\n TextGlobalPropertyHandle,\n} from \"../GlobalPropertyConfiguration\";\nimport {\n BundleOptions,\n GlobalPropertyStateManager,\n GlobalPropertyStateManagerImpl,\n calculateMandatoryStates,\n} from \"../GlobalPropertyStateManager\";\nimport type { DesignCreationProgressUpdate, WorkflowManager } from \"../WorkflowManager\";\nimport { BundleStateManager } from \"./stateManager\";\nimport { persistenceService } from \"../services/persistence\";\nimport { ProductCollection } from \"../productCollection\";\nimport { createDesigns } from \"../services/design\";\nimport type { ModelContainer, ThreeDPreviewService } from \"@spiffcommerce/preview\";\nimport { gql } from \"@apollo/client/core\";\nimport type { CompleteQuoteMessage } from \"@spiffcommerce/theme-bridge\";\nimport { EventEmitter } from \"../util/event\";\nimport { BundleEvent, BundleEventMap } from \"./event\";\nimport { getAssets } from \"../services/asset\";\nimport isEqual from \"lodash.isequal\";\n\nconst addAddressToBundleMutation = gql`\n mutation AddAddressToBundle(\n $bundleId: String!\n $streetAddress: String\n $apartment: String\n $city: String\n $country: String\n $state: String\n $postCode: String\n ) {\n addressAttachToBundle(\n bundleId: $bundleId\n streetAddress: $streetAddress\n apartment: $apartment\n city: $city\n country: $country\n state: $state\n postCode: $postCode\n ) {\n id\n }\n }\n`;\n\nconst addOrganizationToBundleMutation = gql`\n mutation AddOrganizationToBundle($bundleId: String!, $organizationName: String!) {\n organizationAttachToBundle(bundleId: $bundleId, organizationName: $organizationName) {\n id\n }\n }\n`;\n\nconst generateQuoteIdMutation = gql`\n mutation GenerateQuoteId($id: String!) {\n bundleGenerateQuoteId(id: $id) {\n id\n quoteId\n }\n }\n`;\n\n/**\n * A bundle serves as a container for a set of workflow experience.\n */\nexport interface Bundle {\n /**\n * @returns The client that this bundle is associated with.\n */\n getClient(): SpiffCommerceClient;\n\n /**\n * @returns The id of the bundle entity in the Spiff Commerce system.\n */\n getId(): string;\n\n /**\n * @returns The name of the bundle.\n */\n getName(): string;\n\n /**\n * @returns True if this bundle is a template, false otherwise.\n */\n getTemplate(): boolean;\n\n /**\n * @returns The quote id of the bundle, if it has one.\n * This is used to identify the bundle in the Spiff Commerce system for quoting purposes.\n */\n getQuoteId(): string | undefined;\n\n /**\n * Set the name of the bundle.\n * @param name The new name for the bundle.\n * @returns A promise that resolves when the name has been updated in the Spiff Commerce system.\n */\n setName(name: string): Promise<void>;\n\n setDispatchDate(dd: string): Promise<void>;\n\n getDispatchDate(): string | undefined;\n\n setPurchaseOrder(po: string): Promise<void>;\n\n getPurchaseOrder(): string | undefined;\n\n /**\n * @returns Custom metadata associated with this bundle.\n */\n getMetadata(): Map<string, string>;\n\n /**\n * Set custom metadata associated with this bundle.\n * @param metadata Updated map of metadata items.\n * @returns A promise that resolves when the metadata has been updated in the Spiff Commerce system.\n */\n setMetadata(metadata: Map<string, string>): Promise<void>;\n\n /**\n * Set the name and metadata for this bundle.\n * @param name The new name for the bundle.\n * @param metadata Updated map of metadata items.\n * @returns A promise that resolves when the name and metadata have been updated in the Spiff Commerce system.\n */\n setNameAndMetadata(name: string, metadata: Map<string, string>): Promise<void>;\n\n /**\n * Returns true if this bundle is associated with a Product Collection that is linked to a Global Property Configuration\n */\n hasGlobalProperties(): boolean;\n\n /**\n * Get a handle to the global properties available within this bundle. Setting values\n * via this method will make selections on all bundles that share the property.\n */\n getGlobalProperties(): Promise<GlobalPropertyHandle[]>;\n\n /**\n * Get the low level state manager for this bundle. Don't use this unless you know what you're doing.\n */\n getGlobalPropertyStateManager(): GlobalPropertyStateManager;\n\n /**\n * Get the total in subunits for all global properties in this bundle.\n */\n getGlobalPropertyTotalSubunits(): Promise<number>;\n\n /**\n * Return the total in subunits for this bundle. This is the sum of the total for all individual transactions.\n */\n getTotalSubunits(): number;\n\n /**\n * Retrieves the product collection associated with this bundle.\n * If the bundle is not associated with a product collection, this method will return undefined.\n */\n getProductCollection(): ProductCollection | undefined;\n\n /**\n * Add another workflow experience to this bundle.\n * @param experience The workflow experience to add to this bundle.\n */\n addWorkflowExperience(experience: WorkflowExperience): Promise<void>;\n\n /**\n * Adds multiple workflow experiences to this bundle.\n * @param experiences The workflow experiences to add to this bundle.\n */\n addWorkflowExperiences(experiences: WorkflowExperience[]): Promise<void>;\n\n /**\n * Remove a workflow experience from this bundle.\n * @param experience The workflow experience to remove from this bundle.\n */\n removeWorkflowExperience(experience: WorkflowExperience): Promise<void>;\n\n /**\n * Removes multiple workflow experiences from this bundle.\n * @param experiences The workflow experiences to remove from this bundle.\n */\n removeWorkflowExperiences(experiences: WorkflowExperience[]): Promise<void>;\n\n /**\n * Remove a workflow experience from this bundle by transaction.\n * @param transaction The transaction to remove from this bundle.\n */\n removeWorkflowExperienceByTransaction(transaction: Transaction): Promise<void>;\n\n /**\n * Removes multiple workflow experiences from this bundle by their transactions.\n * @param transactions The transactions to remove from this bundle.\n */\n removeWorkflowExperiencesByTransactions(transactions: Transaction[]): Promise<void>;\n\n /**\n * Inserts the given workflow experience into the bundle at the given index.\n * NOTE: If you intend to insert a workflow experience at the end of the bundle, use `addWorkflowExperience` instead as it is more efficient.\n * @param experience The workflow experience to insert.\n * @param index The index to insert the workflow experience at.\n */\n insertWorkflowExperience(experience: WorkflowExperience, index: number): Promise<void>;\n\n /**\n * Replaces a workflow experience at the given index with the given workflow experience. This essentially removes the old one and inserts the new one.\n * @param index The index to replace the workflow experience at.\n * @param experience The workflow experience to replace the old one with.\n */\n replaceWorkflowExperience(index: number, experience: WorkflowExperience): Promise<void>;\n\n /**\n * Swaps the workflow experiences at the given indices.\n */\n swapWorkflowExperiences(a: number, b: number): Promise<void>;\n\n /**\n * Returns all workflow experiences currently added to this bundle.\n */\n getWorkflowExperiences(): WorkflowExperience[];\n\n /**\n * Sort the list of workflow experiences. The sorting is performed locally, and then the order is updated in the Spiff Commerce system.\n * @returns A promise that resolves when the re-ordering of the workflow experiences has been updated in the Spiff Commerce system.\n * The sorting will occur immediately, but the promise will not resolve until the Spiff Commerce system has been updated.\n */\n sortWorkflowExperiences(sortFunc: (expA: WorkflowExperience, expB: WorkflowExperience) => number): Promise<void>;\n\n /**\n * @returns The number of workflow experiences in this bundle.\n */\n getWorkflowExperienceCount(): number;\n\n /**\n * Add a stakeholder to this bundle. If the stakeholder already exists, it will be updated. Write access to the bundle is required.\n * @param customerDetails The details of the customer to add. The emailAddress field is required.\n * @param stakeholderType The type of stakeholder to add. Defaults to Owner.\n */\n addStakeholder(customerDetails: CustomerDetailsInput, stakeholderType?: StakeholderType): Promise<void>;\n\n /**\n * Removes a stakeholder from this bundle. Write access to the bundle is required.\n * @param emailAddress The email address of the stakeholder to remove.\n */\n removeStakeholder(emailAddress: string): Promise<void>;\n\n /**\n * Updates all stakeholders associated with this bundle. Write access to the bundle is required.\n * @param stakeholders An array of stakeholders to update. Unknown stakeholders will be added, and absent stakeholders will be removed.\n */\n updateStakeholders(stakeholders: BundleStakeholderInput[]): Promise<void>;\n\n /**\n * Retrieves all stakeholders associated with this bundle.\n */\n getAllStakeholders(): Promise<BundleStakeholder[]>;\n\n /**\n * Retrieves the current stakeholder for this bundle. This is the stakeholder that has write access to the bundle.\n * If no stakeholder has write access, this will return undefined.\n * @returns A promise that resolves with the current stakeholder, or undefined if no stakeholder has write access.\n */\n getCurrentStakeholder(): Promise<BundleStakeholder | undefined>;\n\n /**\n * Finalizes all experiences within the bundle. This will return a promise that resolves when all experiences have been finalized.\n * The promise resolves with a list of messages that indicate the status of each experience including\n * helpful details like what product to add to cart on supported e-commerce platforms.\n * @param onProgressUpdate A callback that will be called when the progress of the finalization changes.\n * @param createPreviewImage A callback that will be called when a preview image is required. This is used to generate a preview image for the design.\n * If this callback is not provided, no preview image will be generated.\n * @returns {BundleDesignCreationMessage} An object containing an array of design messages, along with the Bundle's Id and the event type.\n */\n finish(\n onProgressUpdate?: DesignCreationProgressUpdate,\n createPreviewImage?: (\n workflowExperience: WorkflowExperience,\n shouldRender3D?: boolean,\n ) => Promise<string | undefined>,\n ): Promise<BundleDesignCreationMessage>;\n\n /**\n * A convenience function allowing you to place an order with all the items in the bundle.\n */\n placeOrder(): Promise<Order>;\n\n /**\n * Add an event listener to this bundle.\n * @param event The event to listen for. Currently only \"conditional-global-properties-changed\" is supported.\n * @param listener The listener to call when the event occurs.\n */\n addEventListener<K extends keyof BundleEventMap>(event: K, listener: (event: BundleEvent<K>) => void): void;\n\n /**\n * Remove a previously added event listener from this bundle.\n */\n removeEventListener<K extends keyof BundleEventMap>(event: K, listener: (event: BundleEvent<K>) => void): void;\n\n /**\n * Retrieves the current preview service for this bundle, if one exists.\n * If a preview service was specified when calling client.getExistingBundle, this will return that service.\n * Call `setPreviewService` to update the preview service for this bundle.\n */\n getPreviewService(): ThreeDPreviewService | undefined;\n\n /**\n * Set the preview service for this bundle. This will update the preview service for all workflow experiences in this bundle, and will\n * also automatically inject the preview service into any new workflow experiences that are added to this bundle.\n * If this method is called with no arguments or undefined, the preview service will be removed from this bundle.\n * @param previewService The preview service to use for this bundle.\n * @returns A promise that resolves when the preview service has been updated for all workflow experiences in this bundle.\n */\n setPreviewService(previewService?: ThreeDPreviewService): Promise<void>;\n\n /**\n * Returns a promise that resolves when the bundle has been initialized.\n * This will resolve immediately if the bundle has no experiences, or if the bundle has already been initialized.\n */\n getInitializationPromise(): Promise<void>;\n\n /**\n * @returns The raw Global Property Configuration that is in use, otherwise `undefined`.\n */\n getGlobalPropertyConfiguration(): GlobalPropertyConfiguration | undefined;\n\n setBundleOptions(bundleOptions?: BundleOptions);\n\n /**\n * Assigns a Product Collection to the Bundle. This will only succeed if the Bundle does not already have a Product Collection assigned to it.\n * @param productCollectionId The ID of the Product Collection to assign to this Bundle.\n */\n assignProductCollection(productCollectionId: string): Promise<void>;\n\n getShareActions(): undefined | ShareAction[];\n\n getWorkflowViewerLink(): string;\n\n getWorkflowViewerAmendLink(): string;\n\n approve(note?: string, stakeholderId?: string): Promise<void>;\n\n reject(note?: string, stakeholderId?: string): Promise<void>;\n\n attachAddress(\n streetAddress?: string,\n apartment?: string,\n city?: string,\n country?: string,\n state?: string,\n postCode?: string,\n ): Promise<void>;\n\n attachOrganization(name: string): Promise<void>;\n\n generateQuoteId(): Promise<string>;\n\n getQuoteCompleteMessage(): CompleteQuoteMessage;\n\n applyGlobalPropertyState(state: GlobalPropertyState): Promise<void>;\n\n getIntegrationProductIds(): undefined | string[];\n\n addIntegrationProductId(id: string): Promise<void>;\n\n removeIntegrationProductIds(ids: string[]): Promise<void>;\n}\n\nexport class BundleImpl implements Bundle {\n readonly client: SpiffCommerceClient;\n\n private readonly id: string;\n private name: string;\n private dispatchDate?: string;\n private purchaseOrder?: string;\n private quoteId?: string;\n private metadata: ReadonlyMap<string, string>;\n private completed: boolean;\n private template: boolean;\n private productCollection?: ProductCollectionResource;\n\n private readonly bundleStateManager: BundleStateManager;\n private readonly globalPropertyStateManager: GlobalPropertyStateManager;\n private readonly globalPropertyHandleService: GlobalPropertyHandleService;\n private readonly initializationPromise: Promise<any>;\n private readonly ownerId?: string;\n private readonly shareActions?: ShareAction[];\n private readonly workflowViewerLink: string;\n private readonly workflowViewerAmendLink: string;\n\n private globalConfigurationPropertyId?: string;\n\n private workflowExperiences: WorkflowExperience[] = [];\n private previewService?: ThreeDPreviewService;\n\n private eventEmitter = new EventEmitter<BundleEventMap>();\n\n private updatesLocked = false;\n\n constructor(\n client: SpiffCommerceClient,\n entity: BundleEntity,\n previewService?: ThreeDPreviewService,\n graphqlOptions?: GetWorkflowGraphqlOptions,\n ownerId?: string,\n bundleOptions?: BundleOptions,\n transactionLoadProgressCallback?: (loaded: number, total: number) => void,\n ) {\n this.client = client;\n this.id = entity.id!;\n this.name = entity.name || \"\";\n this.dispatchDate = entity.dispatchDate;\n this.template = entity.template || false;\n this.quoteId = entity.quoteId;\n this.shareActions = entity.bundleShareActions;\n this.workflowViewerLink = entity.workflowViewerLink;\n this.workflowViewerAmendLink = entity.workflowViewerAmendLink;\n this.ownerId = ownerId;\n this.metadata = new Map(entity.metadata?.map((m) => [m.key, m.value]) || []);\n this.completed = entity.completed ?? false;\n this.productCollection = entity.productCollection;\n this.bundleStateManager = new BundleStateManager(entity.bundleStateData);\n const defaultGlobalPropertyConfiguration = this.productCollection?.globalPropertyConfiguration;\n this.globalConfigurationPropertyId = defaultGlobalPropertyConfiguration?.id;\n this.globalPropertyStateManager = new GlobalPropertyStateManagerImpl(\n this.id,\n this.ownerId,\n defaultGlobalPropertyConfiguration,\n this.onGlobalPropertiesChanged.bind(this),\n bundleOptions,\n );\n this.globalPropertyHandleService = new GlobalPropertyHandleService(this);\n this.setPreviewService(previewService);\n\n this.initializationPromise = Promise.all([\n this.loadExistingWorkflowExperiences(\n entity.transactionIds || [],\n {\n ...graphqlOptions,\n bundleOwnerId: ownerId,\n },\n transactionLoadProgressCallback,\n ),\n this.globalPropertyStateManager.getInitializationPromise(),\n ]).then(\n () =>\n new Promise<void[]>((resolve, reject) => {\n if (bundleOptions?.readonly) {\n resolve([]);\n return;\n }\n console.log(`Setting default global variants.`);\n const state = this.globalPropertyStateManager.getGlobalPropertyState();\n if (!state) {\n console.log(`Attempted to set global default variant before state was initialized.`);\n resolve([]);\n } else {\n this.globalPropertyHandleService.getHandles().then((handles) => {\n const promises = handles.map(async (handle) => {\n if (\n handle.getType() === AspectType.ColorOption ||\n handle.getType() === AspectType.Option\n ) {\n const h = handle as OptionGlobalPropertyHandle;\n const aspect = state.aspects.find((a) => a.name === h.getName());\n if (!aspect) {\n try {\n // Only init aspects that aren't already set.\n return await h.initDefaultVariant();\n } catch (e) {\n // FIXME: It appears that some layout elements aren't immediately available on reload\n console.error(`Failed to initialize default global variant - ${e}`);\n }\n }\n }\n });\n Promise.all(promises).then(resolve).catch(reject);\n });\n }\n }),\n );\n this.initializationPromise.catch((e) => {\n console.error(`Bundle initialization failed: ${e}`);\n });\n this.initializationPromise.then(() => {\n this.getGlobalProperties().then((handles) => this.checkMandatoryHandlesChanged(undefined, handles));\n });\n }\n\n getIntegrationProductIds(): undefined | string[] {\n return this.bundleStateManager.getState()?.integrationProductIds;\n }\n\n async addIntegrationProductId(id: string): Promise<void> {\n const state = this.bundleStateManager.getState();\n if (state) {\n if (!state.integrationProductIds) {\n state.integrationProductIds = [];\n } else if (state.integrationProductIds.some((it) => it === id)) {\n // No need to send a network request or update state.\n // Still fire event to maintain existing behaviour\n this.fireEvent(\"bundle-integration-products-added\", {\n integrationProductIds: state.integrationProductIds,\n });\n return;\n }\n state.integrationProductIds = [...state.integrationProductIds, id];\n const stateString = JSON.stringify(state);\n this.bundleStateManager.setState(stateString);\n this.fireEvent(\"bundle-integration-products-added\", {\n integrationProductIds: state.integrationProductIds,\n });\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: updateBundleMutation,\n variables: {\n id: this.id,\n bundleStateData: stateString,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n }\n }\n\n async removeIntegrationProductIds(ids: string[]) {\n const state = this.bundleStateManager.getState();\n if (state) {\n const idsToRemove = ids.filter((id) => (state.integrationProductIds ?? []).includes(id));\n if (idsToRemove.length === 0) {\n return;\n }\n state.integrationProductIds = (state.integrationProductIds ?? []).filter((it) => !idsToRemove.includes(it));\n const stateString = JSON.stringify(state);\n this.bundleStateManager.setState(stateString);\n this.fireEvent(\"bundle-integration-products-removed\", {\n integrationProductIds: idsToRemove,\n });\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: updateBundleMutation,\n variables: {\n id: this.id,\n bundleStateData: stateString,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n }\n }\n\n getTemplate(): boolean {\n return this.template;\n }\n\n async generateQuoteId(): Promise<string> {\n const result = await graphQlManager.getShadowGraphqlClient().mutate<{ bundleGenerateQuoteId: BundleEntity }>({\n mutation: generateQuoteIdMutation,\n variables: {\n id: this.id,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n const quoteId = result.data?.bundleGenerateQuoteId?.quoteId;\n this.quoteId = quoteId;\n return quoteId || \"\";\n }\n\n async attachAddress(\n streetAddress?: string,\n apartment?: string,\n city?: string,\n country?: string,\n state?: string,\n postCode?: string,\n ): Promise<void> {\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: addAddressToBundleMutation,\n variables: {\n bundleId: this.id,\n streetAddress: streetAddress || undefined,\n apartment: apartment || undefined,\n city: city || undefined,\n country: country || undefined,\n state: state || undefined,\n postCode: postCode || undefined,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n }\n\n async attachOrganization(name: string): Promise<void> {\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: addOrganizationToBundleMutation,\n variables: {\n bundleId: this.id,\n organizationName: name,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n }\n\n setBundleOptions(bundleOptions?: BundleOptions) {\n this.globalPropertyStateManager.setBundleOptions(bundleOptions);\n }\n\n getInitializationPromise(): Promise<void> {\n return this.initializationPromise;\n }\n\n addEventListener<K extends keyof BundleEventMap>(event: K, listener: (event: BundleEvent<K>) => void): void {\n this.eventEmitter.on(event, listener);\n }\n\n removeEventListener<K extends keyof BundleEventMap>(event: K, listener: (event: BundleEvent<K>) => void): void {\n this.eventEmitter.off(event, listener);\n }\n\n getClient() {\n return this.client;\n }\n\n getId() {\n return this.id;\n }\n\n getName(): string {\n return this.name;\n }\n\n getQuoteId(): string | undefined {\n return this.quoteId;\n }\n\n setName(name: string): Promise<void> {\n this.name = name;\n return this.updateBundle();\n }\n\n getDispatchDate(): string | undefined {\n return this.dispatchDate;\n }\n\n setDispatchDate(dd: string): Promise<void> {\n this.dispatchDate = dd;\n return this.updateBundle();\n }\n\n getPurchaseOrder(): string | undefined {\n return this.purchaseOrder;\n }\n\n setPurchaseOrder(po: string): Promise<void> {\n this.purchaseOrder = po;\n return this.updateBundle();\n }\n\n getMetadata(): Map<string, string> {\n return new Map(this.metadata);\n }\n\n setMetadata(metadata: Map<string, string>): Promise<void> {\n this.metadata = new Map(metadata);\n return this.updateBundle();\n }\n\n setNameAndMetadata(name: string, metadata: Map<string, string>): Promise<void> {\n this.name = name;\n this.metadata = new Map(metadata);\n return this.updateBundle();\n }\n\n hasGlobalProperties(): boolean {\n // For now we just check if this bundle is linked to a product collection that has global properties.\n // In the future there could be other ways of providing global properties.\n return !!this.productCollection?.globalPropertyConfiguration;\n }\n\n getGlobalPropertyConfiguration() {\n return this.productCollection?.globalPropertyConfiguration;\n }\n\n async getGlobalProperties(): Promise<GlobalPropertyHandle[]> {\n return this.globalPropertyHandleService.applyConditionsFromState(\n await this.globalPropertyHandleService.getHandles(),\n this.getGlobalPropertyStateManager().getGlobalPropertyState(),\n );\n }\n\n async applyGlobalPropertyState(state: GlobalPropertyState): Promise<void> {\n this.updatesLocked = true;\n const handles = await this.globalPropertyHandleService.getHandles();\n try {\n // First we have to ensure that the aspects have been set,\n // because the rest of the logic relies on it.\n for (const aspect of state.aspects) {\n const name = aspect?.name;\n await this.getGlobalPropertyStateManager().setAspect(name, aspect.value);\n }\n\n // Then we do the general work.\n for (const aspect of state.aspects) {\n const name = aspect?.name;\n const handle = handles.find((h) => h.getName() === name);\n if (handle) {\n switch (aspect.type) {\n case AspectType.FileUpload: {\n const fileHandle = handle as FileUploadGlobalPropertyHandle;\n const assets = await getAssets([aspect.value]);\n if (assets.length > 0) {\n await fileHandle.selectImage(assets[0]);\n }\n const colors = (aspect.storage as GlobalPropertyStateFileUploadStorage | undefined)?.colors;\n if (colors) {\n const colorMap = Object.fromEntries(\n colors.map((it) => [\n it.key,\n { browserValue: it.browserValue, pmsValue: it.pmsValue },\n ]) ?? [],\n );\n await fileHandle.changeColors(colorMap);\n }\n break;\n }\n case AspectType.ColorOption: {\n const colorHandle = handle as ColorOptionGlobalPropertyHandle;\n const variants = await colorHandle.getAllVariants();\n const variant = variants.find((v) => v.getId() === aspect.value);\n const storage = aspect.storage\n ? (aspect.storage as GlobalPropertyStateColorOptionStorage)\n : undefined;\n if (variant) {\n await colorHandle.selectVariant(variant);\n }\n if (storage?.customColor) {\n colorHandle.setCustomColor(storage.customColor);\n }\n break;\n }\n case AspectType.Option: {\n const optionHandle = handle as OptionGlobalPropertyHandle;\n const variants = await optionHandle.getAllVariants();\n const variant = variants.find((v) => v.getId() === aspect.value);\n if (variant) {\n await optionHandle.selectVariant(variant);\n }\n break;\n }\n case AspectType.Text: {\n const textHandle = handle as TextGlobalPropertyHandle;\n await textHandle.setText(aspect.value);\n break;\n }\n }\n }\n }\n } finally {\n this.updatesLocked = false;\n // Fire off any relevant events\n this.onGlobalPropertiesChanged(undefined, this.globalPropertyStateManager.getGlobalPropertyState()!);\n }\n }\n\n getGlobalPropertyStateManager(): GlobalPropertyStateManager {\n return this.globalPropertyStateManager;\n }\n\n async getGlobalPropertyTotalSubunits(): Promise<number> {\n const handles = await this.globalPropertyHandleService.getHandles();\n const options = handles.filter((h) => h.getType() === AspectType.Option) as OptionGlobalPropertyHandle[];\n return options.map((o) => o.getCurrentVariant()?.getPrice() || 0).reduce((partialSum, a) => partialSum + a, 0);\n }\n\n getTotalSubunits() {\n return this.workflowExperiences.map((we) => we.getTotalPriceSubunits()).reduce((a, b) => a + b, 0);\n }\n\n getProductCollection(): ProductCollection | undefined {\n return this.productCollection ? new ProductCollection(this.productCollection) : undefined;\n }\n\n private async initializeAdditionalRequiredColorChannels(experience: WorkflowExperience) {\n // If the experience corresponds to a global illustration we check whether the\n // experience we're adding has more channels than have been initialized.\n for (const step of experience.getStepsByType(StepType.Illustration)) {\n const aspectNames = step.getGlobalPropertyAspects(this.globalConfigurationPropertyId || \"\");\n for (const aspectName of aspectNames) {\n const matchingAspect = this.getGlobalPropertyConfiguration()?.aspects.find(\n (a) => a.name === aspectName,\n );\n if (matchingAspect && matchingAspect.type === AspectType.ColorOption) {\n const asset = step.getCurrentVariant()?.getAssetResource();\n const channelNumbers = asset?.assetConfiguration?.channelNumbers || [];\n const defaultColors = asset?.assetConfiguration?.defaultColorVariants || [];\n const amtChannelsInitialized = amtChannelsForAspect(this, aspectName);\n const uniqueChannelNumbers = [...new Set(channelNumbers.map((cn) => cn.number))];\n const amtChannelsInExperience = uniqueChannelNumbers.length;\n if (amtChannelsInExperience > amtChannelsInitialized) {\n for (const channelNumber of uniqueChannelNumbers) {\n const manager = this.getGlobalPropertyStateManager();\n const dc = defaultColors.find((dc) => dc.channelNumber === channelNumber);\n if (dc) {\n await manager.setAspect(aspectName, dc.variant.id || \"\", undefined, dc.channelNumber);\n }\n }\n }\n }\n }\n }\n }\n\n async addWorkflowExperience(experience: WorkflowExperience) {\n await this.initializeAdditionalRequiredColorChannels(experience);\n\n // Append the experience to the bundle.\n experience.setBundle(this);\n await this.appendWorkflowExperience(experience);\n // If a preview is attached to the bundle inject it into that.\n await this.injectExperienceIntoPreviewService(experience);\n // Ensure the experience is loaded to prevent timing issues with global property application.\n await experience.getWorkflowManager().getInitializationPromise();\n\n // Apply global state if required.\n const globalProperties = await this.getGlobalProperties();\n for (const p of globalProperties) {\n await p.applyGlobalState([experience]);\n }\n\n this.fireEvent(\"workflow-experience-added\", {\n workflowExperiences: [experience],\n });\n }\n\n async addWorkflowExperiences(experiences: WorkflowExperience[]) {\n for (const experience of experiences) {\n await this.initializeAdditionalRequiredColorChannels(experience);\n }\n\n const transactionIds = experiences.map((experience) => experience.getTransaction().id);\n const existing = transactionIds.map((transactionId) =>\n this.workflowExperiences.find((exp) => exp.getTransaction().id === transactionId),\n );\n if (existing.some((e) => !!e))\n throw new Error(\n \"Unable to add transaction to bundle - Already Exists: \" +\n existing\n .filter((e) => !!e)\n .map((e) => e?.getTransaction().id)\n .join(\", \"),\n );\n // Use the owner ID from the persistence service if it exists. Otherwise the client will fall back to other methods.\n const ownerMap = persistenceService.getMap(\"transactionOwnerIds\") || new Map();\n const existingOwnerIds = transactionIds.map((transactionId) => ownerMap.get(transactionId));\n await graphQlManager\n .getShadowGraphqlClient()\n .mutate({\n mutation: bundleAddTransactionsMutation,\n variables: {\n id: this.id,\n transactionIds: transactionIds,\n transactionOwnerIds: existingOwnerIds,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n })\n .catch((e) => {\n console.error(e);\n });\n this.workflowExperiences.push(...experiences);\n\n const initializeExperience = async () => {\n for (const experience of experiences) {\n experience.setBundle(this);\n await this.injectExperienceIntoPreviewService(experience);\n }\n await Promise.all(experiences.map((exp) => exp.getWorkflowManager().getInitializationPromise()));\n const globalProperties = await this.getGlobalProperties();\n for (const p of globalProperties) {\n await p.applyGlobalState(experiences);\n }\n };\n\n await Promise.all([this.updateTransactionOrder(), initializeExperience()]);\n // Check changes after adding all (experiences rely on checking each other)\n this.workflowExperiences.forEach((experience) => experience.checkForPriceBreakChanges());\n\n this.fireEvent(\"workflow-experience-added\", {\n workflowExperiences: this.workflowExperiences,\n });\n }\n\n private async appendWorkflowExperience(experience: WorkflowExperience, updateArray = true) {\n const transactionId = experience.getTransaction().id;\n const existing = this.workflowExperiences.find((exp) => exp.getTransaction().id === transactionId);\n if (existing) throw new Error(\"Unable to add transaction to bundle - Already Exists!\");\n // Use the owner ID from the persistence service if it exists. Otherwise the client will fall back to other methods.\n const ownerMap = persistenceService.getMap(\"transactionOwnerIds\") || new Map();\n const existingOwnerId = ownerMap.get(transactionId);\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: bundleAddTransactionMutation,\n variables: {\n id: this.id,\n transactionId: transactionId,\n },\n context: {\n bundleOwnerId: this.ownerId,\n transactionOwnerId: existingOwnerId,\n },\n });\n if (updateArray) {\n this.workflowExperiences.push(experience);\n this.workflowExperiences.forEach((experience) => experience.checkForPriceBreakChanges());\n }\n }\n\n async removeWorkflowExperience(experience: WorkflowExperience) {\n const index = this.workflowExperiences.indexOf(experience);\n await this.removeTransaction(index, this.workflowExperiences[index].getTransaction());\n this.fireEvent(\"workflow-experience-added\", {\n workflowExperiences: [experience],\n });\n }\n\n async removeWorkflowExperiences(experiences: WorkflowExperience[]) {\n await this.removeTransactions(experiences.map((exp) => exp.getTransaction()));\n }\n\n async removeWorkflowExperienceByTransaction(transaction: Transaction) {\n const index = this.workflowExperiences.findIndex((we) => we.getTransaction().id === transaction.id);\n await this.removeTransaction(index, transaction);\n }\n\n async removeWorkflowExperiencesByTransactions(transactions: Transaction[]) {\n await this.removeTransactions(transactions);\n }\n\n private async removeTransaction(index: number, transaction: Transaction, updateArray = true) {\n if (index > -1) {\n const removed = this.workflowExperiences.find((we) => we.getTransaction().id === transaction.id)!;\n removed.setBundle(undefined);\n if (this.previewService) {\n removed.getWorkflowManager().ejectFromPreviewService();\n }\n this.bundleStateManager.removeStateForTransaction(transaction.id);\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: bundleRemoveTransactionMutation,\n variables: {\n id: this.id,\n transactionId: transaction.id,\n name: this.name,\n metadata: Array.from(this.metadata.entries()).map(([key, value]) => ({ key, value })),\n bundleStateData: this.bundleStateManager.getSerializedState(),\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (updateArray) {\n const removedExp = this.workflowExperiences.splice(index, 1);\n this.workflowExperiences.forEach((experience) => experience.checkForPriceBreakChanges());\n removed.checkForPriceBreakChanges();\n await this.updateTransactionOrder();\n this.fireEvent(\"workflow-experience-removed\", {\n workflowExperiences: removedExp,\n });\n }\n } else {\n throw new Error(\"Unable to remove workflow experience from bundle - Not Found! - \" + transaction.id);\n }\n }\n\n private async removeTransactions(transactions: Transaction[]) {\n const indices = transactions.map((transaction) =>\n this.workflowExperiences.findIndex((we) => we.getTransaction().id === transaction.id),\n );\n if (indices.some((index) => index === -1)) {\n throw new Error(\n \"Unable to remove workflow experience from bundle - The following aren't included in the bundle: \" +\n transactions\n .filter((_, i) => indices[i] === -1)\n .map((t) => t.id)\n .join(\", \"),\n );\n }\n const removedExperiences = transactions.map(\n (t) =>\n this.workflowExperiences.splice(\n this.workflowExperiences.findIndex((we) => we.getTransaction().id === t.id),\n 1,\n )[0],\n );\n removedExperiences.forEach((experience) => experience.setBundle(undefined));\n [...this.workflowExperiences, ...removedExperiences].forEach((experience) =>\n experience.checkForPriceBreakChanges(),\n );\n if (this.previewService) {\n removedExperiences.forEach((experience) => experience.getWorkflowManager().ejectFromPreviewService());\n }\n transactions.forEach((transaction) => this.bundleStateManager.removeStateForTransaction(transaction.id));\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: bundleRemoveTransactionsMutation,\n variables: {\n id: this.id,\n transactionIds: transactions.map((t) => t.id),\n name: this.name,\n metadata: Array.from(this.metadata.entries()).map(([key, value]) => ({ key, value })),\n bundleStateData: this.bundleStateManager.getSerializedState(),\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n this.fireEvent(\"workflow-experience-removed\", {\n workflowExperiences: removedExperiences,\n });\n await this.updateTransactionOrder();\n }\n\n async insertWorkflowExperience(experience: WorkflowExperience, index: number): Promise<void> {\n await this.appendWorkflowExperience(experience, false);\n this.workflowExperiences.splice(index, 0, experience);\n await Promise.all([\n this.updateTransactionOrder(),\n (async () => {\n await this.injectExperienceIntoPreviewService(experience);\n const globalProperties = await this.getGlobalProperties();\n await Promise.all(globalProperties.map((p) => p.applyGlobalState([experience])));\n })(),\n ]);\n }\n\n async replaceWorkflowExperience(index: number, experience: WorkflowExperience): Promise<void> {\n if (index < 0 || index >= this.workflowExperiences.length) {\n throw new Error(\"Unable to replace workflow experience in bundle - Index out of range!\");\n }\n const oldExperience = this.workflowExperiences[index];\n if (oldExperience.getTransaction().id === experience.getTransaction().id) {\n throw new Error(\"Unable to replace workflow experience in bundle - Same transaction!\");\n }\n await Promise.all([\n this.removeTransaction(index, oldExperience.getTransaction(), false),\n this.appendWorkflowExperience(experience, false),\n ]);\n this.workflowExperiences[index] = experience;\n await Promise.all([\n this.updateTransactionOrder(),\n (async () => {\n await this.injectExperienceIntoPreviewService(experience);\n const globalProperties = await this.getGlobalProperties();\n await Promise.all(globalProperties.map((p) => p.applyGlobalState([experience])));\n })(),\n ]);\n }\n\n async swapWorkflowExperiences(a: number, b: number): Promise<void> {\n if (a < 0 || a >= this.workflowExperiences.length || b < 0 || b >= this.workflowExperiences.length) {\n throw new Error(\"Unable to swap workflow experiences in bundle - Index out of range!\");\n }\n if (a === b) return;\n const temp = this.workflowExperiences[a];\n this.workflowExperiences[a] = this.workflowExperiences[b];\n this.workflowExperiences[b] = temp;\n await this.updateTransactionOrder();\n }\n\n getWorkflowExperiences() {\n return [...this.workflowExperiences];\n }\n\n async sortWorkflowExperiences(\n sortFunc: (expA: WorkflowExperience, expB: WorkflowExperience) => number,\n ): Promise<void> {\n this.workflowExperiences = this.workflowExperiences.sort(sortFunc);\n await this.updateTransactionOrder();\n }\n\n getWorkflowExperienceCount(): number {\n return this.workflowExperiences.length;\n }\n\n async addStakeholder(customerDetails: CustomerDetailsInput, stakeholderType?: StakeholderType): Promise<void> {\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{ bundleAddStakeholder: BundleEntity }>({\n mutation: bundleAddStakeholderMutation,\n variables: {\n id: this.id,\n details: customerDetails,\n type: stakeholderType || StakeholderType.Owner,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (!response.data?.bundleAddStakeholder) throw new Error(\"Bundle not found!\");\n const stakeholders = response.data.bundleAddStakeholder.bundleStakeholders || [];\n this.storeStakeholderCustomers(stakeholders);\n }\n\n async removeStakeholder(emailAddress: string): Promise<void> {\n const response = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ bundleRemoveStakeholder: BundleEntity }>({\n mutation: bundleRemoveStakeholderMutation,\n variables: {\n id: this.id,\n emailAddress,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (!response.data?.bundleRemoveStakeholder) throw new Error(\"Bundle not found!\");\n }\n\n async updateStakeholders(stakeholders: BundleStakeholderInput[]): Promise<void> {\n const response = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ bundleUpdateStakeholders: BundleEntity }>({\n mutation: bundleUpdateStakeholdersMutation,\n variables: {\n id: this.id,\n input: stakeholders,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (!response.data?.bundleUpdateStakeholders) throw new Error(\"Bundle not found!\");\n const updatedStakeholders = response.data.bundleUpdateStakeholders.bundleStakeholders || [];\n this.storeStakeholderCustomers(updatedStakeholders);\n }\n\n async getAllStakeholders(): Promise<BundleStakeholder[]> {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ bundles: BundleEntity[] }>({\n query: getBundleStakeholdersQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.id,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (!response.data.bundles || response.data.bundles.length === 0) throw new Error(\"Bundle not found!\");\n const stakeholders = response.data.bundles[0].bundleStakeholders || [];\n this.storeStakeholderCustomers(stakeholders);\n return stakeholders;\n }\n\n async getCurrentStakeholder(): Promise<BundleStakeholder | undefined> {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ bundles: BundleEntity[] }>({\n query: getBundleStakeholdersQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.id,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (!response.data.bundles || response.data.bundles.length === 0) throw new Error(\"Bundle not found!\");\n const bundle = response.data.bundles[0];\n return bundle.currentBundleStakeholder;\n }\n\n private storeStakeholderCustomers(stakeholders: BundleStakeholder[]) {\n stakeholders.forEach((stakeholder) => {\n if (stakeholder.customer) {\n this.client.storeCustomer(stakeholder.customer);\n }\n });\n }\n\n async finish(\n onProgressUpdate?: DesignCreationProgressUpdate,\n createPreviewImage?: (\n workflowExperience: WorkflowExperience,\n shouldRender3D?: boolean,\n ) => Promise<string | undefined>,\n ): Promise<BundleDesignCreationMessage> {\n // Flush any changes beforehand\n if (this.completed) {\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: finalizeUpdateBundleMutation,\n variables: {\n bundleId: this.id,\n },\n });\n }\n // Compute the results\n const results = await createDesigns(\n this.workflowExperiences.map((exp) => {\n const workflow = exp.getWorkflow();\n if (!workflow) throw new Error(\"Unable to create designs - Workflow not found!\");\n const product = exp.getProduct();\n if (!product) throw new Error(\"Unable to create designs - Product not found!\");\n return {\n workflowManager: exp.getWorkflowManager(),\n workflow: workflow,\n layouts: exp.getWorkflowManager().getLayouts(),\n getReducerState: () => exp.getCommandContext().getState()!,\n product: product,\n transaction: exp.getTransaction(),\n workflowSelections: exp.getWorkflowManager().getWorkflowSelections(),\n designName: workflow.name,\n workflowMetadata: exp.getWorkflowManager().getWorkflowMetadata(),\n };\n }),\n createPreviewImage\n ? (shouldRender3D?: boolean, transactionId?: string) => {\n const experience = this.workflowExperiences.find(\n (exp) => exp.getTransaction().id === transactionId,\n );\n if (!experience) {\n console.warn(\n \"SpiffCommerce - Bundle create design - Unable to find experience for transaction: \" +\n transactionId,\n );\n return Promise.resolve(undefined);\n }\n return createPreviewImage(experience, shouldRender3D);\n }\n : undefined,\n );\n return {\n bundleId: this.id,\n name: this.getName(),\n dispatchDate: this.getDispatchDate() || \"\",\n purchaseOrder: this.getPurchaseOrder() || \"\",\n collectionId: this.getProductCollection()?.getId() || \"\",\n collectionName: this.getProductCollection()?.getName() || \"\",\n items: results,\n bundleOwnerId: this.ownerId,\n };\n }\n\n async placeOrder(): Promise<Order> {\n const orderItems = this.workflowExperiences.map((exp) => {\n return {\n transactionId: exp.getTransaction().id,\n amountToOrder: exp.getTransaction().quantity || 1,\n };\n });\n return await this.getClient().placeOrder(orderItems);\n }\n\n getPreviewService() {\n return this.previewService;\n }\n\n async setPreviewService(previewService?: ThreeDPreviewService): Promise<void> {\n if (this.workflowExperiences && this.workflowExperiences.length > 0) {\n this.workflowExperiences.forEach((exp) => exp.getWorkflowManager().ejectFromPreviewService());\n if (previewService) {\n // Sequentially inject each experience into the preview service, for performance reasons.\n for (const experience of this.workflowExperiences) {\n await this.injectExperienceIntoPreviewService(experience);\n }\n }\n }\n if (previewService && previewService.registerModelLoadEventListener) {\n previewService.registerModelLoadEventListener(this.onModelLoadEvent.bind(this));\n }\n if (\n this.previewService &&\n this.previewService !== previewService &&\n this.previewService.unregisterModelLoadEventListener\n ) {\n this.previewService.unregisterModelLoadEventListener(this.onModelLoadEvent.bind(this));\n }\n this.previewService = previewService;\n }\n\n async assignGlobalPropertyConfiguration(globalPropertyConfigurationId: string) {\n await graphQlManager.getShadowGraphqlClient().mutate<{ bundleAssignProductCollection: BundleEntity }>({\n mutation: bundleAssignGlobalPropertyConfiguration,\n variables: {\n bundleId: this.id,\n globalPropertyConfigurationId,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n this.globalConfigurationPropertyId = globalPropertyConfigurationId;\n }\n\n async assignProductCollection(productCollectionId: string) {\n const response = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ bundleAssignProductCollection: BundleEntity }>({\n mutation: bundleAssignProductCollectionMutation(\n this.globalPropertyStateManager.getBundleOptions()?.eagerFetchProducts ?? false,\n ),\n variables: {\n id: this.id,\n productCollectionId: productCollectionId ?? \"\",\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (response.data?.bundleAssignProductCollection.productCollection) {\n this.productCollection = response.data.bundleAssignProductCollection.productCollection;\n const globalPropertyConfiguration =\n response.data.bundleAssignProductCollection.productCollection.globalPropertyConfiguration;\n this.globalPropertyStateManager.setConfiguration(globalPropertyConfiguration);\n await this.globalPropertyHandleService.getHandles();\n this.globalConfigurationPropertyId = globalPropertyConfiguration?.id;\n }\n }\n\n private onModelLoadEvent(e: { eventType: \"load\" | \"unload\"; modelContainer: ModelContainer }): void {\n if (e.eventType === \"unload\" || !e.modelContainer) return;\n e.modelContainer.registerMaterialSelectedCallback(() => this.onModelSelectedEvent(e.modelContainer, true));\n e.modelContainer.registerMaterialDeselectedCallback(() => this.onModelSelectedEvent(e.modelContainer, false));\n }\n\n private onModelSelectedEvent(modelContainer: ModelContainer, selected: boolean): void {\n if (modelContainer && modelContainer.metadata && modelContainer.metadata instanceof Map) {\n if (modelContainer.metadata.has(\"workflowManager\")) {\n const workflowManager: WorkflowManager = modelContainer.metadata.get(\"workflowManager\");\n const transaction = workflowManager.getWorkflowExperience().getTransaction();\n const experience = this.workflowExperiences.find((exp) => exp.getTransaction().id === transaction.id);\n if (experience) {\n this.fireEvent(selected ? \"workflow-experience-hover-enter\" : \"workflow-experience-hover-exit\", {\n workflowExperience: experience,\n });\n }\n }\n }\n }\n\n private async injectExperienceIntoPreviewService(experience: WorkflowExperience) {\n if (this.previewService) {\n await experience.getWorkflowManager().injectIntoPreviewService(this.previewService);\n }\n }\n\n private async loadExistingWorkflowExperiences(\n transactionIds: string[],\n graphqlOptions?: GetWorkflowGraphqlOptions,\n transactionLoadProgressCallback?: (loaded: number, total: number) => void,\n ): Promise<void> {\n if (transactionIds.length === 0) return;\n const experiences = await this.client.getWorkflowExperiences(\n transactionIds.map((id) => ({\n type: \"transaction\",\n transactionId: id,\n })),\n graphqlOptions,\n undefined,\n transactionLoadProgressCallback,\n );\n experiences.forEach((wfe) => wfe.setBundle(this));\n experiences.forEach((wfe) => wfe.checkForPriceBreakChanges());\n this.workflowExperiences = experiences;\n if (this.previewService) {\n for (const experience of experiences) {\n await this.injectExperienceIntoPreviewService(experience);\n }\n }\n\n // Get products in bundle.\n // Get products in bundle's product collection.\n // Check that each bundle product is still in the collection.\n // For any product that has since been removed from the collection:\n // - Iterate over the bundle's transactions, remove product if the product matches\n // - Remove the product from the bundle.\n const integrationProductIds = this.getIntegrationProductIds() || [];\n const productCollection = this.getProductCollection();\n if (productCollection && integrationProductIds.length > 0) {\n await productCollection.fetchProducts();\n const products = productCollection.getProducts();\n for (const ipId of integrationProductIds) {\n const product = products.find((p) => p.getCurrentIntegration().id === ipId);\n if (!product) {\n for (const experience of experiences) {\n if (\n experience\n .getProduct()\n ?.integrationProducts?.map((ip) => ip.id)\n ?.includes(ipId)\n ) {\n await experience.clearProduct();\n }\n }\n await this.removeIntegrationProductIds([ipId]);\n }\n }\n }\n }\n\n private async updateBundle() {\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{ bundleUpdate: BundleEntity }>({\n mutation: updateBundleMutation,\n variables: {\n id: this.id,\n name: this.name,\n metadata: Array.from(this.metadata.entries()).map(([key, value]) => ({ key, value })),\n bundleStateData: this.bundleStateManager.getSerializedState(),\n dispatchDate: this.dispatchDate,\n purchaseOrder: this.purchaseOrder,\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n if (!response.data?.bundleUpdate) throw new Error(\"Bundle not found!\");\n }\n\n private async updateTransactionOrder() {\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: bundleUpdateTransactionOrderMutation,\n variables: {\n id: this.id,\n transactionIds: this.workflowExperiences.map((exp) => exp.getTransaction().id),\n },\n context: {\n bundleOwnerId: this.ownerId,\n },\n });\n }\n\n private async onGlobalPropertiesChanged(\n previousState: GlobalPropertyState | undefined,\n newState: GlobalPropertyState,\n ) {\n if (this.updatesLocked) {\n return;\n }\n const handles = await this.globalPropertyHandleService.getHandles();\n const previousHandles = this.globalPropertyHandleService.applyConditionsFromState(handles, previousState);\n const newHandles = this.globalPropertyHandleService.applyConditionsFromState(handles, newState);\n\n // Check changes and fire events\n this.checkConditionalHandlesChanged(previousHandles, newHandles);\n this.checkMandatoryHandlesChanged(previousState, newHandles);\n\n // Aspects that are no longer active need to be cleared from the\n // state (particularly to deactivate aspects that are transitively dependent).\n const stateManager = this.getGlobalPropertyStateManager();\n let oldAspects: string[] = [];\n for (const handle of handles) {\n if (!newHandles.find((newHandle) => newHandle.getName() == handle.getName())) {\n oldAspects = [...oldAspects, handle.getName()];\n }\n }\n await stateManager.clearAspects(oldAspects);\n\n // Apply default variants on new handles\n const promises = newHandles.map((handle) => {\n if (handle.getType() === AspectType.ColorOption || handle.getType() === AspectType.Option) {\n const h = handle as OptionGlobalPropertyHandle;\n const aspect = newState.aspects.find((a) => a.name === h.getName());\n if (!aspect) {\n // Only init aspects that aren't already set.\n return h.initDefaultVariant();\n }\n }\n });\n await Promise.all(promises);\n\n // Ensure new handles' associated workflow experiences have up-to-date global property state\n await Promise.all(newHandles.map((handle) => handle.applyGlobalState()));\n\n const resultingState = this.globalPropertyStateManager.getGlobalPropertyState()!;\n const nextHandles = this.globalPropertyHandleService.applyConditionsFromState(handles, resultingState);\n if (!isEqual(newHandles.sort(), nextHandles.sort())) {\n // Recurse to remove transitively conditional steps.\n this.checkConditionalHandlesChanged(newHandles, nextHandles);\n this.checkMandatoryHandlesChanged(resultingState, nextHandles);\n await this.onGlobalPropertiesChanged(newState, resultingState);\n }\n }\n\n private checkConditionalHandlesChanged(\n previousHandles: GlobalPropertyHandle[],\n newHandles: GlobalPropertyHandle[],\n ) {\n const checkHandlesChanged = () => {\n if (previousHandles.length !== newHandles.length) return true;\n for (let i = 0; i < previousHandles.length; i++) {\n if (previousHandles[i].getName() !== newHandles[i].getName()) return true;\n }\n return false;\n };\n const changed = checkHandlesChanged();\n if (changed) {\n this.fireEvent(\"conditional-global-properties-changed\", {\n globalProperties: newHandles,\n });\n }\n }\n\n private checkMandatoryHandlesChanged(\n previousState: GlobalPropertyState | undefined,\n newHandles: GlobalPropertyHandle[],\n ) {\n const changed: GlobalPropertyHandle[] = [];\n const completed: GlobalPropertyHandle[] = [];\n const remaining: GlobalPropertyHandle[] = [];\n const previousMandatory = calculateMandatoryStates(previousState);\n newHandles.forEach((handle) => {\n if (handle.isMandatory()) {\n const fulfilled = handle.isMandatoryFulfilled();\n if (fulfilled) {\n completed.push(handle);\n } else {\n remaining.push(handle);\n }\n const oldAspects = previousMandatory.get(handle.getName());\n if (oldAspects === undefined || oldAspects !== fulfilled) {\n changed.push(handle);\n }\n }\n });\n this.fireEvent(\"global-properties-mandatory-changed\", {\n changed,\n completed,\n remaining,\n });\n }\n\n private fireEvent<K extends keyof BundleEventMap>(event: K, data: BundleEventMap[K]): void {\n this.eventEmitter.emit(event, data);\n }\n\n getShareActions(): undefined | ShareAction[] {\n return this.shareActions;\n }\n\n getWorkflowViewerLink(): string {\n return this.workflowViewerLink;\n }\n\n getWorkflowViewerAmendLink(): string {\n return this.workflowViewerAmendLink;\n }\n\n async approve(note?: string, stakeholderId?: string): Promise<void> {\n await graphQlManager.getShadowGraphqlClient().mutate<{ bundleApprove: string }>({\n mutation: bundleApprovalQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.id,\n note,\n stakeholderId,\n },\n });\n }\n\n async reject(note?: string, stakeholderId?: string): Promise<void> {\n await graphQlManager.getShadowGraphqlClient().mutate<{ bundleReject: string }>({\n mutation: bundleRejectionQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: this.id,\n note,\n stakeholderId,\n },\n });\n }\n\n getQuoteCompleteMessage(): CompleteQuoteMessage {\n return {\n bundleId: this.id,\n bundleOwnerId: this.ownerId,\n quoteId: this.quoteId || \"\",\n };\n }\n}\n","import { ApolloQueryResult, gql } from \"@apollo/client/core\";\nimport { graphQlManager } from \"./services/server\";\n\n/**\n * Graphql query for executing a process flow.\n */\nconst executeProcessFlow = gql`\n mutation processFlowCreate($processFlowId: String!, $inputs: [String]!) {\n processExecutionCreate(processFlowId: $processFlowId, inputs: $inputs) {\n id\n }\n }\n`;\n\n/**\n * The response from the server when executing a process flow.\n */\ninterface ExecutionResponseGraphQL {\n processExecutions: ExecutionResponse;\n}\n\n/**\n * A list of node types available in executions\n */\nexport enum NodeType {\n Split = \"Split\",\n TextJoin = \"TextJoin\",\n TextSlice = \"TextSlice\",\n TextUpper = \"TextUpper\",\n TextLower = \"TextLower\",\n ParseJson = \"ParseJson\",\n TextBuilder = \"TextBuilder\",\n Design = \"Design\",\n OverlayImage = \"OverlayImage\",\n OverlayText = \"OverlayText\",\n TableGenerator = \"TableGenerator\",\n QR = \"QR\",\n CSV = \"CSV\",\n PDF = \"PDF\",\n PNG = \"PNG\",\n Email = \"Email\",\n LocationDelivery = \"LocationDelivery\",\n TemplateEmail = \"TemplateEmail\",\n Map = \"Map\",\n Sort = \"Sort\",\n Group = \"Group\",\n InnerJoin = \"InnerJoin\",\n Contains = \"Contains\",\n Flatten = \"Flatten\",\n KeyValuePairs = \"KeyValuePairs\",\n ListConcatenate = \"ListConcatenate\",\n Repeat = \"Repeat\",\n Size = \"Size\",\n ListBuilder = \"ListBuilder\",\n MapBuilder = \"MapBuilder\",\n PairBuilder = \"PairBuilder\",\n AND = \"AND\",\n OR = \"OR\",\n NOT = \"NOT\",\n Equals = \"Equals\",\n Present = \"Present\",\n ManualOperation = \"ManualOperation\",\n Switch = \"Switch\",\n AssetMetadata = \"AssetMetadata\",\n DataSelect = \"DataSelect\",\n LayoutSelect = \"LayoutSelect\",\n TransactionMetadata = \"TransactionMetadata\",\n VariantSelection = \"VariantSelection\",\n StartTerminal = \"StartTerminal\",\n EndTerminal = \"EndTerminal\",\n MiscNote = \"MiscNote\",\n Assign = \"Assign\",\n CsvVlookup = \"CsvVlookup\",\n ProcessFlow = \"ProcessFlow\",\n TemporaryAssetUrl = \"TemporaryAssetUrl\",\n WebRequest = \"WebRequest\",\n}\n\ninterface ExecutionNodeResponse {\n id: string;\n type: NodeType;\n artifacts: string;\n}\n\ninterface ExecutionResponse {\n id: string;\n nodes: ExecutionNodeResponse[];\n completedAt?: string;\n failedAt?: string;\n}\n\n/**\n * A service containing functionality for interacting with the Spiff Commerce API to execute and inspect the result of process flows.\n */\nexport class FlowService {\n /**\n *\n * @param id\n * @param inputs\n * @param options\n * @returns\n */\n async execute(\n id: string,\n inputs: FlowExecutionInput[],\n options?: { sleepTime?: number; repeats?: number },\n ): Promise<FlowExecutionResult> {\n // Fire the execution\n const createResponse = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ processExecutionCreate: { id: string } }>({\n mutation: executeProcessFlow,\n variables: {\n processFlowId: id,\n inputs: [...inputs.map((input) => input.getValueForTransmission())],\n },\n });\n\n const executionId = createResponse.data?.processExecutionCreate?.id;\n if (!executionId) throw new Error(\"Failed to create process execution.\");\n\n function delay(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms); // Convert seconds to milliseconds\n });\n }\n\n // Evaluate completion\n let completed: boolean = false;\n let repeats = 0;\n let response: ApolloQueryResult<ExecutionResponseGraphQL> | undefined;\n let flowResult: FlowExecutionResult | undefined = undefined;\n while (!completed) {\n response = await graphQlManager.getShadowGraphqlClient().query<ExecutionResponseGraphQL>({\n query: gql`\n query getProcessFlowExecution($ids: [String]!) {\n processExecutions(ids: $ids) {\n id\n completedAt\n failedAt\n nodes {\n id\n type\n artifacts\n }\n }\n }\n `,\n variables: {\n ids: [executionId],\n },\n });\n const responseData = response.data?.processExecutions[0];\n\n // Check valid response\n if (!response || !responseData) throw new Error(\"Failed to retrieve server response for execution.\");\n\n // If the execution failed prompt developer to access execution details in hub\n if (responseData.failedAt) {\n throw new Error(\n \"Execution has failed to complete. See Automation > FLows in Flight on partner account on SpiffCommerce Hub.\",\n );\n }\n\n // Check for completion otherwise.\n if (responseData.completedAt) {\n completed = true;\n flowResult = new FlowExecutionResult(responseData);\n break;\n }\n\n repeats += 1;\n\n const maxRepeats = options?.repeats ? options?.repeats : 5;\n if (repeats >= maxRepeats) throw new Error(\"Maximum wait time exceeded for execution result.\");\n await delay(options?.sleepTime ? Math.max(options.sleepTime, 500) : 2000);\n }\n if (!flowResult) throw new Error(\"Failed to retrieve server response for execution.\");\n return Promise.resolve(flowResult);\n }\n}\n\n/**\n * Handles preparing a flow input for transmission to the server.\n */\nexport class FlowExecutionResult {\n protected readonly execution: ExecutionResponse;\n\n constructor(execution: ExecutionResponse) {\n this.execution = execution;\n }\n\n /**\n * @returns The raw response from the server.\n */\n getRaw(): ExecutionResponse {\n return this.execution;\n }\n\n /**\n * @returns The nodes contained within the execution.\n */\n getNodes(): FlowExecutionNodeResult[] {\n return this.execution.nodes.map((n) => new FlowExecutionNodeResult(n));\n }\n\n /**\n * @param type The type of node to return.\n * @returns A list of nodes matching the requested type.\n */\n getNodesByType(type: NodeType): FlowExecutionNodeResult[] {\n return this.execution.nodes.filter((n) => n.type === type).map((n) => new FlowExecutionNodeResult(n));\n }\n\n /**\n * @returns A list of input nodes that exist in this execution.\n */\n getInputs(): FlowExecutionNodeResult[] {\n return this.execution.nodes\n .filter((n) => n.type === NodeType.StartTerminal)\n .map((n) => new FlowExecutionNodeResult(n));\n }\n\n /**\n * @returns A list of out put nodes that exist in this execution.\n */\n getOutputs(): FlowExecutionNodeResult[] {\n return this.execution.nodes\n .filter((n) => n.type === NodeType.EndTerminal)\n .map((n) => new FlowExecutionNodeResult(n));\n }\n\n /**\n * @returns A date object representing the point in time this execution completed.\n */\n getCompletedAt(): Date | undefined {\n if (!this.execution.completedAt) return undefined;\n return new Date(this.execution.completedAt);\n }\n\n /**\n * @returns A date object representing the point in time this execution failed.\n */\n getFailedAt(): Date | undefined {\n if (!this.execution.failedAt) return undefined;\n return new Date(this.execution.failedAt);\n }\n}\n\n/**\n * Handles preparing a flow input for transmission to the server.\n */\nexport class FlowExecutionNodeResult {\n protected readonly node: ExecutionNodeResponse;\n\n constructor(node: ExecutionNodeResponse) {\n this.node = node;\n }\n\n getId(): string {\n return this.node.id;\n }\n\n getType(): NodeType {\n return this.node.type;\n }\n\n getArtifacts(): Map<string, any> {\n return new Map(Object.entries(JSON.parse(this.node.artifacts).value));\n }\n\n getArtifactByName<T>(name: string): T {\n return this.getArtifacts().get(name) as T;\n }\n}\n\n/**\n * Handles preparing a flow input for transmission to the server.\n */\nabstract class FlowExecutionInput {\n protected readonly value: string;\n constructor(value: string) {\n this.value = value;\n }\n getRaw(): string {\n return this.value;\n }\n getValueForTransmission(): string {\n const v = this.value;\n if (v.startsWith(\"[\")) {\n return JSON.stringify(JSON.parse(v));\n } else {\n return v;\n }\n }\n}\n\n/**\n * Represents the type of object being referenced by the input.\n */\nexport const enum ObjectInputType {\n Transaction = \"Transaction\",\n Bundle = \"Bundle\",\n Product = \"Product\",\n Variant = \"Variant\",\n Option = \"Option\",\n LineItem = \"LineItem\",\n Asset = \"Asset\",\n}\n\nexport class TextInput extends FlowExecutionInput {\n constructor(input: string) {\n super(`\"${input}\"`);\n }\n}\n\n/**\n * Handles validation of spiffObject structure for transmission to the server.\n */\nexport class ObjectInput extends FlowExecutionInput {\n constructor(id: string, type: ObjectInputType) {\n // Assets aren't a UUID but most other assets will be UUID values.\n if (type !== ObjectInputType.Asset && !ObjectInput.validUUID(id))\n throw new Error(\"Invalid ID, must be a valid v4 UUID. https://www.uuidgenerator.net/\");\n // The server expects a specific structure for representing a reference to an object in our platform.\n super(`{\"isSpiffObject\": true, \"id\": \"${id}\", \"type\": \"${type}\"}`);\n }\n static validUUID(uuid: string) {\n return uuid.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);\n }\n}\n\n/**\n * Handles validation of array input for transmission to the server.\n */\nexport class ArrayInput extends FlowExecutionInput {\n constructor(elements: FlowExecutionInput[]) {\n super(`[${elements.map((e) => e.getRaw()).join(\",\")}]`);\n }\n}\n","import { ProductWorkflow } from \"./productCollection\";\nimport { IntegrationProductResource } from \"./types\";\n\nexport class IntegrationProduct {\n private readonly integrationProduct: IntegrationProductResource;\n\n constructor(product: IntegrationProductResource) {\n this.integrationProduct = product;\n }\n\n getId(): string {\n return this.integrationProduct.id;\n }\n\n getResource(): IntegrationProductResource {\n return this.integrationProduct;\n }\n\n getBasePrice(): number {\n if (!this.integrationProduct.product) {\n throw new Error(\"IntegrationProductResource does not have a product\");\n }\n const basePrice = this.integrationProduct.product.basePrice || 0;\n const additionalIP = this.integrationProduct?.additionalIntegrationProduct;\n if (!additionalIP) return basePrice;\n if (additionalIP && !additionalIP.product) {\n throw new Error(\"An additional integration product was found, but it does not have a product\");\n }\n return basePrice + (additionalIP.product!.basePrice || 0);\n }\n\n getDefaultWorkflow(): ProductWorkflow {\n if (!this.integrationProduct.product) {\n throw new Error(\"IntegrationProductResource does not have a product\");\n }\n const workflows = this.integrationProduct.product.workflows || [];\n if (workflows.length === 0) {\n throw new Error(\n \"No workflows found on product. This is generally due to a configuration error. Please confirm at least one workflow is configured for this product.\",\n );\n }\n return new ProductWorkflow(workflows[0]);\n }\n\n getAllWorkflows(): ProductWorkflow[] {\n if (!this.integrationProduct.product) {\n throw new Error(\"IntegrationProductResource does not have a product\");\n }\n const workflows = this.integrationProduct.product.workflows || [];\n if (workflows.length === 0) {\n throw new Error(\n \"No workflows found on product. This is generally due to a configuration error. Please confirm at least one workflow is configured for this product.\",\n );\n }\n return workflows\n .sort((a, b) => (a.index ?? 0) - (b.index ?? 0))\n .map((workflow) => new ProductWorkflow(workflow));\n }\n}\n","import { gql } from \"@apollo/client/core\";\n\nexport const getCustomerQuery = gql`\n query GetCustomer($emailAddress: String!) {\n customer(emailAddress: $emailAddress) {\n id\n emailAddress\n hasBundleTemplates\n partner {\n id\n }\n productCollectionCustomers {\n id\n productCollection {\n id\n }\n }\n }\n }\n`;\n\nexport const customerCreateMutation = gql`\n mutation CustomerCreate($details: CustomerDetailsInput!) {\n customerCreate(details: $details) {\n id\n emailAddress\n partner {\n id\n }\n }\n }\n`;\n\nexport const customerAuthenticateMutation = gql`\n mutation CustomerAuthenticate($loginToken: String!) {\n customerAuthenticate(loginToken: $loginToken) {\n id\n emailAddress\n stakeholders {\n id\n type\n transaction {\n id\n }\n }\n bundleStakeholders {\n id\n authorizationStatus\n authorizationDate\n authorizationNote\n type\n bundle {\n id\n transactions {\n id\n }\n }\n }\n partner {\n id\n }\n }\n }\n`;\n\nexport const customerGenerateVerificationCodeMutation = gql`\n mutation CustomerGenerateVerificationCode($emailAddress: String!) {\n customerGenerateVerificationCode(emailAddress: $emailAddress)\n }\n`;\n\nexport const customerVerifyCodeMutation = gql`\n mutation CustomerVerifyCode($emailAddress: String!, $verificationCode: String!) {\n customerVerifyCode(emailAddress: $emailAddress, verificationCode: $verificationCode) {\n id\n emailAddress\n loginToken\n partner {\n id\n }\n stakeholders {\n id\n type\n transaction {\n id\n }\n }\n bundleStakeholders {\n id\n authorizationStatus\n authorizationDate\n authorizationNote\n type\n bundle {\n id\n transactions {\n id\n }\n }\n }\n }\n }\n`;\n\nexport const customerMetafieldsQuery = gql`\n query CustomerMetafields($id: String!) {\n metafields(entityId: $id) {\n id\n createdAt\n updatedAt\n entityId\n value\n metafieldConfiguration {\n id\n createdAt\n updatedAt\n entityType\n metafieldType\n name\n }\n }\n }\n`;\n","import {\n ApolloClient,\n ApolloQueryResult,\n DefaultContext,\n FetchResult,\n MutationOptions,\n OperationVariables,\n QueryOptions,\n} from \"@apollo/client/core\";\nimport { graphQlManager } from \"./server\";\n\ninterface GraphQlClient {\n query<T = any, TVariables extends OperationVariables = OperationVariables>(\n options: QueryOptions<TVariables, T>,\n ): Promise<ApolloQueryResult<T>>;\n mutate<\n TData = any,\n TVariables extends OperationVariables = OperationVariables,\n TContext extends Record<string, any> = DefaultContext,\n >(\n options: MutationOptions<TData, TVariables, TContext>,\n ): Promise<FetchResult<TData>>;\n}\n\nexport type GraphQlClientFunc = () => GraphQlClient;\n\n/**\n * Provides an interface to customize GraphQL requests before they are processed.\n */\nexport class GraphQlClientWrapper implements GraphQlClient {\n constructor(\n private readonly options?: {\n onQuery?: (\n options: QueryOptions<OperationVariables, any>,\n ) => Partial<QueryOptions<OperationVariables, any>>;\n onMutate?: (\n options: MutationOptions<any, OperationVariables, DefaultContext>,\n ) => Partial<MutationOptions<any, OperationVariables, DefaultContext>>;\n },\n private readonly client: () => ApolloClient<any> = graphQlManager.getShadowGraphqlClient.bind(graphQlManager),\n ) {}\n\n query<T = any, TVariables extends OperationVariables = OperationVariables>(\n options: QueryOptions<TVariables, T>,\n ): Promise<ApolloQueryResult<T>> {\n const base = this.options?.onQuery ? this.options?.onQuery(options) : {};\n return this.client().query({\n ...base,\n ...options,\n context: {\n ...(base.context ?? {}),\n ...(options.context ?? {}),\n },\n });\n }\n\n mutate<\n TData = any,\n TVariables extends OperationVariables = OperationVariables,\n TContext extends Record<string, any> = DefaultContext,\n >(options: MutationOptions<TData, TVariables, TContext>): Promise<FetchResult<TData>> {\n const base = this.options?.onMutate ? this.options?.onMutate(options) : {};\n return this.client().mutate({\n ...base,\n ...options,\n context: {\n ...(base.context ?? {}),\n ...(options.context ?? {}),\n },\n });\n }\n}\n","import {\n AuthenticationResultType,\n CognitoIdentityProviderClient,\n InitiateAuthCommand,\n InitiateAuthCommandOutput,\n RespondToAuthChallengeCommand,\n RespondToAuthChallengeCommandOutput,\n} from \"@aws-sdk/client-cognito-identity-provider\";\n\nclass UserPoolManager {\n cognitoClient?: CognitoIdentityProviderClient;\n spiffRegion?: string;\n userPoolClientId?: string;\n\n private challengeSession?: string;\n\n init(spiffRegion: string, userPoolRegion: string, userPoolClientId: string) {\n this.cognitoClient = new CognitoIdentityProviderClient({ region: userPoolRegion });\n this.spiffRegion = spiffRegion;\n this.userPoolClientId = userPoolClientId;\n }\n\n async generateCode(emailAddress: string): Promise<void> {\n const response = await this.cognitoClient?.send(\n new InitiateAuthCommand({\n AuthFlow: \"CUSTOM_AUTH\",\n ClientId: this.userPoolClientId,\n AuthParameters: {\n USERNAME: emailAddress,\n },\n }),\n );\n if (response?.ChallengeName === \"CUSTOM_CHALLENGE\") {\n this.challengeSession = response.Session;\n }\n }\n\n async verifyCode(\n emailAddress: string,\n code: string,\n partnerId: string,\n ): Promise<RespondToAuthChallengeCommandOutput | undefined> {\n const response = await this.cognitoClient?.send(\n new RespondToAuthChallengeCommand({\n ClientId: this.userPoolClientId,\n ChallengeName: \"CUSTOM_CHALLENGE\",\n Session: this.challengeSession,\n ChallengeResponses: {\n USERNAME: emailAddress,\n ANSWER: code,\n },\n ClientMetadata: {\n partnerId,\n environment: (this.spiffRegion || \"\").toLowerCase(),\n },\n }),\n );\n if (response?.ChallengeName === \"CUSTOM_CHALLENGE\") {\n this.challengeSession = response.Session;\n }\n return response;\n }\n\n async refreshTokens(): Promise<InitiateAuthCommandOutput | undefined> {\n const existingTokensString = localStorage.getItem(\"cognito-tokens\");\n if (!existingTokensString) {\n throw new Error(\"Failed to find existing tokens.\");\n }\n const existingTokens: AuthenticationResultType = JSON.parse(existingTokensString);\n return await this.cognitoClient?.send(\n new InitiateAuthCommand({\n AuthFlow: \"REFRESH_TOKEN_AUTH\",\n ClientId: this.userPoolClientId,\n AuthParameters: {\n REFRESH_TOKEN: existingTokens.RefreshToken || \"\",\n },\n }),\n );\n }\n}\n\nconst userPoolManager = new UserPoolManager();\nexport { userPoolManager };\n","import Dinero, { Currency } from \"dinero.js\";\nimport * as CurrencyCodes from \"currency-codes\";\n\nexport class CurrencyService {\n /**\n * Returns a formatted string representing a given amount with desired currency.\n * @param currency The currency to represent the amount in.\n * @param amount The amount in minor units to format.\n */\n formatCurrencyForDisplay(currency: Currency, amount: number) {\n const currencyFormatSettings = {\n amount: amount || 0,\n currency,\n precision: this.getPrecisionForCurrency(currency),\n };\n const formatter = Dinero(currencyFormatSettings);\n return formatter.toFormat(this.getSpecialFormat(currency));\n }\n\n /**\n * Get the number of decimal places expected in a currency string.\n * @param currency The currency to determine precision for.\n */\n getPrecisionForCurrency(currency: Currency) {\n const currencyCode = currency as string;\n const currencyCodeData = CurrencyCodes.code(currencyCode);\n if (!currencyCodeData) {\n return 2;\n }\n return currencyCodeData.digits;\n }\n\n /**\n * Sometimes default formatting will display format in a way that isn't natural\n * for natives of a currency. This function is intended to capture those specific cases and return a format\n * that makes the most sense.\n * @param currency The currency to test for special format.\n */\n private getSpecialFormat(currency: Currency) {\n const currencyCode = currency as string;\n const currencyCodeData = CurrencyCodes.code(currencyCode);\n\n // Special case for Chilean Peso (CLP) where the format is not standard.\n if (currencyCodeData?.code === \"CLP\") {\n return \"USD0,0\"; // USD will return the currency code given.\n }\n\n return undefined;\n }\n}\n\nconst currencyService = new CurrencyService();\n\nexport class CurrencyContext {\n private readonly presentmentCurrency?: Currency = undefined;\n private readonly partnerCurrency: Currency;\n private readonly rateFrom: number;\n private readonly rateTo: number;\n\n constructor(rateFrom: number, rateTo: number, partnerCurrency: Currency, presentmentCurrency?: Currency) {\n this.presentmentCurrency = presentmentCurrency;\n this.partnerCurrency = partnerCurrency;\n this.rateFrom = rateFrom;\n this.rateTo = rateTo;\n }\n\n /**\n * @returns The currency code for the currency being used for monetary display.\n */\n code(): Currency {\n return this.presentmentCurrency ? this.presentmentCurrency : this.partnerCurrency;\n }\n\n /**\n * @returns true if the conversion is required, false otherwise.\n */\n conversionRequired(): boolean {\n return this.presentmentCurrency !== undefined && this.code() !== this.partnerCurrency;\n }\n\n /**\n * Converts a monetary value from a workflow in a partner specified currency\n * to the units of the currency being used for display.\n * @param amount The amount in minor units to convert.\n * @returns\n */\n getConvertedSubunits(amount: number): number {\n if (!this.conversionRequired()) {\n return amount;\n }\n return Math.ceil(\n this.subunits((this.units(amount, this.partnerCurrency) / this.rateFrom) * this.rateTo, this.code()),\n );\n }\n\n /**\n * Converts a monetary value from the database to the units of its currency.\n */\n private units(subUnits: number, currencyCode: Currency): number {\n return subUnits / Math.pow(10, currencyService.getPrecisionForCurrency(currencyCode));\n }\n\n /**\n * Converts a monetary value in units to the subunits of its currency.\n */\n private subunits(units: number, currencyCode: Currency): number {\n return units * Math.pow(10, currencyService.getPrecisionForCurrency(currencyCode));\n }\n}\n\nexport { currencyService };\n","import {\n readTransactionsQuery,\n updateTransactionWorkflowStateQuery,\n createManyTransactionsMutation,\n getIntegrationProductsQuery,\n getIntegrationProductFromExternalIdsQuery,\n getTransactionShareActionsQuery,\n currentIntegrationQuery,\n getWorkflowsQuery,\n getMarketplaceThemeInstallConfigurationQuery,\n getBundleForMarketplaceThemeQuery,\n getTransactionForMarketplaceThemeQuery,\n getTransactionQuery,\n createOrderMutation,\n currencyConversionQuery,\n readIntegrationProductsQuery,\n} from \"./query\";\nimport { AssetManager, assetService } from \"./services/asset\";\nimport { persistenceService } from \"./services/persistence\";\nimport { getApplicationKey, graphQlManager, setApplicationKey, setBearerAuthenticationToken } from \"./services/server\";\nimport {\n Bundle as BundleEntity,\n BundleStakeholder,\n Customer,\n IntegrationProductResource,\n StakeholderType,\n Transaction,\n Extendable,\n Integration,\n AddonHandle,\n ShareAction,\n Metafield,\n BundlesFeed,\n BundleTemplateStatus,\n LayoutsState,\n Workflow,\n Theme,\n GlobalPropertyState,\n OrderItem,\n Order,\n Product,\n} from \"./types\";\nimport { ClientError, UnhandledBehaviorError } from \"./util/exception\";\nimport { ExperienceOptions, WorkflowExperience, WorkflowExperienceImpl } from \"./WorkflowExperience\";\nimport { StateMutationFunc } from \"./WorkflowManager\";\nimport { Bundle, BundleImpl } from \"./Bundle\";\nimport {\n createBundleMutation,\n customerBundlesFeedQuery,\n deleteBundleQuery,\n duplicateBundleMutation,\n findBundleForTransactionsQuery,\n getBundleQuery,\n getBundlesAndStakeholdersForCustomerQuery,\n} from \"./Bundle/query\";\nimport { FlowService } from \"./flowService\";\nimport promiseCache from \"./services/promiseCache\";\nimport type { ThreeDPreviewService } from \"@spiffcommerce/preview\";\nimport chunk from \"lodash.chunk\";\nimport { IntegrationProduct } from \"./integration\";\nimport { spiffCoreConfiguration } from \"./Configuration\";\nimport { isTokenExpired } from \"./services/design\";\nimport {\n getCustomerQuery,\n customerCreateMutation,\n customerGenerateVerificationCodeMutation,\n customerMetafieldsQuery,\n} from \"./customer\";\nimport { rehydrateSerializedLayout } from \"./LayoutsState\";\nimport { ThemeInstallConfigurationGraphQl } from \"@spiffcommerce/theme-bridge\";\nimport { GraphQlClientWrapper } from \"./services/graphql\";\nimport { AuthenticationResultType } from \"@aws-sdk/client-cognito-identity-provider\";\nimport { userPoolManager } from \"./services/userPool\";\nimport { CurrencyContext } from \"./currency\";\n\nconst getWorkflowsInternal = async (ids: string[], options?: GetWorkflowGraphqlOptions): Promise<Workflow[]> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ workflows: Workflow[] }>({\n query: getWorkflowsQuery(options?.assets?.metadata || false),\n errorPolicy: \"all\",\n variables: {\n ids,\n },\n });\n if (response.error) {\n throw response.error;\n }\n if (response.errors) {\n response.errors.forEach((e) => console.error(e));\n throw new Error(\"Unable to read workflows. Consult GraphQL errors.\");\n }\n const workflows = response.data.workflows;\n if (workflows === undefined || workflows.length !== ids.length) {\n throw new Error(`Unable to read workflows: ${response.errors ?? \"Length mismatch in response\"}`);\n }\n workflows.forEach((workflow) => {\n if (!workflow.finalizeStepConfig) {\n workflow.finalizeStepConfig = {};\n }\n workflow.finalizeStepConfig.termsMarkdown =\n workflow.finalizeStepConfig.termsMarkdown || (workflow as any).partner.termsMarkdown;\n });\n return workflows;\n};\n\nconst pickWorkflowFromPromise = async (id: string, promise: Promise<Workflow[]>): Promise<Workflow> => {\n const workflows = await promise;\n const workflow = workflows.find((workflow) => workflow.id === id);\n if (!workflow) {\n throw new Error(`Workflow not found: ${id}`);\n }\n return workflow;\n};\n\nexport const getWorkflows = async (ids: string[], options?: GetWorkflowGraphqlOptions): Promise<Workflow[]> => {\n const existingPromises = ids.map((id) => promiseCache.get({ id, options }));\n const uncachedIds = ids.filter((_id, index) => existingPromises[index] === undefined);\n if (uncachedIds.length === 0) {\n return Promise.all(existingPromises);\n }\n const getWorkflowsPromise = getWorkflowsInternal(uncachedIds, options);\n const uncachedPromises = uncachedIds.map((id) =>\n promiseCache.set({ id, options }, pickWorkflowFromPromise(id, getWorkflowsPromise)),\n );\n const filteredPromises = existingPromises.filter((promise) => promise !== undefined);\n return await Promise.all(filteredPromises.concat(uncachedPromises));\n};\n\nexport const getWorkflow = async (id: string, options?: GetWorkflowGraphqlOptions): Promise<Workflow> => {\n return (await getWorkflows([id], options))[0];\n};\n\nexport const getIntegrationProducts = async (ids: string[]): Promise<IntegrationProductResource[]> => {\n const resp = await graphQlManager\n .getShadowGraphqlClient()\n .query<{ integrationProducts?: IntegrationProductResource[] }>({\n query: readIntegrationProductsQuery,\n variables: {\n ids: ids,\n },\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n });\n if (resp.errors) {\n console.error(resp.errors);\n }\n return resp.data.integrationProducts || [];\n};\n\n/**\n * Options that can be used during instantiation of the SpiffCommerce Javascript Client.\n * Please refer to the documentation for more information.\n */\ninterface ClientOptions {\n /**\n * The client will use the provided application key to\n * authenticate with the SpiffCommerce API. This key can be generated and replaced in Spiffcommerce Hub.\n */\n applicationKey?: string;\n\n /**\n * Force enable beta features, even if the partner does not have the flag turned on.\n *\n * This is generally reserved for development and testing.\n */\n enableBetaFeatures?: boolean;\n}\n\nexport interface GetBundleGraphqlAssetsOptions {\n metadata?: boolean;\n}\n\nexport interface GetBundleGraphqlProductCollectionOptions {\n eagerFetchProducts?: boolean;\n}\n\nexport interface GetBundleGraphqlOptions {\n productCollection?: GetBundleGraphqlProductCollectionOptions;\n assets?: GetBundleGraphqlAssetsOptions;\n additionalHeaders?: { [key: string]: string };\n}\n\nexport interface GetBundleOptions {\n /**\n * Configuration for the graphQL request made for bundles. Allows for retrieval\n * of additional data.\n */\n graphql?: GetBundleGraphqlOptions;\n readonly?: boolean;\n}\n\nexport interface GetWorkflowGraphqlAssetsOptions {\n metadata?: boolean;\n}\n\nexport interface GetWorkflowGraphqlOptions {\n assets?: GetWorkflowGraphqlAssetsOptions;\n bundleOwnerId?: string;\n}\n\nexport interface GetWorkflowOptionsBase {\n /**\n * An existing preview service to use, instead of creating a new one.\n */\n previewService?: ThreeDPreviewService;\n\n /**\n * Configuration related to the\n * workflow and how the system interprets it.\n */\n workflowConfiguration?: {\n /**\n * False by default, when true the system will treat\n * steps with a single variant\n * as being renderable.\n */\n singleVariantsRenderable?: boolean;\n };\n\n /**\n * Configuration for the graphQL request made for workflows. Allows for retrieval\n * of additional data.\n */\n graphql?: GetWorkflowGraphqlOptions;\n}\n\nexport interface GetWorkflowFromTransactionOptions extends GetWorkflowOptionsBase {\n /** The existing Transaction to use. */\n transactionId: string;\n /** If set to true, the workflow will display in a read-only mode. */\n readOnly?: boolean;\n /** An existing workflow state, if available. */\n workflowState?: string;\n type: \"transaction\";\n}\n\nexport interface GetNewWorkflowExperienceOptionsBase extends GetWorkflowOptionsBase {\n /** A name for the new transaction. */\n designName?: string;\n /** The workflow to load. */\n workflowId?: string;\n /** An existing workflow state, if available. */\n workflowState?: string;\n /** An initial quantity to use in place of the default. */\n quantity?: number;\n /** Initial recipient details to use. */\n recipient?: any;\n}\n\nexport interface GetWorkflowExperienceFromBlankOptions extends GetNewWorkflowExperienceOptionsBase {\n type: \"blank\";\n}\n\nexport interface GetWorkflowExperienceFromIntegrationProductOptions extends GetNewWorkflowExperienceOptionsBase {\n integrationProductId: string;\n type: \"integration\";\n}\n\nexport interface GetWorkflowExperienceFromExternalProductOptions extends GetNewWorkflowExperienceOptionsBase {\n /** The external ID associated with an integration. */\n externalIntegrationId: string;\n /** The ID of the product from the external system. */\n externalProductId: string;\n type: \"external\";\n}\n\nexport type GetNewWorkflowExperienceOptions =\n | GetWorkflowExperienceFromBlankOptions\n | GetWorkflowExperienceFromIntegrationProductOptions\n | GetWorkflowExperienceFromExternalProductOptions;\n\nexport type GetWorkflowOptions = GetWorkflowFromTransactionOptions | GetNewWorkflowExperienceOptions;\n\ninterface ClientConfiguration {\n hubUrl: string;\n serverUrl: string;\n servicesApiUrl: string;\n marketplaceThemeInstallId?: string;\n marketplaceThemeInstallConfigurationId?: string;\n bearerAuthenticationToken?: string;\n userPoolClientId?: string;\n userPoolRegion?: string;\n spiffRegion?: string; // dev | au | us\n}\n\n/**\n * The Spiff Commerce Javascript Client. Required for\n * creating workflow experiences.\n */\nexport class SpiffCommerceClient {\n private options: ClientOptions;\n private customer?: Customer;\n private activeIntegration?: Promise<Integration> = undefined;\n private marketplaceThemeInstallId?: string;\n private marketplaceThemeInstallConfigurationId?: string;\n private userPoolClientId?: string;\n private userPoolRegion?: string;\n private spiffRegion?: string;\n\n constructor(options: ClientOptions) {\n this.options = options;\n\n this.options.applicationKey && setApplicationKey(this.options.applicationKey);\n\n console.debug(\"------------------------\");\n console.debug(\"Spiff Commerce Core SDK\");\n console.debug(`Version: ${__SPIFF_CORE_VERSION__}`);\n console.debug(`Application Key Provided: ${!!this.options.applicationKey}`);\n console.debug(\"------------------------\");\n }\n\n configure(configuration: ClientConfiguration) {\n spiffCoreConfiguration.setHubUrl(configuration.hubUrl);\n spiffCoreConfiguration.setServerUrl(configuration.serverUrl);\n spiffCoreConfiguration.setServicesApiUrl(configuration.servicesApiUrl);\n this.marketplaceThemeInstallId = configuration.marketplaceThemeInstallId;\n this.marketplaceThemeInstallConfigurationId = configuration.marketplaceThemeInstallConfigurationId;\n this.userPoolClientId = configuration.userPoolClientId;\n this.userPoolRegion = configuration.userPoolRegion;\n this.spiffRegion = configuration.spiffRegion;\n if (configuration.bearerAuthenticationToken) {\n setBearerAuthenticationToken(configuration.bearerAuthenticationToken);\n }\n if (this.options.applicationKey) {\n this.getIntegration();\n }\n if (this.spiffRegion && this.userPoolRegion && this.userPoolClientId) {\n userPoolManager.init(this.spiffRegion, this.userPoolRegion, this.userPoolClientId);\n }\n }\n\n /**\n * @returns The asset manager allows for common operations related to assets\n * and the Spiff Commerce platform.\n */\n getAssetManager(): AssetManager {\n return assetService;\n }\n\n /**\n * @returns A promise that resolves with a boolean indicating whether to use beta features.\n */\n async getBetaEnabled(): Promise<boolean> {\n if (this.options.enableBetaFeatures) {\n return true;\n }\n return (await this.getIntegration()).partner.beta === true;\n }\n\n getFlowService(): FlowService {\n const appKey = getApplicationKey();\n if (!appKey) throw new Error(\"Application key required to use Flow Service.\");\n return new FlowService();\n }\n\n async getCurrencyContext(presentmentCurrency: string): Promise<CurrencyContext> {\n const integration = await this.getIntegration();\n const partnerCurrency = integration.partner.currencyCode;\n\n const graphqlClient = graphQlManager.getShadowGraphqlClient();\n // Fetch the transaction to retrieve the associated partner ID.\n const conversionResponse = await graphqlClient.query<{\n currencyConversion: { rateFrom: number; rateTo: number; timestamp: number };\n }>({\n query: currencyConversionQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"cache-first\",\n variables: {\n from: partnerCurrency,\n to: presentmentCurrency,\n },\n });\n\n const { rateFrom, rateTo } = conversionResponse.data.currencyConversion;\n\n return new CurrencyContext(rateFrom, rateTo, partnerCurrency, presentmentCurrency);\n }\n\n async getIntegration(): Promise<Integration> {\n if (this.activeIntegration) {\n return this.activeIntegration;\n }\n if (!this.options.applicationKey) {\n throw new Error(\"Cannot get current Integration without specifying an Application Key.\");\n }\n this.activeIntegration = getIntegration(this.options.applicationKey);\n return this.activeIntegration;\n }\n\n async canUseAddon(addonHandle: AddonHandle): Promise<boolean> {\n try {\n const integration = await this.getIntegration();\n return integration.partner.activeAddons?.includes(addonHandle) ?? false;\n } catch (e) {\n console.error(e);\n return false;\n }\n }\n\n clearCustomer() {\n this.customer = undefined;\n }\n\n clearCustomerForTransaction(transactionId: string) {\n const transactionCustomers = persistenceService.getMap(\"transactionCustomerIds\");\n if (transactionCustomers?.has(transactionId)) {\n transactionCustomers.delete(transactionId);\n persistenceService.setMap(\"transactionCustomerIds\", transactionCustomers);\n }\n }\n\n async customerHasBundleTemplates(emailAddress: string): Promise<boolean> {\n const graphqlClient = graphQlManager.getShadowGraphqlClient();\n const customerResponse = await graphqlClient.query<{ customer: Customer }>({\n query: getCustomerQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n emailAddress,\n },\n });\n const customer = customerResponse.data.customer;\n if (!customer.id) {\n return false;\n }\n return customer.hasBundleTemplates ?? false;\n }\n\n getStakeholderTypeForTransaction(transactionId: string): StakeholderType | undefined {\n const transactionStakeholder = this.customer?.stakeholders?.find(\n (stakeholder) => stakeholder.transaction?.id === transactionId,\n );\n if (!transactionStakeholder) {\n return undefined;\n }\n return transactionStakeholder.type;\n }\n\n async getOrCreateCustomer(emailAddress: string): Promise<{\n customer: Customer;\n isAuthenticated: boolean;\n }> {\n this.customer = undefined;\n const graphqlClient = graphQlManager.getShadowGraphqlClient();\n // Grabs the customer from the API, using the application key to resolve the partner.\n const customerResponse = await graphqlClient.query<{ customer: Customer }>({\n query: getCustomerQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n emailAddress,\n },\n });\n const customer = customerResponse.data.customer;\n if (!customer.id) {\n const customerCreateResponse = await graphqlClient.mutate<{ customerCreate: Customer }>({\n mutation: customerCreateMutation,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n details: {\n emailAddress,\n },\n },\n });\n const createdCustomer = customerCreateResponse.data?.customerCreate;\n if (!createdCustomer) {\n throw new Error(\"Unable to create customer.\");\n }\n this.storeCustomer(createdCustomer);\n this.customer = createdCustomer;\n return {\n customer: createdCustomer,\n isAuthenticated: false,\n };\n }\n this.storeCustomer(customer);\n const authResult = await this.reloadLoggedInCustomer();\n return {\n customer: this.customer || customer,\n isAuthenticated: authResult,\n };\n }\n\n getCustomer() {\n return this.customer;\n }\n\n /**\n * Check if a customer is logged in.\n * If they are, set the customer object.\n * This is how we resume sessions between loads.\n */\n async reloadLoggedInCustomer(): Promise<boolean> {\n // If nothing in local storage, return false.\n const lastRefreshed = localStorage.getItem(\"last-refreshed-cognito-tokens\");\n const existingTokensString = localStorage.getItem(\"cognito-tokens\");\n const emailAddress = localStorage.getItem(\"cognito-email\");\n if (!lastRefreshed || !existingTokensString || !emailAddress) {\n return false;\n }\n\n // If we need to refresh the token, do it.\n const existingTokens: AuthenticationResultType = JSON.parse(existingTokensString);\n const nowSeconds = new Date().getTime() / 1000;\n if (!existingTokens.ExpiresIn || existingTokens.ExpiresIn < nowSeconds - parseInt(lastRefreshed)) {\n const response = await userPoolManager.refreshTokens();\n if (response?.AuthenticationResult) {\n localStorage.setItem(\"last-refreshed-cognito-tokens\", `${new Date().getTime() / 1000}`);\n existingTokens.AccessToken = response.AuthenticationResult.AccessToken;\n localStorage.setItem(\"cognito-tokens\", JSON.stringify(existingTokens));\n } else {\n this.logOut();\n console.error(\"Failed to refresh tokens.\");\n return false;\n }\n }\n\n // Check that the customer ID is the expected one.\n const customerResponse = await graphQlManager.getShadowGraphqlClient().query<{ customer: Customer }>({\n query: getCustomerQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n emailAddress,\n },\n });\n const customer = customerResponse.data.customer;\n\n if (!customer.id) {\n console.error(\"Failed to get customer.\");\n return false;\n }\n this.customer = customer;\n\n return true;\n }\n\n /**\n * Generate an email code to allow logging in as a Spiff user.\n */\n async generateVerificationCode(emailAddress: string): Promise<void> {\n // First we invoke the generate method of the old flow, for two outcomes:\n // 1. To create a customer for the given user and partner if it doesn't exist.\n // 2. To generate the login code in the backend.\n await graphQlManager.getShadowGraphqlClient().mutate({\n mutation: customerGenerateVerificationCodeMutation,\n variables: {\n emailAddress,\n },\n });\n\n await userPoolManager.generateCode(emailAddress);\n }\n\n /**\n * Verify an email code to log in as a Spiff user.\n * Always returns true if it doesn't throw.\n */\n async verifyCode(emailAddress: string, code: string): Promise<boolean> {\n const partnerId = (await this.getIntegration()).partner.id || \"\";\n const response = await userPoolManager.verifyCode(emailAddress, code, partnerId);\n if (response?.AuthenticationResult) {\n localStorage.setItem(\"last-refreshed-cognito-tokens\", `${new Date().getTime() / 1000}`);\n localStorage.setItem(\"cognito-tokens\", JSON.stringify(response.AuthenticationResult));\n localStorage.setItem(\"cognito-email\", emailAddress);\n\n const customerResponse = await graphQlManager.getShadowGraphqlClient().query<{ customer: Customer }>({\n query: getCustomerQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n emailAddress,\n },\n });\n const customer = customerResponse.data.customer;\n if (!customer.id) {\n throw new Error(\"Failed to get customer.\");\n }\n this.customer = customer;\n return true;\n } else {\n throw new Error();\n }\n }\n\n /**\n * Log out the currently logged-in Spiff user.\n */\n async logOut(): Promise<void> {\n localStorage.removeItem(\"last-refreshed-cognito-tokens\");\n localStorage.removeItem(\"cognito-tokens\");\n localStorage.removeItem(\"cognito-email\");\n this.clearCustomer();\n }\n\n // Get a Cognito bearer token from local storage, attempting to refresh if it's old.\n async loggedInBearerToken(): Promise<string> {\n const lastRefreshed = localStorage.getItem(\"last-refreshed-cognito-tokens\");\n const existingTokensString = localStorage.getItem(\"cognito-tokens\");\n if (!lastRefreshed || !existingTokensString) {\n throw new Error(\"No token data in storage.\");\n }\n const existingTokens: AuthenticationResultType = JSON.parse(existingTokensString);\n const nowSeconds = new Date().getTime() / 1000;\n const expired = !existingTokens?.AccessToken || isTokenExpired(existingTokens.AccessToken);\n if (!existingTokens.ExpiresIn || existingTokens.ExpiresIn < nowSeconds - parseInt(lastRefreshed) || expired) {\n const response = await userPoolManager.refreshTokens();\n if (response?.AuthenticationResult) {\n localStorage.setItem(\"last-refreshed-cognito-tokens\", `${new Date().getTime() / 1000}`);\n existingTokens.AccessToken = response.AuthenticationResult.AccessToken;\n localStorage.setItem(\"cognito-tokens\", JSON.stringify(existingTokens));\n } else {\n this.logOut();\n throw new Error(\"Failed to refresh tokens.\");\n }\n }\n if (!existingTokens.AccessToken) {\n throw new Error(\"No bearer token in storage.\");\n }\n return existingTokens.AccessToken;\n }\n\n async getCustomerMetafields(): Promise<Metafield[]> {\n if (!this.customer?.id) {\n throw new Error(\"Customer must be logged in before calling this function.\");\n }\n const response = await graphQlManager.getShadowGraphqlClient().query<{ metafields: Metafield[] }>({\n query: customerMetafieldsQuery,\n variables: {\n id: this.customer.id,\n },\n });\n return response.data.metafields;\n }\n\n /**\n * @param collectionId Optional: The id of the product collection that the bundle can use.\n * @returns A bundle to be used for grouping and operating on large amounts of workflow experiences.\n */\n async getNewBundle(\n collectionId?: string,\n initialMetadata?: { [key: string]: string },\n options?: GetBundleOptions,\n ): Promise<Bundle> {\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{ bundleCreate: BundleEntity }>({\n mutation: createBundleMutation(options?.graphql?.productCollection?.eagerFetchProducts || false),\n variables: {\n collectionId,\n initialMetadata: initialMetadata\n ? Object.entries(initialMetadata).map((k, _idx) => {\n return { key: k[0], value: k[1] };\n })\n : undefined,\n marketplaceThemeInstallId: this.marketplaceThemeInstallId,\n marketplaceThemeInstallConfigurationId: this.marketplaceThemeInstallConfigurationId,\n },\n fetchPolicy: \"no-cache\",\n });\n const bundleEntity = response.data?.bundleCreate;\n if (!bundleEntity?.id) {\n throw new Error(`Unable to create bundle`);\n }\n\n const bundlePartnerMap = persistenceService.getMap(\"bundlePartnerIds\") || new Map();\n bundlePartnerMap.set(bundleEntity.id!, bundleEntity.partner!.id);\n persistenceService.setMap(\"bundlePartnerIds\", bundlePartnerMap);\n\n // Store the bundle owner id in local storage.\n const ownerMap = persistenceService.getMap(\"bundleOwnerIds\") || new Map();\n ownerMap.set(bundleEntity.id!, bundleEntity.bundleOwnerId!);\n persistenceService.setMap(\"bundleOwnerIds\", ownerMap);\n // Return a new bundle instance for this bundle entity.\n const newBundle = new BundleImpl(this, bundleEntity, undefined, undefined, bundleEntity.bundleOwnerId, {\n eagerFetchProducts: options?.graphql?.productCollection?.eagerFetchProducts,\n });\n await newBundle.getInitializationPromise();\n return newBundle;\n }\n\n /**\n * Retrieves an existing bundle from the API, by id.\n * @param bundleId The id of the bundle to retrieve.\n * @param previewService Optional: A reference to an existing preview service to use. This can be assigned manually later.\n * @param graphqlOptions Optional: Options to configure loading the bundle.\n * @param options Optional: Options to configure loading the bundle.\n * @returns A bundle to be used for grouping and operating on large amounts of workflow experiences.\n */\n async getExistingBundle(\n bundleId: string,\n previewService?: ThreeDPreviewService,\n /**\n * @deprecated use GetBundleOptions instead. This attribute will be removed in the future.\n */\n graphqlOptions?: GetBundleGraphqlOptions,\n options?: GetBundleOptions,\n transactionLoadProgressCallback?: (loaded: number, total: number) => void,\n ): Promise<Bundle> {\n const ownerMap = persistenceService.getMap(\"bundleOwnerIds\");\n const bundleOwnerId = ownerMap?.get(bundleId);\n\n const extraHeaders: { [key: string]: string } = {};\n try {\n const token = await this.loggedInBearerToken();\n extraHeaders[\"Authorization\"] = `Bearer ${token}`;\n } catch (e) {\n // Hack to get the token from editor's amplify.\n const keys = Object.entries(localStorage);\n const jwtTokenKey =\n keys.find(([k, _]) => {\n return k.startsWith(\"CognitoIdentityServiceProvider\") && k.endsWith(\"idToken\");\n })?.[0] || \"\";\n const jwtToken = localStorage.getItem(jwtTokenKey);\n if (jwtToken && !isTokenExpired(jwtToken)) {\n extraHeaders[\"Authorization\"] = `Bearer ${jwtToken}`;\n }\n }\n\n // TODO: Update customer auth to store bundle stakeholders as well.\n const contextHeaders = {\n bundleOwnerId,\n ...extraHeaders,\n ...options?.graphql?.additionalHeaders,\n };\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n globalPropertyState: GlobalPropertyState;\n bundles: BundleEntity[];\n }>({\n query: getBundleQuery(options?.graphql?.productCollection?.eagerFetchProducts || false),\n variables: {\n id: bundleId,\n },\n fetchPolicy: \"no-cache\",\n context: {\n headers: contextHeaders,\n },\n });\n if (!response.data?.bundles || response.data?.bundles.length === 0 || !response.data?.bundles[0]) {\n throw new Error(`Unable to find bundle: ${bundleId}`);\n }\n const bundleEntity = response.data?.bundles[0];\n\n const bundlePartnerMap = persistenceService.getMap(\"bundlePartnerIds\") || new Map();\n bundlePartnerMap.set(bundleEntity.id!, bundleEntity.partner!.id);\n persistenceService.setMap(\"bundlePartnerIds\", bundlePartnerMap);\n\n const bundleWrapper = new BundleImpl(\n this,\n bundleEntity,\n previewService,\n graphqlOptions,\n bundleOwnerId,\n {\n additionalHeaders: options?.graphql?.additionalHeaders,\n eagerFetchProducts: options?.graphql?.productCollection?.eagerFetchProducts,\n existingGlobalPropertyState: response.data.globalPropertyState,\n readonly: options?.readonly,\n },\n transactionLoadProgressCallback,\n );\n await bundleWrapper.getInitializationPromise();\n return bundleWrapper;\n }\n\n /**\n * @param bundleId The id of the bundle to copy. The current context must have write access to the this bundle in order to duplicate it.\n * @param template Optional: Whether to mark the new bundle as a template. Default is false.\n * @param duplicateTransactions Optional: Whether to also duplicate the original bundle's transactions. Default is true.\n * @returns A bundle to be used for grouping and operating on large amounts of workflow experiences.\n */\n async duplicateBundle(\n bundleId: string,\n template?: boolean,\n duplicateTransactions?: boolean,\n options?: GetBundleOptions,\n ): Promise<() => Promise<Bundle>> {\n const bundleContextHeaders = await getContextHeadersForBundle(bundleId);\n const contextHeaders = {\n ...bundleContextHeaders,\n ...options?.graphql?.additionalHeaders,\n };\n\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{ bundleDuplicate: BundleEntity }>({\n mutation: duplicateBundleMutation(),\n variables: {\n id: bundleId,\n template: template,\n marketplaceThemeInstallId: this.marketplaceThemeInstallId,\n marketplaceThemeInstallConfigurationId: this.marketplaceThemeInstallConfigurationId,\n duplicateTransactions: duplicateTransactions,\n },\n context: {\n headers: contextHeaders,\n },\n fetchPolicy: \"no-cache\",\n });\n const bundleEntity = response.data?.bundleDuplicate;\n if (!bundleEntity?.id) {\n throw new Error(`Unable to duplicate bundle`);\n }\n\n const bundlePartnerMap = persistenceService.getMap(\"bundlePartnerIds\") || new Map();\n bundlePartnerMap.set(bundleEntity.id!, bundleEntity.partner!.id);\n persistenceService.setMap(\"bundlePartnerIds\", bundlePartnerMap);\n\n // Store the bundle owner id in local storage.\n const bundleOwnerMap = persistenceService.getMap(\"bundleOwnerIds\") || new Map();\n bundleOwnerMap.set(bundleEntity.id!, bundleEntity.bundleOwnerId!);\n persistenceService.setMap(\"bundleOwnerIds\", bundleOwnerMap);\n\n // Return a function that can create a new bundle instance for this bundle entity.\n return async () => {\n const newBundle = await this.getExistingBundle(bundleEntity.id!, undefined, undefined, {\n graphql: {\n productCollection: {\n eagerFetchProducts: options?.graphql?.productCollection?.eagerFetchProducts || false,\n },\n },\n });\n return newBundle;\n };\n }\n\n /**\n * Fetches information about the currently authenticated customer's bundles.\n * NOTE: This does not initialize a bundle for active use.\n * You must call either `getExistingBundle` or `duplicateBundle` to actually interact with a bundle.\n * @param options Options to configure the request.\n * @returns A promise that resolves with an object containing:\n * `items` - The bundles that matched the request.\n * `total` - The total number of bundles on the server that match this query.\n */\n async getBundlesForCustomer(options: {\n /** Whether to include each bundle's metadata in the response. */\n includeMetadata?: boolean;\n /** The maximum amount of bundles to return in the response. */\n limit: number;\n /** The amount of items to skip over in the server query. */\n offset: number;\n /** Undefined: Any bundle, template or not. True: The bundle must be a template. False: The bundle must not be a template */\n template?: boolean;\n /** Undefined: Any bundle, ordered or not. True. Just the ordered ones. False: Just the unordered ones. */\n ordered?: boolean;\n /** The status of the bundle template; \"Active\" or \"Draft\". */\n templateStatus?: BundleTemplateStatus;\n }): Promise<BundlesFeed> {\n if (!this.customer?.id) {\n throw new Error(\"Customer not authenticated.\");\n }\n const { includeMetadata, ...variables } = options;\n const result = await graphQlManager.getShadowGraphqlClient().query<{ customerBundlesFeed: BundlesFeed }>({\n query: customerBundlesFeedQuery(includeMetadata ?? false),\n variables: {\n ...variables,\n id: this.customer.id!,\n },\n fetchPolicy: \"no-cache\",\n });\n return result.data.customerBundlesFeed;\n }\n\n /**\n * Retrieves all existing bundle stakeholders from the API, for the currently authenticated customer.\n * @returns An array of bundle stakeholders.\n */\n async getBundleStakeholders(): Promise<BundleStakeholder[]> {\n if (!this.customer) {\n throw new Error(\"Customer not authenticated.\");\n }\n const response = await graphQlManager.getShadowGraphqlClient().query<{ customers: Customer[] }>({\n query: getBundlesAndStakeholdersForCustomerQuery,\n variables: {\n id: this.customer.id,\n },\n fetchPolicy: \"no-cache\",\n });\n if (!response.data?.customers || response.data.customers.length === 0) {\n throw new Error(\"Unable to find customer.\");\n }\n const customer = response.data.customers[0];\n const stakeholders = customer.bundleStakeholders || [];\n const bundlePartnerMap = persistenceService.getMap(\"bundlePartnerIds\") || new Map();\n stakeholders.forEach((stakeholder) => {\n if (stakeholder.bundle?.id && stakeholder.bundle.partner?.id) {\n bundlePartnerMap.set(stakeholder.bundle.id, stakeholder.bundle.partner.id);\n }\n });\n persistenceService.setMap(\"bundlePartnerIds\", bundlePartnerMap);\n return stakeholders;\n }\n\n /**\n * Creates a new instance of WorkflowExperience. A high level wrapper for workflows.\n * @param options Options to configure loading the transaction and workflow.\n * @param previewServiceConstructor A function called during initialization. Takes a class implementing ThreeDPreviewService in return.\n * @returns A workflow experience configured as requested.\n */\n async getWorkflowExperience(\n options: GetWorkflowOptions,\n previewServiceConstructor?: (workflow: Workflow) => ThreeDPreviewService,\n ): Promise<WorkflowExperience> {\n if (!options)\n throw new Error(\"getWorkflowExperience has been called without an options object! This is not supported.\");\n\n // We request the construction of a new workflow experience.\n const result = await this.getWorkflowExperiences([options], options.graphql);\n const exp = result[0];\n\n // Handle the preview service injection if requested.\n const instantiatedWorkflow = exp.getWorkflow();\n if (previewServiceConstructor && !instantiatedWorkflow) {\n console.error(\"No workflow instantiated when trying to create preview service.\");\n }\n if (previewServiceConstructor && instantiatedWorkflow) {\n await exp.getWorkflowManager().injectIntoPreviewService(previewServiceConstructor(instantiatedWorkflow));\n }\n\n return result[0];\n }\n\n /**\n * Gets multiple workflow experiences at once.\n * @param optionsArray An array of options to configure loading the transactions and workflows.\n * NOTE: The `previewService` field on the option is currently unsupported in this function, as loading multiple models at once will likely cause performance issues.\n * @param graphqlOptions Options to configure loading the workflows.\n * @returns An array of workflow experiences configured as requested.\n */\n async getWorkflowExperiences(\n optionsArray: GetWorkflowOptions[],\n graphqlOptions?: GetWorkflowGraphqlOptions,\n transactionInitializedCallback?: () => void,\n transactionLoadProgressCallback?: (loaded: number, total: number) => void,\n ): Promise<WorkflowExperience[]> {\n if (optionsArray.length === 0) {\n throw new ClientError(\"No options provided!\");\n }\n const indexedOptions = optionsArray.map((x, i) => ({ option: x, index: i }));\n const transactionOptions = indexedOptions.filter((x) => x.option.type === \"transaction\") as {\n option: GetWorkflowFromTransactionOptions;\n index: number;\n }[];\n const createOptions = indexedOptions.filter(\n (x) => x.option.type === \"integration\" || x.option.type === \"external\" || x.option.type === \"blank\",\n ) as {\n option: GetNewWorkflowExperienceOptions;\n index: number;\n }[];\n\n // Split into batches\n const batchSize = 50;\n const batchedReadTransactions = chunk(transactionOptions, batchSize);\n const batchedCreateOptions = chunk(createOptions, batchSize);\n let amtLoaded = 0;\n\n const graphQlClient = graphQlManager.getShadowGraphqlClient();\n const readTransactions = async (\n batch: {\n option: GetWorkflowFromTransactionOptions;\n index: number;\n }[],\n ) => {\n if (batch.length === 0) {\n return [];\n }\n const transactionIds = batch.map((x) => x.option.transactionId);\n const response = await graphQlClient.query<{ transactions: Transaction[] }>({\n query: readTransactionsQuery,\n variables: {\n ids: transactionIds,\n },\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n });\n const transactions = response.data.transactions;\n amtLoaded = amtLoaded + transactions.length;\n if (transactionLoadProgressCallback) {\n transactionLoadProgressCallback(amtLoaded, transactionOptions.length);\n }\n if (transactions.length !== batch.length) {\n const reason = response.errors?.[0]?.message || \"Unknown error\";\n throw new ClientError(`Not all transactions were found: ${reason}`);\n }\n if (!this.activeIntegration && transactions[0].integrationProduct?.integration) {\n // TODO: Move this to a separate request. We don't want or need to fetch all integration details on every single transaction.\n this.activeIntegration = Promise.resolve(transactions[0].integrationProduct.integration);\n }\n return transactions.map((transaction, idx) => ({\n transaction,\n workflowId: transaction.workflowId!,\n readOnly: batch.find((x) => x.option.transactionId === transaction.id)?.option.readOnly ?? false,\n index: batch[idx].index,\n }));\n };\n const createTransactions = async (\n batch: {\n option: GetNewWorkflowExperienceOptions;\n index: number;\n }[],\n ) => {\n if (batch.length === 0) {\n return [];\n }\n\n const response = await graphQlClient.mutate<{ transactionCreateMany: Transaction[] }>({\n mutation: createManyTransactionsMutation,\n variables: {\n inputs: batch.map((x) => ({\n integrationProductId:\n x.option.type === \"integration\" ? x.option.integrationProductId : undefined,\n externalIntegrationId:\n x.option.type === \"external\" ? x.option.externalIntegrationId : undefined,\n externalProductId: x.option.type === \"external\" ? x.option.externalProductId : undefined,\n workflowId: x.option.workflowId,\n designName: x.option.designName,\n claim: true,\n quantity: x.option.quantity,\n recipient: x.option.recipient,\n })),\n marketplaceThemeInstallId: this.marketplaceThemeInstallId,\n marketplaceThemeInstallConfigurationId: this.marketplaceThemeInstallConfigurationId,\n },\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n });\n const transactions = response.data?.transactionCreateMany;\n if (!transactions || transactions.length === 0) {\n const reason = response.errors?.[0]?.message || \"Unknown error\";\n throw new ClientError(`Failed to create transactions: ${reason}`);\n }\n amtLoaded = amtLoaded + transactions.length;\n if (transactionLoadProgressCallback) {\n transactionLoadProgressCallback(amtLoaded, transactionOptions.length);\n }\n return transactions.map((transaction, idx) => ({\n transaction,\n workflowId: transaction.workflowId,\n readOnly: false,\n index: batch[idx].index,\n }));\n };\n\n // Fetch all transactions\n const transactionResults = (\n await Promise.all([\n ...batchedReadTransactions.map(readTransactions),\n ...batchedCreateOptions.map(createTransactions),\n ])\n ).flat();\n\n const integrationProductIds = [\n ...new Set(transactionResults.map((x) => x.transaction.integrationProductId)),\n ].filter((x) => x !== undefined) as string[];\n\n const workflowIds = [...new Set(transactionResults.map((x) => x.workflowId))].filter(\n (x) => x !== undefined,\n ) as string[];\n\n const [integrationProducts, workflows] = await Promise.all([\n (async () =>\n integrationProductIds.length > 0 ? await getIntegrationProducts(integrationProductIds) : [])(),\n (async () => (workflowIds.length > 0 ? await getWorkflows(workflowIds, graphqlOptions) : []))(),\n ]);\n const integrationProductMap = new Map(integrationProducts.map((x) => [x.id, x]));\n const workflowMap = new Map(workflows.map((x) => [x.id, x]));\n\n const experienceOptionsPromises = transactionResults.map(async (transactionResult) => {\n const { transaction, workflowId, readOnly, index } = transactionResult;\n const workflow = workflowId ? workflowMap.get(workflowId) : undefined;\n const options = optionsArray[index];\n\n if (transaction.integrationProductId) {\n const p = integrationProductMap.get(transaction.integrationProductId);\n transaction.integrationProduct = p;\n transaction.product = p?.product;\n if (!transaction.integrationProduct) {\n console.error(\"failed to find transaction's product\");\n }\n }\n\n // Persist the owner ID for use when updating (only when creating a new transaction)\n // Note: if anything is awaited you *must* refetch this object, since other promises may update it.\n const ownerMap = persistenceService.getMap(\"transactionOwnerIds\") || new Map();\n if (!ownerMap.get(transaction.id) && transaction.transactionOwnerId) {\n ownerMap.set(transaction.id, transaction.transactionOwnerId);\n persistenceService.setMap(\"transactionOwnerIds\", ownerMap);\n }\n const transactionOwnerId = ownerMap.get(transaction.id) || undefined;\n const graphQlClientWrapper = new GraphQlClientWrapper({\n onMutate: () => {\n return { context: { transactionOwnerId, bundleOwnerId: graphqlOptions?.bundleOwnerId } };\n },\n onQuery: () => {\n return { context: { transactionOwnerId, bundleOwnerId: graphqlOptions?.bundleOwnerId } };\n },\n });\n const workflowExperienceOptions: ExperienceOptions = {\n workflow,\n transaction,\n singleVariantsRenderable: options?.workflowConfiguration?.singleVariantsRenderable,\n stateMutationFunc: !readOnly\n ? async (options) => {\n return this.updateTransactionState({\n ...options,\n context: { transactionOwnerId, bundleOwnerId: graphqlOptions?.bundleOwnerId },\n });\n }\n : async () => {\n throw new UnhandledBehaviorError(\"State mutation is forbidden in read only mode!\");\n },\n graphQlClient: () => {\n return graphQlClientWrapper;\n },\n readOnly,\n isReloadedTransaction: options.type === \"transaction\",\n };\n\n // We either reload initial state or we create a new one.\n if (options.type === \"transaction\" && transaction.workflowState) {\n // Reloading an existing transaction.\n const reloadedState: LayoutsState = JSON.parse(transaction.workflowState);\n await rehydrateSerializedLayout(reloadedState);\n workflowExperienceOptions.reloadedState = reloadedState;\n } else if (!readOnly && options.workflowState) {\n // Manual workflow state passed in\n const reloadedState: LayoutsState = JSON.parse(options.workflowState);\n await rehydrateSerializedLayout(reloadedState);\n workflowExperienceOptions.reloadedState = reloadedState;\n }\n\n workflowExperienceOptions.delayWorkflowStateSync = true;\n\n return { experienceOptions: workflowExperienceOptions, index, options };\n });\n\n const experienceOptions = await Promise.all(experienceOptionsPromises);\n const sortedExperienceOptions = experienceOptions.sort((a, b) => a.index - b.index);\n\n // Simultaneously trigger N transaction update graphql calls, one for each workflow manager's initialization promise.\n let experiences: WorkflowExperienceImpl[] = [];\n for (const x of sortedExperienceOptions) {\n const { experienceOptions, options } = x;\n const we = new WorkflowExperienceImpl(this, experienceOptions);\n await we.getWorkflowManager().getInitializationPromise();\n if (transactionInitializedCallback) {\n transactionInitializedCallback();\n }\n if (options.type !== \"transaction\" && this.customer) {\n await we.attachCustomerDetails({ email: this.customer.emailAddress });\n }\n experiences = [...experiences, we];\n we.getWorkflowManager().setWorkflowStateSyncEnabled(true);\n }\n\n return experiences;\n }\n\n /**\n * A function used to synchronize transaction state with the server.\n * @param options New state details. To be spread into the query.\n * @returns\n */\n private updateTransactionState: StateMutationFunc = async (options) => {\n try {\n return graphQlManager.getShadowGraphqlClient().mutate({\n ...options,\n mutation: updateTransactionWorkflowStateQuery,\n });\n } catch (error) {\n console.error(error);\n throw new ClientError(\"Critical - Unable to synchronize workflow state with server.\");\n }\n };\n\n storeCustomer(customer: Customer) {\n const partnerCustomerMap = persistenceService.getMap(\"partnerCustomerIds\") || new Map();\n partnerCustomerMap.set(customer.partner!.id, customer.id);\n persistenceService.setMap(\"partnerCustomerIds\", partnerCustomerMap);\n }\n\n async getIntegrationProductById(\n integrationProductId: string,\n fetchIntegrationsOnProduct?: boolean,\n ): Promise<IntegrationProduct> {\n const graphQlClient = graphQlManager.getShadowGraphqlClient();\n const response = await graphQlClient.query<{ integrationProducts: IntegrationProductResource[] }>({\n query: getIntegrationProductsQuery(fetchIntegrationsOnProduct),\n variables: {\n ids: [integrationProductId!],\n },\n fetchPolicy: \"no-cache\",\n errorPolicy: \"all\",\n });\n const integrationProducts = response.data?.integrationProducts;\n if (!integrationProducts || integrationProducts.length === 0 || !integrationProducts[0]?.id) {\n throw new Error(\"Integration product not found.\");\n }\n return new IntegrationProduct(integrationProducts[0]);\n }\n\n async getIntegrationProductFromExternalIds(\n externalIntegrationId: string,\n externalProductId: string,\n fetchIntegrationsOnProduct?: boolean,\n ): Promise<IntegrationProduct> {\n const graphQlClient = graphQlManager.getShadowGraphqlClient();\n const response = await graphQlClient.query<{ integrationProductFromExternalIds: IntegrationProductResource }>({\n query: getIntegrationProductFromExternalIdsQuery(fetchIntegrationsOnProduct),\n variables: {\n externalProductId: externalProductId!,\n externalIntegrationId: externalIntegrationId!,\n },\n fetchPolicy: \"no-cache\",\n errorPolicy: \"all\",\n });\n const integrationProduct = response.data?.integrationProductFromExternalIds;\n if (!integrationProduct?.id) {\n throw new Error(\"Integration product not found.\");\n }\n return new IntegrationProduct(integrationProduct);\n }\n\n async getIntegrationProduct(\n options:\n | Extendable<{\n type: \"integration\";\n integrationProductId: string;\n }>\n | Extendable<{\n type: \"external\";\n externalIntegrationId: string;\n externalProductId: string;\n }>,\n ): Promise<IntegrationProduct> {\n if (options.type === \"integration\") {\n return this.getIntegrationProductById(options.integrationProductId);\n }\n return this.getIntegrationProductFromExternalIds(options.externalIntegrationId, options.externalProductId);\n }\n\n async getShareActionsForTransaction(transactionId: string): Promise<ShareAction[] | undefined> {\n const ownerMap = persistenceService.getMap(\"transactionOwnerIds\") || new Map();\n const transactionOwnerId = ownerMap.get(transactionId) || undefined;\n const response = await graphQlManager.getShadowGraphqlClient().query<{ transactions: Transaction[] }>({\n query: getTransactionShareActionsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: transactionId,\n },\n context: {\n transactionOwnerId,\n },\n });\n if (!response.data.transactions || response.data.transactions.length !== 1) {\n throw new Error(`Failed to fetch share actions for transaction: ${transactionId}`);\n }\n return response.data.transactions[0].transactionShareActions;\n }\n\n async placeOrder(orderItems: OrderItem[]): Promise<Order> {\n const orderCreateResponse = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ orderCreate: { id: string; internalId: string } }>({\n mutation: createOrderMutation,\n variables: {\n orderItems,\n },\n });\n if (orderCreateResponse.errors) {\n throw new Error(orderCreateResponse.errors[0].message);\n }\n if (!orderCreateResponse.data) {\n throw new Error(\"Failed to create order: No order data in response.\");\n }\n return {\n id: orderCreateResponse.data.orderCreate.id,\n internalId: orderCreateResponse.data.orderCreate.internalId,\n };\n }\n}\n\nexport const getIntegration = async (applicationKey: string, themeConfigurationId?: string): Promise<Integration> => {\n const graphqlClient = graphQlManager.getShadowGraphqlClient();\n const integrationResponse = await graphqlClient.query<{ currentIntegration: Integration }>({\n query: currentIntegrationQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n context: {\n headers: {\n \"x-application-key\": applicationKey,\n },\n skipIntegrationCheck: true,\n },\n variables: {\n themeConfigurationId,\n },\n });\n return integrationResponse.data.currentIntegration;\n};\n\nexport const getTransaction = async (transactionId: string): Promise<Transaction | undefined> => {\n const graphqlClient = graphQlManager.getShadowGraphqlClient();\n const result = await graphqlClient.query<{ transactions: Transaction[] }>({\n query: getTransactionQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"network-only\",\n variables: {\n id: transactionId,\n },\n });\n if (result.data.transactions.length === 0) return undefined;\n return result.data.transactions[0];\n};\n\nexport const getOverrideThemeConfiguration = async (\n overrideThemeConfigurationId: string,\n overrideThemeInstallId: string,\n): Promise<ThemeInstallConfigurationGraphQl | undefined> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n marketplaceThemeInstallConfiguration: ThemeInstallConfigurationGraphQl;\n }>({\n query: getMarketplaceThemeInstallConfigurationQuery,\n errorPolicy: \"all\",\n variables: {\n themeConfigurationId: overrideThemeConfigurationId,\n themeInstallId: overrideThemeInstallId,\n },\n });\n return response.data?.marketplaceThemeInstallConfiguration;\n};\n\nexport const getBundleThemeConfiguration = async (\n bundleId: string,\n): Promise<ThemeInstallConfigurationGraphQl | undefined> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n bundles: { marketplaceThemeInstallConfiguration?: ThemeInstallConfigurationGraphQl }[];\n }>({\n query: getBundleForMarketplaceThemeQuery,\n errorPolicy: \"all\",\n variables: {\n id: bundleId,\n },\n });\n return response.data?.bundles?.[0]?.marketplaceThemeInstallConfiguration;\n};\n\nexport const getTransactionThemeConfiguration = async (\n transactionId: string,\n): Promise<ThemeInstallConfigurationGraphQl | undefined> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n transactions: Transaction[];\n }>({\n query: getTransactionForMarketplaceThemeQuery,\n errorPolicy: \"all\",\n variables: {\n id: transactionId,\n },\n });\n return response.data?.transactions?.[0]?.marketplaceThemeInstallConfiguration;\n};\n\nasync function getAuthHeaders(): Promise<{ [key: string]: string }> {\n const extraHeaders: { [key: string]: string } = {};\n try {\n const token = await this.loggedInBearerToken();\n extraHeaders[\"Authorization\"] = `Bearer ${token}`;\n } catch (e) {\n // Hack to get the token from editor's amplify.\n const keys = Object.entries(localStorage);\n const jwtTokenKey =\n keys.find(([k, _]) => {\n return k.startsWith(\"CognitoIdentityServiceProvider\") && k.endsWith(\"idToken\");\n })?.[0] || \"\";\n const jwtToken = localStorage.getItem(jwtTokenKey);\n if (jwtToken && !isTokenExpired(jwtToken)) {\n extraHeaders[\"Authorization\"] = `Bearer ${jwtToken}`;\n }\n }\n return extraHeaders;\n}\n\nasync function getContextHeadersForBundle(id: string): Promise<any> {\n const ownerMap = persistenceService.getMap(\"bundleOwnerIds\");\n const bundleOwnerId = ownerMap?.get(id);\n // TODO: Update customer auth to store bundle stakeholders as well.\n const extraHeaders = await getAuthHeaders();\n return {\n bundleOwnerId,\n ...extraHeaders,\n };\n}\n\nasync function getContextHeadersForTransaction(id: string): Promise<any> {\n const ownerMap = persistenceService.getMap(\"transactionOwnerIds\");\n const transactionOwnerId = ownerMap?.get(id);\n const extraHeaders = await getAuthHeaders();\n return {\n transactionOwnerId,\n ...extraHeaders,\n };\n}\n\n/**\n * Marks the Bundle with the provided id as deleted. The Bundle's data will still persist on the server and as such you can still retrieve it directly via id,\n * but it will no longer be visible in list/feed queries and it can no longer be converted into an Order.\n */\nexport const deleteBundle = async (id: string): Promise<void> => {\n const bundleContextHeaders = await getContextHeadersForBundle(id);\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{ bundleDelete: string }>({\n mutation: deleteBundleQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id,\n },\n context: {\n headers: bundleContextHeaders,\n },\n });\n if (response.data?.bundleDelete !== id) {\n throw new Error(`Failed to delete bundle: ${response.errors}`);\n }\n};\n\n/**\n * Finds the bundle id for the given transaction id, or undefined if the transaction is not linked to a bundle.\n */\nexport const getBundleIdForTransaction = async (id: string): Promise<string | undefined> => {\n const transactionContextHeaders = await getContextHeadersForTransaction(id);\n const response = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ transactions?: { id: string; bundle?: { id: string } }[] }>({\n mutation: findBundleForTransactionsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n ids: [id],\n },\n context: {\n headers: transactionContextHeaders,\n },\n });\n if (\n !response.data?.transactions ||\n response.data.transactions.length !== 1 ||\n response.data.transactions[0].id !== id\n ) {\n throw new Error(`Failed to find transaction to read bundle id: ${JSON.stringify(response.errors)}`);\n }\n return response.data.transactions[0].bundle?.id;\n};\n","import { FrameStepStorage, FrameData, FrameThresholdSettings, FrameOffsets, PatternImageData } from \"../../../types\";\nimport debounce from \"lodash.debounce\";\nimport isEqual from \"lodash.isequal\";\nimport { WorkflowManager } from \"../../../WorkflowManager\";\nimport { UnhandledBehaviorError } from \"../../../util/exception\";\nimport { calculateOffsets, frameDataCache, getFrameData } from \"../../../util/frame\";\nimport { modifySVGColors } from \"../../../util/illustration\";\nimport { svgToDataUrl } from \"../../../util/crossplatform\";\nimport { GroupCommand, UpdateFramePattern, UpdateFrameThresholdSettingsCommand } from \"../../../command\";\n\n/**\n * Bounds the offsets for an image to the box, preventing\n * the user from moving the image in a way that wouldn't be intended.\n * @param newOffsets The new intended offsets for the image.\n * @param frameData The current frame information\n * @param borderWidth The width of the border added by the cropper.\n * @param mustCover When true the image sgould be bounded in such a way that it covers the entire frame at all times.\n */\nexport function getBoundedOffsets(\n newOffsets: FrameOffsets,\n frameData: FrameData,\n imageData: PatternImageData,\n mustCover?: boolean,\n) {\n const newWidth = imageData.width * newOffsets.zoom;\n const newHeight = imageData.height * newOffsets.zoom;\n\n if (mustCover) {\n // Find which is smaller: framewidth / imagewidth or frameheight / imageheight\n // Then calculate the min zoom factor based on the smaller\n // of the zoom to atleast fit the image and the users new zoom level.\n const covering = newOffsets;\n const zoomMinimumBound = Math.max(frameData.width / imageData.width, frameData.height / imageData.height);\n covering.zoom = Math.max(zoomMinimumBound, newOffsets.zoom);\n const boundedWidth = imageData.width * covering.zoom;\n const boundedHeight = imageData.height * covering.zoom;\n covering.x = boundToRange(newOffsets.x, frameData.width - boundedWidth, 0);\n covering.y = boundToRange(newOffsets.y, frameData.height - boundedHeight, 0);\n return covering;\n }\n\n // If we don't need to cover we just make sure the users can't drag the image completely off\n // screen which may cause trouble when trying to find the image again.\n const bounded = newOffsets;\n bounded.x = boundToRange(bounded.x, -newWidth, frameData.width);\n bounded.y = boundToRange(bounded.y, -newHeight, frameData.height);\n\n return bounded;\n}\n\n/**\n * Bounds a value to a given range\n * @param value The value to bound\n * @param min The minimum bound that value must be above.\n * @param max The maximum bound the value must be below.\n */\nfunction boundToRange(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport type UpdateFrameOffsets = (\n newOffsets: FrameOffsets[],\n imageData: PatternImageData,\n frameData: FrameData[],\n thresholdSettings: FrameThresholdSettings,\n onComplete?: () => void,\n) => void;\n\nexport class FrameService {\n // Internal state\n private offsets: FrameOffsets[];\n private thresholdSettings: FrameThresholdSettings;\n private forceImageCover?: boolean;\n private initialZoom?: number;\n private targetElements: string[]; // A list of canvas element ids that should be updated when changes occur to this frame.\n\n // FIXME: Can we pull these from the element itself?\n private imageData?: PatternImageData; // The current pattern if any.\n // FIXME: Can we pull these from the element itself?\n private frameData?: FrameData[]; // The current frame if any.\n\n // Debounced functions\n\n private readonly _debouncedUpdateFrameOffsets: UpdateFrameOffsets;\n\n // constants\n\n /**\n * The calculated minimum zoom value, per frame.\n */\n public minZoomScale = [0.03];\n /**\n * The calculated maximum zoom value. Note: This is calculated based on the first frame.\n */\n public maxZoomScale = [20];\n\n // Listeners\n\n private onFrameDataChangeListeners: ((frameData: FrameData[] | undefined) => void)[];\n private onZoomChangeListeners: ((zoomValue: number[]) => void)[];\n\n // Workflow manager related logic\n private workflowManager?: WorkflowManager;\n private stepName?: string;\n\n constructor(forceImageCover?: boolean, initialZoom?: number) {\n this._debouncedUpdateFrameOffsets = debounce(this.updateFrameOffsets, 200);\n this.targetElements = [];\n this.onFrameDataChangeListeners = [];\n this.onZoomChangeListeners = [];\n this.forceImageCover = forceImageCover;\n this.initialZoom = initialZoom;\n this.thresholdSettings = {\n useThreshold: false,\n invertThreshold: false,\n threshold: 128,\n thresholdSaturation: 0.5,\n };\n }\n\n /**\n * When we want to connect a workflow manager to the state of the image cropper we\n * can pass it to this function. Inside we'll attach any required event listeners.\n * @param workflowManager The workflow manager to attach.\n * @param stepName The specific step we want to attach to within the manager.\n */\n connectWorkflowManager(workflowManager: WorkflowManager, stepName?: string) {\n if (stepName) {\n workflowManager.addStepSpecificStorageCallback(async (storage) => {\n if (storage) {\n const frameStorage = storage as FrameStepStorage;\n if (frameStorage.currentFrameSources) {\n let changed = false;\n for (let i = 0; i < frameStorage.currentFrameSources.length; i++) {\n const frameSource = frameStorage.currentFrameSources[i];\n const newFrameData = await getFrameData(frameSource);\n const existingFrameData = this.frameData ? this.frameData[i] : undefined;\n if (!isEqual(newFrameData, existingFrameData)) {\n if (!this.frameData) {\n this.frameData = new Array(frameStorage.currentFrameSources.length);\n }\n this.frameData[i] = newFrameData;\n changed = true;\n }\n }\n if (changed) {\n this.onFrameDataChangeListeners.forEach((frameDataChangeListener) =>\n frameDataChangeListener(this.frameData),\n );\n if (this.frameData && this.imageData) {\n this.recalculateOffsets(this.imageData);\n this.updateOffsets(this.offsets);\n this.recalculateZoomLimits(this.imageData, this.frameData);\n }\n }\n }\n }\n }, stepName);\n }\n\n this.workflowManager = workflowManager;\n this.stepName = stepName;\n }\n\n /**\n * Sets the elements that should be update when changes are made to\n * the cropper that owns this service.\n * @param targetElements A list of element Ids to track\n */\n setTargetElements(targetElements: string[]) {\n this.targetElements = targetElements;\n }\n\n /**\n * Gets the current calculated frame data\n * @returns A FrameData object or undefined if no frame has been set.\n */\n getFrameData(): FrameData[] | undefined {\n return this.frameData;\n }\n\n /**\n * Sets the current frame data. Note:\n * @param paths The paths to lookup in our frame data cache.\n */\n setFrameData(paths: string[] | undefined) {\n if (!paths) {\n this.frameData = undefined;\n return;\n }\n paths.forEach((path, index) => {\n const frameData = frameDataCache.get(path);\n if (frameData) {\n if (!this.frameData) {\n this.frameData = new Array(paths.length);\n }\n this.frameData[index] = frameData;\n }\n });\n }\n\n /**\n * Gets the currently set image of the frame..\n * @returns A PatternImageData object, or undefined if no image is set.\n */\n getImageData(): PatternImageData | undefined {\n return this.imageData;\n }\n\n /**\n * Helper function to get the src of the image of the frame, since it can be an svg with modified colors.\n * @returns A url (a data url if svg), or undefined if no image is set.\n */\n getImageSrc(): string | undefined {\n if (!this.imageData) {\n return undefined;\n }\n if (this.imageData.svg) {\n const modifiedSvg = modifySVGColors(this.imageData.svg, this.imageData.colors || {}, false);\n return svgToDataUrl(modifiedSvg);\n }\n return this.imageData.src;\n }\n\n /**\n * Gets the current calculated offsets of the pattern within the frame.\n * @returns A FrameOffsets object or undefined if no offsets are defined.\n */\n getOffsets(): FrameOffsets[] | undefined {\n return this.offsets;\n }\n\n /**\n * Updates the frame offsets explicitly.\n */\n setOffsets(offsets: FrameOffsets[]) {\n this.offsets = offsets;\n }\n\n /**\n * Sets the zoom of the cropper that owns this service.\n * @param zoom The new zoom value, per frame.\n * @param cX The center of zoom on x axis, per frame.\n * @param cY The center of zoom on Y axis, per frame.\n * @param onComplete A function to call when zoom changes have been completed\n */\n setZoom(zoom: number[], cX: number[], cY: number[], onComplete?: () => void) {\n if (this.imageData && this.offsets && this.frameData) {\n if (!this.offsets || this.offsets.length !== this.frameData.length) {\n this.offsets = new Array(this.frameData.length);\n }\n const calculatedOffsets = this.frameData.map((frameData, index) => {\n // Figure out the top/left displacement caused by the zoom.\n const xoff = (cX[index] - this.offsets[index].x) / this.offsets[index].zoom;\n const yoff = (cY[index] - this.offsets[index].y) / this.offsets[index].zoom;\n const dX = cX[index] - xoff * zoom[index];\n const dY = cY[index] - yoff * zoom[index];\n const calculatedOffsets = {\n x: dX,\n y: dY,\n zoom: (this.imageData!.width * zoom[index]) / this.imageData!.width,\n };\n return calculatedOffsets;\n });\n // Applying the new offsets will cause the image to be bounded.\n this.updateOffsets(calculatedOffsets, onComplete);\n this.onZoomChangeListeners.forEach((zoomChangeListener) => zoomChangeListener(zoom));\n }\n }\n\n /**\n * Sets the image currently contained by this frame.\n * @param value The new image as an ImageData property\n * @param [recalculateOffsets=true] Optional: Enable/disable re-calculating of frame offsets. Default: `true`.\n * Note: Will always calculate when offsets have not been calculated.\n */\n setPatternData(value: PatternImageData, recalculateOffsets = true) {\n this.imageData = value;\n if (value && this.frameData) {\n if (recalculateOffsets || !this.offsets) {\n this.recalculateOffsets(value);\n }\n // Applying the new offsets will cause the image to be bounded.\n this.updateOffsets(this.offsets, undefined, true);\n }\n if (this.imageData && this.frameData) {\n this.recalculateZoomLimits(this.imageData, this.frameData);\n }\n }\n\n /**\n * Modify the offsets of the frame.\n * @param value The new FrameOffsets objects.\n * @param onComplete A callback, called when the modification is complete\n * @param forceUpdate When true the offsets will be updated even if they haven't changed.\n */\n updateOffsets(value: FrameOffsets[], onComplete?: () => void, forceUpdate?: boolean) {\n const patternData = this.imageData;\n // If the frame isn't correctly initialized yet just ignore..\n if (!patternData || !this.frameData) {\n return;\n }\n\n if (this.frameData.length !== value.length) {\n throw new UnhandledBehaviorError(\n \"Frame data and offsets are not the same length. This is a bug. Please report it.\",\n );\n }\n\n const changed = this.offsets.some((offset, index) => {\n // If there hasn't been any change let's not set or update\n // the offsets internally. Doing so will trigger re-rendering for no good reason.\n if (value[index].x === offset.x && value[index].y === offset.y && value[index].zoom === offset.zoom) {\n return false;\n }\n return true;\n });\n if (!changed && !forceUpdate) {\n onComplete && onComplete();\n return;\n }\n\n if (!this.offsets || this.offsets.length !== this.frameData.length) {\n this.offsets = new Array(this.frameData.length);\n }\n this.frameData.forEach((frameData, index) => {\n this.offsets[index] = getBoundedOffsets(value[index], frameData, this.imageData!, this.forceImageCover);\n });\n\n // Update anyone who wants to know about changes to the frame.\n this._debouncedUpdateFrameOffsets(\n this.offsets,\n patternData,\n this.frameData,\n this.thresholdSettings,\n onComplete,\n );\n }\n\n getThresholdSettings(): FrameThresholdSettings {\n return this.thresholdSettings;\n }\n\n setThresholdSettings(settings: FrameThresholdSettings) {\n this.thresholdSettings = settings;\n if (this.imageData && this.frameData) {\n this._debouncedUpdateFrameOffsets(this.offsets, this.imageData, this.frameData, settings);\n }\n }\n\n // Allows users of the frame service to listen to frame data changes.\n onFrameDataChanged(newListener: (frameData: FrameData[] | undefined) => void) {\n newListener(this.frameData);\n this.onFrameDataChangeListeners.push(newListener);\n }\n\n /**\n * Append a new listener to zoom events on this frame.\n * @param newListener\n */\n onZoom(newListener: (zoomValue: number[]) => void) {\n this.onZoomChangeListeners.push(newListener);\n }\n\n /**\n * Updates the offsets of the frame\n * @param newOffsets New offset object\n * @param imageData The image data\n * @param frameData The frame data\n * @param targetElements A list of elements that need updating, by ID\n * @param onComplete A callback when the operation is completed.\n */\n private updateFrameOffsets(\n newOffsets: FrameOffsets[],\n imageData: PatternImageData,\n frameData: FrameData[],\n thresholdSettings: FrameThresholdSettings,\n onComplete?: () => void,\n ) {\n if (!frameData || frameData.length === 0 || frameData.some((frame) => !frame)) {\n throw new UnhandledBehaviorError(\"Frame data not set. This is a bug\");\n }\n\n if (!this.workflowManager) throw new UnhandledBehaviorError(\"No workflow manager set, cannot update offsets.\");\n\n const regionElements = this.workflowManager.getRegionElements(this.stepName || \"\");\n const commandDispatcher = this.workflowManager.getCommandDispatcher();\n this.targetElements.forEach((elementID, index) => {\n let offsetIndex = regionElements.find((r) => r.id === elementID)?.regionIndex ?? index;\n if (offsetIndex >= newOffsets.length) {\n offsetIndex = index;\n }\n commandDispatcher(\n new GroupCommand([\n new UpdateFramePattern(elementID, imageData, newOffsets[offsetIndex]),\n new UpdateFrameThresholdSettingsCommand(\n elementID,\n thresholdSettings.useThreshold,\n thresholdSettings.invertThreshold,\n thresholdSettings.threshold,\n thresholdSettings.thresholdSaturation,\n ),\n ]),\n );\n });\n\n if (this.stepName) {\n this.workflowManager.updateStorage(this.stepName, {\n frameOffsetsList: newOffsets,\n });\n }\n\n onComplete && onComplete();\n }\n\n /**\n * Determines limitations of zoom based on relative size of image and frame.\n * @param imageData The image to include in calculations\n * @param frameData The frame to include in calculations.\n */\n private recalculateZoomLimits(imageData: PatternImageData, frameData: FrameData[]) {\n if (this.minZoomScale.length !== frameData.length || this.maxZoomScale.length !== frameData.length) {\n this.minZoomScale = new Array(frameData.length);\n this.maxZoomScale = new Array(frameData.length);\n }\n frameData.forEach((frame, index) => {\n const minimumScale = Math.max(frame.width / imageData.width, frame.height / imageData.height);\n if (this.forceImageCover) {\n this.minZoomScale[index] = minimumScale;\n this.maxZoomScale[index] = minimumScale * 2.5;\n } else {\n this.minZoomScale[index] = minimumScale / 10;\n this.maxZoomScale[index] = minimumScale * 2.5;\n }\n });\n }\n\n private recalculateOffsets(imageData: PatternImageData) {\n if (!this.frameData) return;\n if (!this.offsets || this.offsets.length !== this.frameData.length) {\n this.offsets = new Array(this.frameData.length);\n }\n this.frameData.forEach((frameData, index) => {\n this.offsets[index] = calculateOffsets(\n imageData,\n frameData,\n this.initialZoom && !this.forceImageCover ? { scale: this.initialZoom } : undefined,\n this.forceImageCover,\n );\n });\n this._debouncedUpdateFrameOffsets(this.offsets, imageData, this.frameData, this.thresholdSettings);\n }\n}\n","import {\n ConfirmCallback,\n EditedCallback,\n ElementsCallback,\n InformationResultCallback,\n InitCallback,\n MakingAdjustmentsCallback,\n MandatoryCallback,\n MetadataCallback,\n RecipientCallback,\n SelectionCallback,\n StepMetadata,\n StepSpecificStorageCallback,\n StorageCallback,\n ValidationCallback,\n WorkflowMetadata,\n} from \".\";\nimport {\n WorkflowManager,\n InformationResult,\n RegionElement,\n SpiffCommerceClient,\n WorkflowExperience,\n WorkflowScene,\n Workflow,\n} from \"..\";\nimport { CanvasCommand } from \"../command\";\nimport { CommandContext, CommandState } from \"../CommandContext\";\nimport { LayoutState, Product, SerializableStep, StepStorage, VariantResource } from \"../types\";\nimport { Poller } from \"../util/Poller\";\n\nexport class MockWorkflowManager implements WorkflowManager {\n traversableScenes(): Promise<WorkflowScene[]> {\n throw new Error(\"Method not implemented.\");\n }\n getMandatoryUnfulfilledSteps: () => string[];\n getTemplatingContext: () => Promise<{ [key: string]: any }>;\n removeRecipientCallback: (callback: RecipientCallback) => void;\n addRecipientCallback: (callback: RecipientCallback) => void;\n getStateHash: () => Promise<string>;\n updateRecipient(\n _firstName?: string,\n _lastName?: string,\n _address?: string,\n _suburb?: string,\n _state?: string,\n _email?: string,\n _postalCode?: string,\n _country?: string,\n _mobile?: string,\n _company?: string,\n _apartment?: string,\n _customField1?: string,\n _customField2?: string,\n _customField3?: string,\n _customField4?: string,\n _customField5?: string,\n _conversionConfigurationId?: string,\n ): Promise<void> {\n throw new Error(\"Method not implemented.\");\n }\n approveTransaction(_note?: string): Promise<void> {\n throw new Error(\"Method not implemented.\");\n }\n rejectTransaction(_note?: string): Promise<void> {\n throw new Error(\"Method not implemented.\");\n }\n private client: SpiffCommerceClient | undefined;\n getClient(): SpiffCommerceClient {\n return this.client ?? ({} as any);\n }\n getWorkflowExperience(): WorkflowExperience {\n return {} as any;\n }\n setClient(client: SpiffCommerceClient) {\n this.client = client;\n }\n getInitializationPromise() {\n return Promise.resolve();\n }\n setWorkflow: (workflow: Workflow) => Promise<void>;\n getProduct: () => Product;\n isInitialized(): boolean {\n return true;\n }\n getCommandContext: () => CommandContext;\n getAllLayoutData: () => LayoutState[];\n getMetadata: (stepName: string) => StepMetadata | undefined;\n getWorkflowMetadata: () => WorkflowMetadata;\n getStepStorage: (stepName: string) => StepStorage | undefined;\n getInformationResults(): InformationResult[] {\n return [];\n }\n async reset() {}\n updateStateWithServer(_getReducerState: () => CommandState) {}\n async outstandingRequestsPromise() {}\n async updateStateWithServerImmediate(_getReducerState: () => CommandState) {}\n addPoller(_poller: Poller) {}\n addConfirmCallback(_callback: ConfirmCallback) {}\n addEditedCallback(_callback: EditedCallback) {}\n addElementsCallback(_callback: ElementsCallback) {}\n addInformationResultCallback(_callback: InformationResultCallback) {}\n addInitCallback(_callback: InitCallback) {}\n addMakingAdjustmentsCallback(_callback: MakingAdjustmentsCallback) {}\n addMandatoryCallback(_callback: MandatoryCallback) {}\n addMetadataCallback(_callback: MetadataCallback) {}\n addSelectionCallback(_callback: SelectionCallback) {}\n addStepSpecificStorageCallback(_callback: StepSpecificStorageCallback, _stepName: string) {}\n addStorageCallback(_callback: StorageCallback) {}\n getCommandDispatcher() {\n return (_command: CanvasCommand) => {};\n }\n getLayouts() {\n return [];\n }\n getLayoutPreviewService() {\n return {\n getAll: () => {\n return new Map();\n },\n } as any;\n }\n getPreviewService() {\n return undefined;\n }\n setModelContainer: (container: any) => void;\n getModelContainer() {\n return undefined;\n }\n getRegionElements(_stepName: string) {\n return [];\n }\n getSerializedStep(_stepName: string, _serializedSteps: SerializableStep[]) {\n return undefined;\n }\n getStepSpecificServices(_stepName: string) {\n return undefined;\n }\n getTransaction() {\n return {\n id: \"\",\n };\n }\n getTransactionCustomer() {\n return undefined;\n }\n setTransactionCustomer() {\n return;\n }\n setTransactionCustomerDetails() {\n return;\n }\n getInitialOptionIds() {\n return new Set<string>();\n }\n getWorkflow() {\n return {\n id: \"\",\n name: \"\",\n panels: [],\n steps: [],\n showModelOnFinishStep: false,\n allowProofDownload: false,\n introduction: \"\",\n stepGroups: [],\n };\n }\n markStepsAsInitialised(_stepNames: string[]) {}\n getUpdatesPending: () => boolean;\n markUpdateCompleted(_update: string) {}\n markUpdatePending() {\n return \"123\";\n }\n getWorkflowSelections() {\n return {};\n }\n getStepSelections() {\n return {};\n }\n setCurrentAdjustingStepId(_stepId: string) {}\n setEditedStatus(_stepName: string, _status: boolean) {}\n setInformationResults(_results: InformationResult[]) {}\n setMandatoryFulfilled(_stepName: string, _status: boolean) {}\n async setSelectionsAndElements(_stepName: string, _variants: VariantResource[], _elements: RegionElement[]) {}\n toggleDesignConfirmed() {}\n updateMetadata(_stepName: string, _update: any) {}\n async updateStorage(_stepName: string, _update: StepStorage) {}\n injectIntoPreviewService(_previewService: any): Promise<void> {\n return Promise.resolve();\n }\n ejectFromPreviewService(): void {}\n setWorkflowStateSyncEnabled(_enabled: boolean) {}\n async updateTransactionShareActions() {}\n addValidationCallback(_callback: ValidationCallback) {}\n setStepError(_stepName: string, _field: string, _error: string | undefined) {}\n getStepErrors(_stepName: string) {\n return undefined;\n }\n getValidationErrors() {\n return { steps: new Map() };\n }\n async updateTransactionStakeholders() {}\n getStepTags(_stepId: string): string[] {\n return [];\n }\n}\n","import { StepHandle } from \"..\";\nimport { WorkflowManager, frameStepService, FrameService, assetService, optionService } from \"../..\";\nimport { Variant } from \"../resource/variant\";\nimport {\n AddonHandle,\n Asset,\n ColorDefinition,\n ColorOption,\n FrameData,\n FrameStepData,\n FrameStepStorage,\n PatternImageData,\n Step,\n VariantResource,\n} from \"../../types\";\nimport { generateSVGWithUnknownColors } from \"../../util/illustration\";\n\nexport enum FrameStep {\n SelectFrame = \"SelectFrame\",\n SelectImage = \"SelectImage\",\n Position = \"Position\",\n}\nexport class FrameStepHandle extends StepHandle<FrameStepData> {\n public frameService: FrameService;\n\n constructor(manager: WorkflowManager, step: Step<FrameStepData>, tags: string[]) {\n super(manager, step, tags);\n const frameStepData = (step as Step<FrameStepData>).data;\n this.frameService = new FrameService(frameStepData.forceImageCover, frameStepData.initialZoomLevel);\n this.frameService.connectWorkflowManager(manager, step.stepName);\n }\n\n selectVariant(variant: Variant) {\n const stepElements = this.manager.getRegionElements(this.step.stepName);\n return frameStepService.selectVariant(this.step, variant.getResource(), stepElements, this.manager, (v) =>\n this.setUpdateState(v),\n );\n }\n\n onFrameDataChanged(callback: (frameData: FrameData[]) => void) {\n if (!this.frameService) return;\n\n this.frameService.onFrameDataChanged((frameData) => {\n if (!frameData) return;\n callback(frameData);\n });\n }\n\n /**\n * Updates the image selection inside the frame.\n * @param asset The asset to use.\n * @param storeAsOriginal Optional: Store this asset as the original, unmodified version of the image. Default: `true`.\n * @param [recalculateOffsets=true] Optional: Recalculates the offsets of the image inside the frame. Default: `true`.\n */\n async selectImage(asset: Asset, storeAsOriginal = true, recalculateOffsets = true): Promise<void> {\n await frameStepService.selectImage(this.step, asset, this.manager, recalculateOffsets);\n if (storeAsOriginal) {\n const existingStorage = this.manager.getStepStorage(this.step.stepName)?.framePatternData || {};\n this.manager.updateStorage(this.step.stepName, {\n framePatternData: {\n ...existingStorage,\n originalAssetKey: asset.key,\n backgroundRemovedAssetKey: undefined,\n useOriginalAsset: undefined,\n },\n });\n }\n }\n\n /**\n * Returns `true` if the Background Remover is available for the current session.\n */\n async canUseBackgroundRemover(): Promise<boolean> {\n return this.manager.getClient().canUseAddon(AddonHandle.BackgroundRemover);\n }\n\n /**\n * Returns `true` if the Background Remover is available for the current session and if the associated frame has a user-supplied raster image.\n */\n async canRemoveBackground(): Promise<boolean> {\n return (\n (await this.canUseBackgroundRemover()) &&\n this.hasOriginalImageSelection() &&\n !!this.frameService?.getImageData()?.src &&\n !this.frameService?.getImageData()?.svg\n );\n }\n\n /**\n * Removes the background from an image, stores it in the state, and returns the new asset.\n * @param applyNewAsset Optionally applies the new asset as the current image selection. Default: `true`.\n * @returns A promise that resolves with the newly generated Asset.\n */\n async removeBackgroundFromImageSelection(applyNewAsset = true): Promise<Asset> {\n if (!(await this.canUseBackgroundRemover())) {\n throw new Error(\n \"The current Integration does not have access to the Background Remover. Please call canUseBackgroundRemover to ensure you disable this feature when appropriate.\",\n );\n }\n const image = await this.getOriginalImageSelection();\n if (!image) {\n throw new Error(\"You must supply an image selection before attempting to remove the background.\");\n }\n const bgRemoved = await assetService.removeBackgroundFromAsset(image);\n if (applyNewAsset) {\n await frameStepService.selectImage(this.step, bgRemoved, this.manager, false);\n }\n const existingStorage = this.manager.getStepStorage(this.step.stepName)?.framePatternData || {};\n this.manager.updateStorage(this.step.stepName, {\n framePatternData: {\n ...existingStorage,\n backgroundRemovedAssetKey: bgRemoved.key,\n useOriginalAsset: !applyNewAsset,\n },\n });\n return bgRemoved;\n }\n\n async changeColors(newFills: Map<string, ColorDefinition>) {\n await frameStepService.changeColors(this.step, this.manager, newFills);\n }\n\n getImageData(): PatternImageData | undefined {\n if (!this.frameService) return undefined;\n return this.frameService.getImageData();\n }\n\n async getColorOption() {\n return await optionService.ensureFullOption(this.step.data.colorOption);\n }\n\n getAvailableColors(): Promise<ColorOption[]> {\n if (!this.step.data.colorPickerEnabled) {\n return Promise.resolve([]);\n }\n return frameStepService.availableColors(this.step, this.manager);\n }\n\n isColorPickerEnabled() {\n return this.step.data.colorPickerEnabled ?? false;\n }\n\n async getOriginalImageColors(): Promise<\n | {\n [key: string]: ColorDefinition;\n }\n | undefined\n > {\n const imageData = this.getImageData();\n if (!imageData?.svg) {\n return undefined;\n }\n const svgData = await generateSVGWithUnknownColors(imageData.svg);\n return svgData.colors;\n }\n\n getMaxAllowedColors(): number | undefined {\n return this.step.data.maxColors;\n }\n\n getUniqueColorCount(): number {\n return frameStepService.getUniqueColorCount(this.step, this.manager);\n }\n\n getCurrentFrameStep(\n frameData: FrameData,\n uploading?: any,\n imageUploadComplete?: any,\n variants?: VariantResource[],\n ): FrameStep {\n if (variants && variants.length > 1 && frameData === undefined) {\n return FrameStep.SelectFrame;\n }\n\n if (uploading || imageUploadComplete || this.getImageData()) {\n return FrameStep.Position;\n }\n return FrameStep.SelectImage;\n }\n\n getFrameService(): FrameService | undefined {\n return this.frameService;\n }\n\n hasOverlayImageKey() {\n return this.step.data.overlayImageKey;\n }\n\n hasOverlayImageUrl() {\n return (this.step.data as any).overlayImageUrl;\n }\n\n getWhitelistedExtensions() {\n return [\n ...this.step.data.whitelistedExtensions,\n ...(this.step.data.whitelistedExtensions.includes(\".jpg\") ? [\".jpeg\"] : []),\n ];\n }\n\n async getOriginalImageSelection(): Promise<Asset | undefined> {\n const key = this.manager.getStepStorage(this.step.stepName)?.framePatternData?.originalAssetKey;\n if (!key) {\n return undefined;\n }\n return assetService.getLocalOrFromServer(key);\n }\n\n async getBackgroundRemovedImageSelection(): Promise<Asset | undefined> {\n const key = this.manager.getStepStorage(this.step.stepName)?.framePatternData?.backgroundRemovedAssetKey;\n if (!key) {\n return undefined;\n }\n return assetService.getLocalOrFromServer(key);\n }\n\n hasOriginalImageSelection(): boolean {\n return !!this.manager.getStepStorage(this.step.stepName)?.framePatternData?.originalAssetKey;\n }\n\n hasBackgroundRemovedImageSelection(): boolean {\n return !!this.getFrameStepStorage()?.framePatternData?.backgroundRemovedAssetKey;\n }\n\n getUseOriginalImageSelection(): boolean {\n return this.getFrameStepStorage()?.framePatternData?.useOriginalAsset ?? false;\n }\n\n async setUseOriginalImageSelection(value: boolean): Promise<void> {\n const existingStorage = this.getFrameStepStorage()?.framePatternData || {};\n if (existingStorage.useOriginalAsset === value) {\n return;\n }\n const originalImage = await this.getOriginalImageSelection();\n if (!originalImage) {\n throw new Error(\"You must provide an image selection before calling setUseOriginalImageSelection\");\n }\n if (!value) {\n const bgRemoved = await this.getBackgroundRemovedImageSelection();\n if (!bgRemoved) {\n throw new Error(\n \"You must call removeBackgroundFromImageSelection before attempting to apply the image.\",\n );\n }\n await this.selectImage(bgRemoved, false, false);\n } else {\n await this.selectImage(originalImage, false, false);\n }\n this.manager.updateStorage(this.step.stepName, {\n framePatternData: { ...existingStorage, useOriginalAsset: value },\n });\n }\n\n private getFrameStepStorage() {\n return this.manager.getStepStorage(this.step.stepName) as FrameStepStorage | undefined;\n }\n}\n","import { gql } from \"@apollo/client/core\";\n\nexport const getCurrentUserDetailsQuery = gql`\n query GetLoggedInCustomer($email: String!) {\n customer(emailAddress: $email) {\n id\n }\n }\n`;\n\nexport const getCustomerTransactionsQuery = gql`\n query GetCustomerTransactions(\n $id: String!\n $limit: Int!\n $offset: Int!\n $startDate: String\n $endDate: String\n $filters: TransactionFiltersInput\n $quicksearch: String\n ) {\n customerTransactionsFeed(\n id: $id\n limit: $limit\n offset: $offset\n startDate: $startDate\n endDate: $endDate\n filters: $filters\n quicksearch: $quicksearch\n ) {\n items {\n id\n createdAt\n designName\n integrationType\n status\n workflowState\n workflowViewerLink\n workflowViewerReadOnlyLink\n product {\n minimumOrderQuantity\n id\n name\n }\n }\n total\n }\n }\n`;\n\nexport const setTransactionDesignName = gql`\n mutation SetTransactionDesignName($id: String!, $name: String!) {\n transactionUpdate(id: $id, designName: $name) {\n id\n designName\n }\n }\n`;\n\nexport const duplicateTransactionMutation = gql`\n mutation DuplicateTransaction($id: String!, $template: Boolean!) {\n transactionDuplicate(id: $id, template: $template) {\n id\n workflowViewerLink\n }\n }\n`;\n\nexport const getCustomerBundlesQuery = gql`\n query GetCustomerBundles($id: String!, $limit: Int!, $offset: Int!) {\n customerBundlesFeed(id: $id, limit: $limit, offset: $offset) {\n items {\n id\n workflowViewerLink\n createdAt\n dispatchDate\n purchaseOrder\n name\n ordered\n }\n total\n }\n }\n`;\n\nexport const getTransactionsForBundleQuery = gql`\n query GetTransactionsForBundle($id: String!) {\n bundles(ids: [$id]) {\n id\n transactions {\n id\n createdAt\n designName\n integrationType\n status\n workflowState\n workflowViewerLink\n workflowViewerReadOnlyLink\n product {\n minimumOrderQuantity\n id\n name\n }\n }\n }\n }\n`;\n\nexport const setBundleName = gql`\n mutation SetBundleName($id: String!, $name: String!) {\n bundleUpdate(id: $id, name: $name) {\n id\n name\n }\n }\n`;\n\nexport const duplicateBundleMutation = gql`\n mutation DuplicateBundle($id: String!, $template: Boolean!) {\n bundleDuplicate(id: $id, template: $template) {\n id\n workflowViewerLink\n }\n }\n`;\n\nexport const getTemplateBundlesQuery = gql`\n query GetBundleTemplates($id: String!, $limit: Int!, $offset: Int!) {\n customerBundlesFeed(id: $id, limit: $limit, offset: $offset, template: true) {\n items {\n id\n workflowViewerLink\n createdAt\n name\n ordered\n }\n total\n }\n }\n`;\n","import { graphQlManager } from \"../services/server\";\nimport { Bundle, BundlesFeed, Transaction } from \"../types\";\nimport { duplicateBundleMutation, duplicateTransactionMutation, getCurrentUserDetailsQuery, getCustomerBundlesQuery, getCustomerTransactionsQuery, getTemplateBundlesQuery, getTransactionsForBundleQuery, setBundleName, setTransactionDesignName } from \"./queries\";\n\nexport const nameBundle = async (id: string, name: string, context: any) => {\n return await graphQlManager.getShadowGraphqlClient().mutate<object>({\n mutation: setBundleName,\n errorPolicy: \"all\",\n variables: {\n id,\n name,\n },\n context,\n });\n};\n\nexport const nameTransaction = async (id: string, name: string) => {\n return await graphQlManager.getShadowGraphqlClient().mutate<object>({\n mutation: setTransactionDesignName,\n errorPolicy: \"all\",\n variables: {\n id,\n name,\n },\n });\n};\n\nexport const duplicateBundle = async (id: string, template: boolean) => {\n const dupe = await graphQlManager.getShadowGraphqlClient().mutate<{ bundleDuplicate: Bundle }>({\n mutation: duplicateBundleMutation,\n errorPolicy: \"all\",\n variables: {\n id,\n template,\n },\n });\n return dupe;\n};\n\nexport const duplicateTransaction = async (id: string, template: boolean) => {\n const dupe = await graphQlManager\n .getShadowGraphqlClient()\n .mutate<{ transactionDuplicate: Transaction }>({\n mutation: duplicateTransactionMutation,\n errorPolicy: \"all\",\n variables: {\n id,\n template,\n },\n });\n return dupe;\n};\n\nexport const getCustomer = async (email: string) => {\n const queryResponse = await graphQlManager.getShadowGraphqlClient().query<{ customer: { id: string } }>({\n query: getCurrentUserDetailsQuery,\n errorPolicy: \"all\",\n variables: {\n email,\n },\n });\n return queryResponse.data.customer;\n};\n\nexport const getCustomerBundles = async (customerId: string, limit: number, offset: number) => {\n const rows = await graphQlManager.getShadowGraphqlClient().query<{\n customerBundlesFeed: BundlesFeed;\n }>({\n query: getCustomerBundlesQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: customerId,\n offset,\n limit,\n },\n });\n return rows;\n};\n\nexport const getTransactionsForBundle = async (id: string, context: any) => {\n return await graphQlManager.getShadowGraphqlClient().query<{\n bundles: { id: string; transactions: Transaction[] }[];\n }>({\n query: getTransactionsForBundleQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id,\n },\n context,\n });\n};\n\ninterface TransactionsFeed {\n items: Transaction[];\n total: number;\n}\n\nexport const getUnorderedTransactions = async (customerId: string, limit: number, offset: number) => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n customerTransactionsFeed: TransactionsFeed;\n }>({\n query: getCustomerTransactionsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: customerId,\n quicksearch: \"\",\n filters: {\n link: \"and\",\n status: {\n operator: \"isAnyOf\",\n values: [\"Created\", \"DesignCompleted\", \"ExternallyOrdered\"],\n },\n template: {\n value: \"false\",\n },\n },\n offset,\n limit,\n },\n });\n return response?.data.customerTransactionsFeed?.items || [];\n};\n\nexport const getOrderedTransactions = async (customerId: string, limit: number, offset: number) => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n customerTransactionsFeed: TransactionsFeed;\n }>({\n query: getCustomerTransactionsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: customerId,\n quicksearch: \"\",\n filters: {\n link: \"and\",\n status: {\n operator: \"equals\",\n value: \"Ordered\",\n },\n template: {\n value: \"false\",\n },\n },\n offset,\n limit,\n },\n });\n return response?.data.customerTransactionsFeed?.items || [];\n};\n\nexport const getTemplateTransactions = async (customerId: string, limit: number, offset: number) => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n customerTransactionsFeed: TransactionsFeed;\n }>({\n query: getCustomerTransactionsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: customerId,\n quicksearch: \"\",\n filters: {\n link: \"and\",\n template: {\n value: \"true\",\n },\n },\n offset,\n limit,\n },\n });\n return response?.data.customerTransactionsFeed?.items || [];\n};\n\nexport const getTemplateBundles = async (customerId: string, limit: number, offset: number) => {\n const rows = await graphQlManager.getShadowGraphqlClient().query<{\n customerBundlesFeed: BundlesFeed;\n }>({\n query: getTemplateBundlesQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"no-cache\",\n variables: {\n id: customerId,\n offset,\n limit,\n },\n });\n return rows?.data.customerBundlesFeed?.items || [];\n};\n","(function(){\"use strict\";try{if(typeof document<\"u\"){var e=document.createElement(\"style\");e.appendChild(document.createTextNode(\"#spiffThemeWrapper{width:100%;height:100%}\")),document.head.appendChild(e)}}catch(t){console.error(\"vite-plugin-css-injected-by-js\",t)}})();\nvar $e = Object.defineProperty;\nvar je = (e, t, n) => t in e ? $e(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;\nvar B = (e, t, n) => (je(e, typeof t != \"symbol\" ? t + \"\" : t, n), n);\nimport Ne from \"fs\";\nimport Ve from \"path\";\nvar Q = /* @__PURE__ */ ((e) => (e.Javascript = \"Javascript\", e.CSS = \"CSS\", e))(Q || {}), x = /* @__PURE__ */ ((e) => (e.Asset = \"Asset\", e.Boolean = \"Boolean\", e.Color = \"Color\", e.ConversionConfiguration = \"ConversionConfiguration\", e.Heading = \"Heading\", e.List = \"List\", e.Number = \"Number\", e.Object = \"Object\", e.Select = \"Select\", e.Text = \"Text\", e.DateRange = \"DateRange\", e))(x || {}), He = /* @__PURE__ */ ((e) => (e.Color = \"Color\", e.ColorProfile = \"ColorProfile\", e.Data = \"Data\", e.Environment = \"Environment\", e.Font = \"Font\", e.Frame = \"Frame\", e.Illustration = \"Illustration\", e.Image = \"Image\", e.Material = \"Material\", e.Model = \"Model\", e.Video = \"Video\", e))(He || {}), De = /* @__PURE__ */ ((e) => (e.Object = \"Object\", e.Union = \"Union\", e))(De || {}), Ie = /* @__PURE__ */ ((e) => (e.Manual = \"Manual\", e.OnStart = \"OnStart\", e.OnQuit = \"OnQuit\", e.OnEnd = \"OnEnd\", e))(Ie || {}), Oe = /* @__PURE__ */ ((e) => (e.Email = \"Email\", e.FirstName = \"FirstName\", e.LastName = \"LastName\", e.Phone = \"Phone\", e.Apartment = \"Apartment\", e.City = \"City\", e.Country = \"Country\", e.OrganizationName = \"OrganizationName\", e.PostCode = \"PostCode\", e.State = \"State\", e.StreetAddress = \"StreetAddress\", e.Custom = \"Custom\", e))(Oe || {});\nfunction X(e) {\n return Object.assign({}, ...e.map((t) => {\n if (t.key)\n return {\n [t.key]: he(t)\n };\n }));\n}\nfunction he(e) {\n var t;\n if (e.type === x.Asset)\n return e.asset;\n if (e.type === x.DateRange) {\n const n = (t = e.value) == null ? void 0 : t.split(\",\");\n if (!n || n.length !== 2 || !n[0] || !n[1])\n return;\n try {\n return {\n start: new Date(n[0]),\n end: new Date(n[1])\n };\n } catch {\n return;\n }\n }\n if (e.type === x.ConversionConfiguration)\n return e.conversionConfiguration;\n if (e.type !== x.List && e.type !== x.Object) {\n if (e.value === void 0)\n return;\n if (e.type === x.Number)\n try {\n return Number.parseFloat(e.value);\n } catch {\n return;\n }\n else if (e.type === x.Boolean)\n return e.value === \"true\";\n return e.value;\n }\n if (e.listValues)\n return e.listValues.map(he);\n if (e.objectValues)\n return {\n ...X(e.objectValues),\n schema: e.schema ?? void 0\n };\n}\nfunction gt(e) {\n return X(e);\n}\nfunction yt(e) {\n return X(e.fields);\n}\nfunction L(e, t) {\n const n = {\n ...e,\n items: void 0,\n fields: void 0\n };\n return e.items !== void 0 && e.items !== null && (n.items = L(t[e.items], t)), e.fields !== void 0 && e.fields !== null && (n.fields = e.fields.map((_) => L(t[_], t))), n;\n}\nfunction Fe(e) {\n var _;\n const t = {\n ...e,\n fields: [],\n customSchemas: (_ = e.customSchemas) == null ? void 0 : _.map((o) => {\n var i;\n return {\n ...o,\n fields: (i = o.fields) == null ? void 0 : i.map((a) => L(e.fields[a], e.fields))\n };\n })\n }, n = [];\n if (e.fields.forEach((o) => {\n o.root && n.push(L(o, e.fields));\n }), e.fields.length > 0 && n.length === 0)\n throw new Error(\"Failed to map ThemeVersionConfiguration GraphQL type to Resource type. Please ensure you've selected the `root` field on ThemeConfigurationSchemaField\");\n return t.fields = n, t;\n}\nfunction bt(e) {\n return {\n ...e,\n configurationSchema: Fe(e.configurationSchema)\n };\n}\nfunction z(e, t) {\n const n = {\n ...e,\n listValues: void 0,\n objectValues: void 0\n };\n return e.listValues !== void 0 && e.listValues !== null && (n.listValues = e.listValues.map((_) => z(t[_], t))), e.objectValues !== void 0 && e.objectValues !== null && (n.objectValues = e.objectValues.map((_) => z(t[_], t))), n;\n}\nfunction kt(e) {\n const t = {\n ...e,\n fields: []\n }, n = [];\n if (e.fields.forEach((_) => {\n _.root && n.push(z(_, e.fields));\n }), e.fields.length > 0 && n.length === 0)\n throw new Error(\"Failed to map ThemeInstallConfiguration GraphQL type to Resource type. Please ensure you've selected the `root` field on ThemeInstallConfigurationField\");\n return t.fields = n, t;\n}\nvar U, f, me, E, _e, ve, Z, $ = {}, ge = [], Le = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i, q = Array.isArray;\nfunction S(e, t) {\n for (var n in t)\n e[n] = t[n];\n return e;\n}\nfunction ye(e) {\n var t = e.parentNode;\n t && t.removeChild(e);\n}\nfunction Me(e, t, n) {\n var _, o, i, a = {};\n for (i in t)\n i == \"key\" ? _ = t[i] : i == \"ref\" ? o = t[i] : a[i] = t[i];\n if (arguments.length > 2 && (a.children = arguments.length > 3 ? U.call(arguments, 2) : n), typeof e == \"function\" && e.defaultProps != null)\n for (i in e.defaultProps)\n a[i] === void 0 && (a[i] = e.defaultProps[i]);\n return D(e, a, _, o, null);\n}\nfunction D(e, t, n, _, o) {\n var i = { type: e, props: t, key: n, ref: _, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, constructor: void 0, __v: o ?? ++me, __i: -1, __u: 0 };\n return o == null && f.vnode != null && f.vnode(i), i;\n}\nfunction R(e) {\n return e.children;\n}\nfunction I(e, t) {\n this.props = e, this.context = t;\n}\nfunction w(e, t) {\n if (t == null)\n return e.__ ? w(e.__, e.__i + 1) : null;\n for (var n; t < e.__k.length; t++)\n if ((n = e.__k[t]) != null && n.__e != null)\n return n.__e;\n return typeof e.type == \"function\" ? w(e) : null;\n}\nfunction be(e) {\n var t, n;\n if ((e = e.__) != null && e.__c != null) {\n for (e.__e = e.__c.base = null, t = 0; t < e.__k.length; t++)\n if ((n = e.__k[t]) != null && n.__e != null) {\n e.__e = e.__c.base = n.__e;\n break;\n }\n return be(e);\n }\n}\nfunction oe(e) {\n (!e.__d && (e.__d = !0) && E.push(e) && !M.__r++ || _e !== f.debounceRendering) && ((_e = f.debounceRendering) || ve)(M);\n}\nfunction M() {\n var e, t, n, _, o, i, a, u, l;\n for (E.sort(Z); e = E.shift(); )\n e.__d && (t = E.length, _ = void 0, i = (o = (n = e).__v).__e, u = [], l = [], (a = n.__P) && ((_ = S({}, o)).__v = o.__v + 1, f.vnode && f.vnode(_), ee(a, _, o, n.__n, a.ownerSVGElement !== void 0, 32 & o.__u ? [i] : null, u, i ?? w(o), !!(32 & o.__u), l), _.__.__k[_.__i] = _, xe(u, _, l), _.__e != i && be(_)), E.length > t && E.sort(Z));\n M.__r = 0;\n}\nfunction ke(e, t, n, _, o, i, a, u, l, s, p) {\n var r, d, c, v, k, g = _ && _.__k || ge, h = t.length;\n for (n.__d = l, Te(n, t, g), l = n.__d, r = 0; r < h; r++)\n (c = n.__k[r]) != null && typeof c != \"boolean\" && typeof c != \"function\" && (d = c.__i === -1 ? $ : g[c.__i] || $, c.__i = r, ee(e, c, d, o, i, a, u, l, s, p), v = c.__e, c.ref && d.ref != c.ref && (d.ref && te(d.ref, null, c), p.push(c.ref, c.__c || v, c)), k == null && v != null && (k = v), 65536 & c.__u || d.__k === c.__k ? l = Ce(c, l, e) : typeof c.type == \"function\" && c.__d !== void 0 ? l = c.__d : v && (l = v.nextSibling), c.__d = void 0, c.__u &= -196609);\n n.__d = l, n.__e = k;\n}\nfunction Te(e, t, n) {\n var _, o, i, a, u, l = t.length, s = n.length, p = s, r = 0;\n for (e.__k = [], _ = 0; _ < l; _++)\n (o = e.__k[_] = (o = t[_]) == null || typeof o == \"boolean\" || typeof o == \"function\" ? null : typeof o == \"string\" || typeof o == \"number\" || typeof o == \"bigint\" || o.constructor == String ? D(null, o, null, null, o) : q(o) ? D(R, { children: o }, null, null, null) : o.constructor === void 0 && o.__b > 0 ? D(o.type, o.props, o.key, o.ref ? o.ref : null, o.__v) : o) != null ? (o.__ = e, o.__b = e.__b + 1, u = Ae(o, n, a = _ + r, p), o.__i = u, i = null, u !== -1 && (p--, (i = n[u]) && (i.__u |= 131072)), i == null || i.__v === null ? (u == -1 && r--, typeof o.type != \"function\" && (o.__u |= 65536)) : u !== a && (u === a + 1 ? r++ : u > a ? p > l - a ? r += u - a : r-- : r = u < a && u == a - 1 ? u - a : 0, u !== _ + r && (o.__u |= 65536))) : (i = n[_]) && i.key == null && i.__e && (i.__e == e.__d && (e.__d = w(i)), J(i, i, !1), n[_] = null, p--);\n if (p)\n for (_ = 0; _ < s; _++)\n (i = n[_]) != null && !(131072 & i.__u) && (i.__e == e.__d && (e.__d = w(i)), J(i, i));\n}\nfunction Ce(e, t, n) {\n var _, o;\n if (typeof e.type == \"function\") {\n for (_ = e.__k, o = 0; _ && o < _.length; o++)\n _[o] && (_[o].__ = e, t = Ce(_[o], t, n));\n return t;\n }\n return e.__e != t && (n.insertBefore(e.__e, t || null), t = e.__e), t && t.nextSibling;\n}\nfunction Ae(e, t, n, _) {\n var o = e.key, i = e.type, a = n - 1, u = n + 1, l = t[n];\n if (l === null || l && o == l.key && i === l.type)\n return n;\n if (_ > (l != null && !(131072 & l.__u) ? 1 : 0))\n for (; a >= 0 || u < t.length; ) {\n if (a >= 0) {\n if ((l = t[a]) && !(131072 & l.__u) && o == l.key && i === l.type)\n return a;\n a--;\n }\n if (u < t.length) {\n if ((l = t[u]) && !(131072 & l.__u) && o == l.key && i === l.type)\n return u;\n u++;\n }\n }\n return -1;\n}\nfunction re(e, t, n) {\n t[0] === \"-\" ? e.setProperty(t, n ?? \"\") : e[t] = n == null ? \"\" : typeof n != \"number\" || Le.test(t) ? n : n + \"px\";\n}\nfunction H(e, t, n, _, o) {\n var i;\n e:\n if (t === \"style\")\n if (typeof n == \"string\")\n e.style.cssText = n;\n else {\n if (typeof _ == \"string\" && (e.style.cssText = _ = \"\"), _)\n for (t in _)\n n && t in n || re(e.style, t, \"\");\n if (n)\n for (t in n)\n _ && n[t] === _[t] || re(e.style, t, n[t]);\n }\n else if (t[0] === \"o\" && t[1] === \"n\")\n i = t !== (t = t.replace(/(PointerCapture)$|Capture$/, \"$1\")), t = t.toLowerCase() in e ? t.toLowerCase().slice(2) : t.slice(2), e.l || (e.l = {}), e.l[t + i] = n, n ? _ ? n.u = _.u : (n.u = Date.now(), e.addEventListener(t, i ? se : ie, i)) : e.removeEventListener(t, i ? se : ie, i);\n else {\n if (o)\n t = t.replace(/xlink(H|:h)/, \"h\").replace(/sName$/, \"s\");\n else if (t !== \"width\" && t !== \"height\" && t !== \"href\" && t !== \"list\" && t !== \"form\" && t !== \"tabIndex\" && t !== \"download\" && t !== \"rowSpan\" && t !== \"colSpan\" && t !== \"role\" && t in e)\n try {\n e[t] = n ?? \"\";\n break e;\n } catch {\n }\n typeof n == \"function\" || (n == null || n === !1 && t[4] !== \"-\" ? e.removeAttribute(t) : e.setAttribute(t, n));\n }\n}\nfunction ie(e) {\n var t = this.l[e.type + !1];\n if (e.t) {\n if (e.t <= t.u)\n return;\n } else\n e.t = Date.now();\n return t(f.event ? f.event(e) : e);\n}\nfunction se(e) {\n return this.l[e.type + !0](f.event ? f.event(e) : e);\n}\nfunction ee(e, t, n, _, o, i, a, u, l, s) {\n var p, r, d, c, v, k, g, h, y, C, j, P, ne, N, W, b = t.type;\n if (t.constructor !== void 0)\n return null;\n 128 & n.__u && (l = !!(32 & n.__u), i = [u = t.__e = n.__e]), (p = f.__b) && p(t);\n e:\n if (typeof b == \"function\")\n try {\n if (h = t.props, y = (p = b.contextType) && _[p.__c], C = p ? y ? y.props.value : p.__ : _, n.__c ? g = (r = t.__c = n.__c).__ = r.__E : (\"prototype\" in b && b.prototype.render ? t.__c = r = new b(h, C) : (t.__c = r = new I(h, C), r.constructor = b, r.render = Re), y && y.sub(r), r.props = h, r.state || (r.state = {}), r.context = C, r.__n = _, d = r.__d = !0, r.__h = [], r._sb = []), r.__s == null && (r.__s = r.state), b.getDerivedStateFromProps != null && (r.__s == r.state && (r.__s = S({}, r.__s)), S(r.__s, b.getDerivedStateFromProps(h, r.__s))), c = r.props, v = r.state, r.__v = t, d)\n b.getDerivedStateFromProps == null && r.componentWillMount != null && r.componentWillMount(), r.componentDidMount != null && r.__h.push(r.componentDidMount);\n else {\n if (b.getDerivedStateFromProps == null && h !== c && r.componentWillReceiveProps != null && r.componentWillReceiveProps(h, C), !r.__e && (r.shouldComponentUpdate != null && r.shouldComponentUpdate(h, r.__s, C) === !1 || t.__v === n.__v)) {\n for (t.__v !== n.__v && (r.props = h, r.state = r.__s, r.__d = !1), t.__e = n.__e, t.__k = n.__k, t.__k.forEach(function(V) {\n V && (V.__ = t);\n }), j = 0; j < r._sb.length; j++)\n r.__h.push(r._sb[j]);\n r._sb = [], r.__h.length && a.push(r);\n break e;\n }\n r.componentWillUpdate != null && r.componentWillUpdate(h, r.__s, C), r.componentDidUpdate != null && r.__h.push(function() {\n r.componentDidUpdate(c, v, k);\n });\n }\n if (r.context = C, r.props = h, r.__P = e, r.__e = !1, P = f.__r, ne = 0, \"prototype\" in b && b.prototype.render) {\n for (r.state = r.__s, r.__d = !1, P && P(t), p = r.render(r.props, r.state, r.context), N = 0; N < r._sb.length; N++)\n r.__h.push(r._sb[N]);\n r._sb = [];\n } else\n do\n r.__d = !1, P && P(t), p = r.render(r.props, r.state, r.context), r.state = r.__s;\n while (r.__d && ++ne < 25);\n r.state = r.__s, r.getChildContext != null && (_ = S(S({}, _), r.getChildContext())), d || r.getSnapshotBeforeUpdate == null || (k = r.getSnapshotBeforeUpdate(c, v)), ke(e, q(W = p != null && p.type === R && p.key == null ? p.props.children : p) ? W : [W], t, n, _, o, i, a, u, l, s), r.base = t.__e, t.__u &= -161, r.__h.length && a.push(r), g && (r.__E = r.__ = null);\n } catch (V) {\n t.__v = null, l || i != null ? (t.__e = u, t.__u |= l ? 160 : 32, i[i.indexOf(u)] = null) : (t.__e = n.__e, t.__k = n.__k), f.__e(V, t, n);\n }\n else\n i == null && t.__v === n.__v ? (t.__k = n.__k, t.__e = n.__e) : t.__e = Ue(n.__e, t, n, _, o, i, a, l, s);\n (p = f.diffed) && p(t);\n}\nfunction xe(e, t, n) {\n t.__d = void 0;\n for (var _ = 0; _ < n.length; _++)\n te(n[_], n[++_], n[++_]);\n f.__c && f.__c(t, e), e.some(function(o) {\n try {\n e = o.__h, o.__h = [], e.some(function(i) {\n i.call(o);\n });\n } catch (i) {\n f.__e(i, o.__v);\n }\n });\n}\nfunction Ue(e, t, n, _, o, i, a, u, l) {\n var s, p, r, d, c, v, k, g = n.props, h = t.props, y = t.type;\n if (y === \"svg\" && (o = !0), i != null) {\n for (s = 0; s < i.length; s++)\n if ((c = i[s]) && \"setAttribute\" in c == !!y && (y ? c.localName === y : c.nodeType === 3)) {\n e = c, i[s] = null;\n break;\n }\n }\n if (e == null) {\n if (y === null)\n return document.createTextNode(h);\n e = o ? document.createElementNS(\"http://www.w3.org/2000/svg\", y) : document.createElement(y, h.is && h), i = null, u = !1;\n }\n if (y === null)\n g === h || u && e.data === h || (e.data = h);\n else {\n if (i = i && U.call(e.childNodes), g = n.props || $, !u && i != null)\n for (g = {}, s = 0; s < e.attributes.length; s++)\n g[(c = e.attributes[s]).name] = c.value;\n for (s in g)\n c = g[s], s == \"children\" || (s == \"dangerouslySetInnerHTML\" ? r = c : s === \"key\" || s in h || H(e, s, null, c, o));\n for (s in h)\n c = h[s], s == \"children\" ? d = c : s == \"dangerouslySetInnerHTML\" ? p = c : s == \"value\" ? v = c : s == \"checked\" ? k = c : s === \"key\" || u && typeof c != \"function\" || g[s] === c || H(e, s, c, g[s], o);\n if (p)\n u || r && (p.__html === r.__html || p.__html === e.innerHTML) || (e.innerHTML = p.__html), t.__k = [];\n else if (r && (e.innerHTML = \"\"), ke(e, q(d) ? d : [d], t, n, _, o && y !== \"foreignObject\", i, a, i ? i[0] : n.__k && w(n, 0), u, l), i != null)\n for (s = i.length; s--; )\n i[s] != null && ye(i[s]);\n u || (s = \"value\", v !== void 0 && (v !== e[s] || y === \"progress\" && !v || y === \"option\" && v !== g[s]) && H(e, s, v, g[s], !1), s = \"checked\", k !== void 0 && k !== e[s] && H(e, s, k, g[s], !1));\n }\n return e;\n}\nfunction te(e, t, n) {\n try {\n typeof e == \"function\" ? e(t) : e.current = t;\n } catch (_) {\n f.__e(_, n);\n }\n}\nfunction J(e, t, n) {\n var _, o;\n if (f.unmount && f.unmount(e), (_ = e.ref) && (_.current && _.current !== e.__e || te(_, null, t)), (_ = e.__c) != null) {\n if (_.componentWillUnmount)\n try {\n _.componentWillUnmount();\n } catch (i) {\n f.__e(i, t);\n }\n _.base = _.__P = null, e.__c = void 0;\n }\n if (_ = e.__k)\n for (o = 0; o < _.length; o++)\n _[o] && J(_[o], t, n || typeof e.type != \"function\");\n n || e.__e == null || ye(e.__e), e.__ = e.__e = e.__d = void 0;\n}\nfunction Re(e, t, n) {\n return this.constructor(e, n);\n}\nfunction We(e, t, n) {\n var _, o, i, a;\n f.__ && f.__(e, t), o = (_ = typeof n == \"function\") ? null : n && n.__k || t.__k, i = [], a = [], ee(t, e = (!_ && n || t).__k = Me(R, null, [e]), o || $, $, t.ownerSVGElement !== void 0, !_ && n ? [n] : o ? null : t.firstChild ? U.call(t.childNodes) : null, i, !_ && n ? n : o ? o.__e : t.firstChild, _, a), xe(i, e, a);\n}\nU = ge.slice, f = { __e: function(e, t, n, _) {\n for (var o, i, a; t = t.__; )\n if ((o = t.__c) && !o.__)\n try {\n if ((i = o.constructor) && i.getDerivedStateFromError != null && (o.setState(i.getDerivedStateFromError(e)), a = o.__d), o.componentDidCatch != null && (o.componentDidCatch(e, _ || {}), a = o.__d), a)\n return o.__E = o;\n } catch (u) {\n e = u;\n }\n throw e;\n} }, me = 0, I.prototype.setState = function(e, t) {\n var n;\n n = this.__s != null && this.__s !== this.state ? this.__s : this.__s = S({}, this.state), typeof e == \"function\" && (e = e(S({}, n), this.props)), e && S(n, e), e != null && this.__v && (t && this._sb.push(t), oe(this));\n}, I.prototype.forceUpdate = function(e) {\n this.__v && (this.__e = !0, e && this.__h.push(e), oe(this));\n}, I.prototype.render = R, E = [], ve = typeof Promise == \"function\" ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, Z = function(e, t) {\n return e.__v.__b - t.__v.__b;\n}, M.__r = 0;\nvar T, m, G, ue, Y = 0, Se = [], O = [], ae = f.__b, le = f.__r, ce = f.diffed, fe = f.__c, pe = f.unmount;\nfunction Ee(e, t) {\n f.__h && f.__h(m, e, Y || t), Y = 0;\n var n = m.__H || (m.__H = { __: [], __h: [] });\n return e >= n.__.length && n.__.push({ __V: O }), n.__[e];\n}\nfunction Be(e) {\n return Y = 1, Ge(we, e);\n}\nfunction Ge(e, t, n) {\n var _ = Ee(T++, 2);\n if (_.t = e, !_.__c && (_.__ = [n ? n(t) : we(void 0, t), function(u) {\n var l = _.__N ? _.__N[0] : _.__[0], s = _.t(l, u);\n l !== s && (_.__N = [s, _.__[1]], _.__c.setState({}));\n }], _.__c = m, !m.u)) {\n var o = function(u, l, s) {\n if (!_.__c.__H)\n return !0;\n var p = _.__c.__H.__.filter(function(d) {\n return d.__c;\n });\n if (p.every(function(d) {\n return !d.__N;\n }))\n return !i || i.call(this, u, l, s);\n var r = !1;\n return p.forEach(function(d) {\n if (d.__N) {\n var c = d.__[0];\n d.__ = d.__N, d.__N = void 0, c !== d.__[0] && (r = !0);\n }\n }), !(!r && _.__c.props === u) && (!i || i.call(this, u, l, s));\n };\n m.u = !0;\n var i = m.shouldComponentUpdate, a = m.componentWillUpdate;\n m.componentWillUpdate = function(u, l, s) {\n if (this.__e) {\n var p = i;\n i = void 0, o(u, l, s), i = p;\n }\n a && a.call(this, u, l, s);\n }, m.shouldComponentUpdate = o;\n }\n return _.__N || _.__;\n}\nfunction Qe(e, t) {\n var n = Ee(T++, 3);\n !f.__s && Je(n.__H, t) && (n.__ = e, n.i = t, m.__H.__h.push(n));\n}\nfunction ze() {\n for (var e; e = Se.shift(); )\n if (e.__P && e.__H)\n try {\n e.__H.__h.forEach(F), e.__H.__h.forEach(K), e.__H.__h = [];\n } catch (t) {\n e.__H.__h = [], f.__e(t, e.__v);\n }\n}\nf.__b = function(e) {\n m = null, ae && ae(e);\n}, f.__r = function(e) {\n le && le(e), T = 0;\n var t = (m = e.__c).__H;\n t && (G === m ? (t.__h = [], m.__h = [], t.__.forEach(function(n) {\n n.__N && (n.__ = n.__N), n.__V = O, n.__N = n.i = void 0;\n })) : (t.__h.forEach(F), t.__h.forEach(K), t.__h = [], T = 0)), G = m;\n}, f.diffed = function(e) {\n ce && ce(e);\n var t = e.__c;\n t && t.__H && (t.__H.__h.length && (Se.push(t) !== 1 && ue === f.requestAnimationFrame || ((ue = f.requestAnimationFrame) || Ze)(ze)), t.__H.__.forEach(function(n) {\n n.i && (n.__H = n.i), n.__V !== O && (n.__ = n.__V), n.i = void 0, n.__V = O;\n })), G = m = null;\n}, f.__c = function(e, t) {\n t.some(function(n) {\n try {\n n.__h.forEach(F), n.__h = n.__h.filter(function(_) {\n return !_.__ || K(_);\n });\n } catch (_) {\n t.some(function(o) {\n o.__h && (o.__h = []);\n }), t = [], f.__e(_, n.__v);\n }\n }), fe && fe(e, t);\n}, f.unmount = function(e) {\n pe && pe(e);\n var t, n = e.__c;\n n && n.__H && (n.__H.__.forEach(function(_) {\n try {\n F(_);\n } catch (o) {\n t = o;\n }\n }), n.__H = void 0, t && f.__e(t, n.__v));\n};\nvar de = typeof requestAnimationFrame == \"function\";\nfunction Ze(e) {\n var t, n = function() {\n clearTimeout(_), de && cancelAnimationFrame(t), setTimeout(e);\n }, _ = setTimeout(n, 100);\n de && (t = requestAnimationFrame(n));\n}\nfunction F(e) {\n var t = m, n = e.__c;\n typeof n == \"function\" && (e.__c = void 0, n()), m = t;\n}\nfunction K(e) {\n var t = m;\n e.__c = e.__(), m = t;\n}\nfunction Je(e, t) {\n return !e || e.length !== t.length || t.some(function(n, _) {\n return n !== e[_];\n });\n}\nfunction we(e, t) {\n return typeof t == \"function\" ? t(e) : t;\n}\nvar Ye = 0;\nfunction Pe(e, t, n, _, o, i) {\n var a, u, l = {};\n for (u in t)\n u == \"ref\" ? a = t[u] : l[u] = t[u];\n var s = { type: e, props: l, key: n, ref: a, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, constructor: void 0, __v: --Ye, __i: -1, __u: 0, __source: o, __self: i };\n if (typeof e == \"function\" && (a = e.defaultProps))\n for (u in a)\n l[u] === void 0 && (l[u] = a[u]);\n return f.vnode && f.vnode(s), s;\n}\nclass Ke {\n constructor() {\n B(this, \"_context\");\n B(this, \"_getContextCallbacks\", []);\n }\n async getContext() {\n return this._context ? this._context : new Promise((t) => {\n this._getContextCallbacks.push(t);\n });\n }\n setContext(t) {\n this._context = t, this._getContextCallbacks.forEach((n) => n(t)), this._getContextCallbacks = [];\n }\n configureClient(t) {\n console.log(\"Client configured\");\n }\n themeLoaded() {\n console.log(\"Theme loaded\");\n }\n close() {\n console.log(\"Theme closed\");\n }\n addToEcommerceCart(t) {\n console.log(\"Add to cart\", t);\n }\n completeQuote() {\n console.log(\"Complete quote\");\n }\n navigateToCustomerPortal() {\n console.log(\"Navigating to customer portal\");\n }\n}\nlet A;\nconst Xe = ({\n context: e\n}) => {\n const [t, n] = Be(null);\n return Qe(() => {\n if (t) {\n if (A === void 0)\n throw new Error(\"Please call setSpiffDevOptions before requesting the context.\");\n A.setContext({\n ...e,\n container: t\n });\n }\n }, [t, e]), Pe(\"div\", {\n ref: n,\n id: \"spiffThemeWrapper\"\n });\n};\nfunction Ct(e, t) {\n A = new Ke(), window.SpiffThemeLoader = A;\n let n;\n typeof e == \"string\" ? n = document.getElementById(e) : n = e, We(Pe(Xe, {\n context: t\n }), n);\n}\nfunction xt(e) {\n return {\n id: \"example\",\n themeInstallId: (e == null ? void 0 : e.themeInstallId) ?? \"example\",\n name: \"Example Configuration\",\n createdAt: \"2021-01-01T00:00:00Z\",\n updatedAt: \"2021-01-01T00:00:00Z\",\n themeVersion: {\n id: \"example\",\n version: \"1.0.0\",\n createdAt: \"2021-01-01T00:00:00Z\",\n updatedAt: \"2021-01-01T00:00:00Z\",\n configurationSchema: {\n fields: []\n },\n launchData: {\n targetFiles: []\n },\n theme: {\n id: \"example\",\n name: \"Example Theme\",\n createdAt: \"2021-01-01T00:00:00Z\",\n updatedAt: \"2021-01-01T00:00:00Z\"\n }\n },\n fields: [],\n ...e\n };\n}\nconst qe = (e) => {\n if (Object.keys(e).includes(\"defaultValue\"))\n return e.defaultValue;\n};\nfunction St(e, ...t) {\n return e.fields.filter((n) => !n.key || !t.includes(n.key)).map((n) => ({\n key: n.key,\n fallbackToDefaultConfiguration: !1,\n value: qe(n),\n type: n.type,\n asset: void 0\n }));\n}\nconst et = \"@spiffcommerce/theme-bridge\", tt = \"1.25.0\", nt = \"module\", _t = {\n build: \"tsc && vite build\",\n preview: \"vite preview\",\n dev: \"ladle serve\",\n schema: \"node --no-warnings=ExperimentalWarning --loader ts-node/esm scripts/generateSchema.ts\"\n}, ot = \"./dist/index.umd.cjs\", rt = \"./dist/index.js\", it = \"./dist/index.d.ts\", st = [\n \"./dist\"\n], ut = {\n import: \"./dist/index.js\",\n require: \"./dist/index.umd.cjs\"\n}, at = {}, lt = {\n \"@ladle/react\": \"^4.0.2\",\n \"@preact/preset-vite\": \"^2.7.0\",\n \"@spiffcommerce/core\": \"^33.0.0\",\n \"@types/node\": \"^20.11.16\",\n \"@typescript-eslint/eslint-plugin\": \"^7.1.0\",\n \"@typescript-eslint/parser\": \"^7.1.0\",\n eslint: \"^8.57.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"eslint-plugin-prettier\": \"^5.1.3\",\n preact: \"^10.19.3\",\n prettier: \"^3.2.4\",\n rollup: \"^4.12.0\",\n \"ts-json-schema-generator\": \"^1.5.0\",\n \"ts-node\": \"^10.9.2\",\n tsup: \"^8.0.1\",\n typescript: \"^5.2.2\",\n vite: \"^5.0.8\",\n \"vite-plugin-css-injected-by-js\": \"^3.4.0\",\n \"vite-plugin-externalize-deps\": \"^0.8.0\"\n}, ct = {\n \"@spiffcommerce/core\": \"^33.0.0\"\n}, ft = \"yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e\", pt = {\n name: et,\n version: tt,\n type: nt,\n scripts: _t,\n main: ot,\n module: rt,\n types: it,\n files: st,\n exports: ut,\n dependencies: at,\n devDependencies: lt,\n peerDependencies: ct,\n packageManager: ft\n};\nfunction dt(e, t, n) {\n if (t.type === \"chunk\") {\n if (console.log(`chunk ${e} isEntry: ${t.isEntry}, isDynamicEntry: ${t.isDynamicEntry}, isImplicitEntry: ${t.isImplicitEntry}`), !t.isEntry && !n)\n return null;\n if (!t.isDynamicEntry)\n return {\n type: Q.Javascript,\n mimeType: \"text/javascript\",\n preload: !t.isEntry,\n filename: e\n };\n } else if (e.endsWith(\".css\"))\n return {\n type: Q.CSS,\n mimeType: \"text/css\",\n filename: e\n };\n return null;\n}\nfunction Et(e) {\n const {\n autoGenerateTargetFiles: t = !0,\n configurationSchema: n,\n includePreloadChunks: _ = !1,\n targetFiles: o\n } = e ?? {};\n return {\n name: \"spiff-theme-plugin\",\n version: pt.version,\n config(i, a) {\n i.base !== void 0 && i.base !== \"\" && console.warn('You have specified a `base` in your vite configuration other than \"\". This value will now be overwritten.'), i.base = \"\";\n },\n writeBundle(i, a) {\n const u = t ? Object.keys(a).map((s) => o != null && o.some((p) => p.filename === s) ? null : dt(s, a[s], _)).filter((s) => s !== null) : [];\n o && u.push(...o);\n const l = {\n launchData: {\n targetFiles: u\n },\n configurationSchema: n\n };\n Ne.writeFileSync(Ve.join(i.dir, \"spiffTheme.json\"), JSON.stringify(l, void 0, 4));\n }\n };\n}\nexport {\n He as AssetType,\n Oe as ConversionDataType,\n Ie as ConversionLocation,\n De as CustomSchemaType,\n x as FieldType,\n Q as ThemeFileType,\n xt as exampleThemeInstallConfig,\n St as getDefaultsForSchema,\n Ct as setSpiffDevOptions,\n Et as spiffThemePlugin,\n gt as themeInstallConfigurationFieldsToRecordObject,\n kt as themeInstallConfigurationGraphQlToResource,\n yt as themeInstallConfigurationToRecordObject,\n Fe as themeVersionConfigurationGraphQlToResource,\n bt as themeVersionGraphQlToResource\n};\n","import { gql } from \"@apollo/client/core\";\nimport { graphQlManager } from \"./services/server\";\nimport { WorkflowExperience } from \"./WorkflowExperience\";\nimport { AddressValidationStatus } from \"./types\";\n\nconst addressValidationResultFragment = gql`\n fragment AddressValidationResultFields on AddressValidationResult {\n addressComplete\n address {\n formattedAddress\n regionCode\n postalCode\n administrativeArea\n locality\n sublocality\n }\n components {\n name\n type\n confirmationLevel\n inferred\n spellCorrected\n replaced\n unexpected\n }\n missingComponentTypes\n }\n`;\nconst addressValidationJobFragment = gql`\n ${addressValidationResultFragment}\n fragment AddressValidationJobFields on AddressValidationJob {\n id\n entityId\n status\n createdAt\n updatedAt\n result {\n ...AddressValidationResultFields\n }\n }\n`;\n\nconst addressValidationJobsQuery = gql`\n ${addressValidationJobFragment}\n query GetAddressValidationJobs($ids: [String!]!) {\n addressValidationJobs(ids: $ids) {\n ...AddressValidationJobFields\n }\n }\n`;\n\nconst recipientAddressValidationJobsQuery = gql`\n ${addressValidationJobFragment}\n query GetRecipientsWithAddressValidationJobs($ids: [String!]!) {\n recipients(ids: $ids) {\n id\n addressValidationJob {\n ...AddressValidationJobFields\n }\n }\n }\n`;\n\nconst recipientValidateMutation = gql`\n ${addressValidationResultFragment}\n mutation ValidateRecipientAddress($id: String!) {\n recipientValidate(id: $id) {\n ...AddressValidationResultFields\n }\n }\n`;\n\nconst recipientValidateBatchMutation = gql`\n ${addressValidationJobFragment}\n mutation BatchValidateRecipientAddress($ids: [String!]!) {\n recipientValidateBatch(ids: $ids) {\n ...AddressValidationJobFields\n }\n }\n`;\n\nconst recipientOverrideAddressMutation = gql`\n mutation OverrideRecipientAddress($id: String!) {\n recipientOverrideAddress(id: $id) {\n id\n }\n }\n`;\n\nexport enum AddressValidationResultConfirmationLevel {\n Confirmed = \"Confirmed\",\n Plausible = \"Plausible\",\n Unlikely = \"Unlikely\",\n}\n\nexport interface AddressValidationResult {\n /**\n * Whether the resulting address is considered complete.\n * An address is considered complete if no components were unexpected or missing.\n */\n addressComplete?: boolean;\n address?: {\n /**\n * The full address, formatted in the standard format for the area.\n */\n formattedAddress?: string;\n /** Country code; AU, US, UK, etc. */\n regionCode?: string;\n postalCode?: string;\n /** The state/province etc. */\n administrativeArea?: string;\n /** Suburb/city */\n locality?: string;\n sublocality?: string;\n };\n /** The individual components of the address, and their associated validation information. */\n components?: AddressComponent[];\n /**\n * Component types that were expected to be on the address, but were not present and could not be inferred by the validator.\n * See https://developers.google.com/maps/documentation/places/web-service/legacy/supported_types#table2 for a list of possible types.\n */\n missingComponentTypes: string[];\n}\n\nexport interface AddressComponent {\n /** The text value of the component. */\n name: string;\n /**\n * The type of component it is.\n * See https://developers.google.com/maps/documentation/places/web-service/legacy/supported_types#table2 for a list of possible types.\n */\n type: string;\n /** How strongly the validator believes the result to be correct. */\n confirmationLevel?: AddressValidationResultConfirmationLevel;\n /** Whether this component was inferred by the validator, i.e. it was not present on the original input. */\n inferred?: boolean;\n /** Whether this component had spelling corrected by the validator. */\n spellCorrected?: boolean;\n /** Whether this component had its original value completely replaced by the validator. */\n replaced?: boolean;\n /** Whether the validator believes this component to be unexpected for the supplied address. */\n unexpected?: boolean;\n}\n\nexport enum AddressValidationJobStatus {\n Created = \"Created\",\n Processing = \"Processing\",\n Completed = \"Completed\",\n Failed = \"Failed\",\n Cancelled = \"Cancelled\",\n}\n\nexport interface AddressValidationJob {\n id: string;\n /** The entity this job was created for. */\n entityId?: string;\n /** The current status of this Job. */\n status: AddressValidationJobStatus;\n /** The datetime of when this Job was created. */\n createdAt: string;\n /** The datetime of when this Job was last updated. */\n updatedAt: string;\n /** The validation result. Only present if status is `Confirmed`. */\n result?: AddressValidationResult;\n}\n\n/**\n * Fetches Recipients of Workflow Experiences and their associated Address Validation Jobs.\n * The resulting array will be in the same order as the input `ids`. If a Recipient does not have an associated Job, it will be `undefined`.\n * @param workflowExperiences The Workflow Experiences to fetch jobs for.\n * @returns The associated Address Validation Jobs for the requested Workflow Experiences.\n */\nexport const getValidationJobsForWorkflowExperiences = async (\n workflowExperiences: WorkflowExperience[],\n): Promise<(AddressValidationJob | undefined)[]> => {\n const ids = workflowExperiences.map((wfe) => wfe.getTransaction().recipient?.id).filter((it) => !!it);\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n recipients: { id: string; addressValidationJob?: AddressValidationJob }[];\n }>({\n query: recipientAddressValidationJobsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"network-only\",\n variables: {\n ids: ids,\n },\n });\n return workflowExperiences.map((wfe) => {\n const id = wfe.getTransaction().recipient?.id;\n if (!id) {\n return undefined;\n }\n return response.data?.recipients?.find((r) => r.id === id)?.addressValidationJob;\n });\n};\n\n/**\n * Retrieves an up-to-date version of the requested Address Validation Jobs.\n * If a Job has been completed, the validation result will be present on the object.\n * @param ids An array of Address Validation Job id strings.\n * @returns An array of Address Validation Jobs.\n */\nexport const getAddressValidationJobs = async (ids: string[]): Promise<AddressValidationJob[] | undefined> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{\n addressValidationJobs: AddressValidationJob[];\n }>({\n query: addressValidationJobsQuery,\n errorPolicy: \"all\",\n fetchPolicy: \"network-only\",\n variables: {\n ids: ids,\n },\n });\n return response.data?.addressValidationJobs;\n};\n\n/**\n * Validate a single Workflow Experience's recipient address.\n * @param workflowExperience The Workflow Experience to validate. If this does not have a recipient attached, the function will immediately resolve with `undefined`.\n * @returns The validation result.\n */\nexport const validateWorkflowExperienceRecipient = async (\n workflowExperience: WorkflowExperience,\n): Promise<AddressValidationResult | undefined> => {\n if (!workflowExperience.getTransaction().recipient?.id) {\n return undefined;\n }\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{\n recipientValidate: AddressValidationResult;\n }>({\n mutation: recipientValidateMutation,\n errorPolicy: \"all\",\n fetchPolicy: \"network-only\",\n variables: {\n id: workflowExperience.getTransaction().recipient!.id!,\n },\n });\n return response.data?.recipientValidate;\n};\n\n/**\n * Requests to validate many Workflow Experiences' recipient addresses asynchronously.\n * @param workflowExperiences The Workflow Experiences to validate.\n * @returns An array of Address Validation Jobs. This is guaranteed to be in the same order as the input array.\n * If an input Workflow Experience does not have a recipient, the associated Job will be `undefined`.\n * The Jobs will likely be incomplete; consider polling `getAddressValidationJobs` with the ids of the Jobs you get from this function.\n */\nexport const validateWorkflowExperienceRecipients = async (\n workflowExperiences: WorkflowExperience[],\n): Promise<(AddressValidationJob | undefined)[]> => {\n const ids = workflowExperiences.map((wfe) => wfe.getTransaction().recipient?.id).filter((it) => !!it);\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{\n recipientValidateBatch: AddressValidationJob[];\n }>({\n mutation: recipientValidateBatchMutation,\n errorPolicy: \"all\",\n fetchPolicy: \"network-only\",\n variables: {\n ids: ids,\n },\n });\n return workflowExperiences.map((wfe) => {\n const id = wfe.getTransaction().recipient?.id;\n if (!id) {\n return undefined;\n }\n return response.data?.recipientValidateBatch?.find((r) => r.entityId === id);\n });\n};\n\n/**\n * Override the address of a specific workflow experience recipient\n * @param workflowExperience The Workflow Experience to override. If this does not have a recipient attached, the function will immediately resolve.\n */\nexport const overrideWorkflowExperienceRecipientAddress = async (\n workflowExperience: WorkflowExperience,\n): Promise<void> => {\n const id = workflowExperience.getTransaction().recipient?.id;\n if (!id) {\n return;\n }\n const response = await graphQlManager.getShadowGraphqlClient().mutate<{\n recipientOverrideAddress: { id: string };\n }>({\n mutation: recipientOverrideAddressMutation,\n errorPolicy: \"all\",\n fetchPolicy: \"network-only\",\n variables: {\n id,\n },\n });\n if (response.data?.recipientOverrideAddress?.id) {\n workflowExperience.getTransaction().addressValidationStatus = AddressValidationStatus.Overridden;\n }\n};\n","import { gql } from \"@apollo/client/core\";\nimport { IntegrationProductResource } from \"../types\";\nimport { graphQlManager, Product } from \"..\";\n\nconst getIntegrationProductsQuery = gql`\n query GetIntegrationProductsForIds($ids: [String!]!) {\n integrationProducts(ids: $ids) {\n id\n product {\n id\n name\n }\n }\n }\n`;\n\nexport const getIntegrationProducts = async (ids: string[]): Promise<IntegrationProductResource[]> => {\n const response = await graphQlManager.getShadowGraphqlClient().query<{ integrationProducts: { id: string, product: Product }[] }>({\n query: getIntegrationProductsQuery,\n variables: {\n ids,\n },\n })\n return response.data.integrationProducts;\n};"],"names":["AssetType","GlobalPropertyConfigurationConditionMode","AspectType","StepType","StepAspectType","LayoutRenderingPurpose","LayoutElementType","BundleDesignCreationCartAddMode","AddressValidationStatus","ShareActionType","IntegrationType","AddonHandle","ProductCameraRig","StakeholderType","TextAlgorithm","ScaleAxis","UnitOfMeasurement","CustomError","message","ConfigurationError","OptionNotFoundError","step","LayoutNotFoundError","region","AssetNotFoundError","variant","ResourceNotFoundError","asset","MisconfigurationError","ImplementationError","UnhandledBehaviorError","ParseError","ClientError","ResourceGenerationError","LocalStorageService","key","val","serialisedMap","mapSerialised","InMemoryStorageService","buildPersistentStorage","persistenceService","Configuration","serverUrl","callback","servicesApiUrl","hubUrl","spiffCoreConfiguration","domImpl","fetchImpl","registerWindowImplementation","impl","registerFetchImplementation","getWindow","fetch","input","init","arrayBufferMimeTypeCache","arrayBufferFileCache","textFileCache","getFromArrayBufferCache","url","cachedPromise","ab","resp","getFromTextCache","hasCapabilities","capabilities","cap","createElement","tag","createElementNS","namespace","elem","domParser","w","domParserConstructor","fetchAsArrayBuffer","externalUrl","allowCache","resolve","reject","response","err","fetchAsString","renderPapyrusComponentAsString","component","renderToStaticMarkup","fontFaceCache","loadFontFaceSet","font","familyName","fontFace","promise","xmlSerializer","toBase64","getMimeTypeOfArrayBuffer","arrayBuffer","getMimeTypeFromArrayBuffer","uint8arr","len","signatureArr","i","signature","mimeTypeData","dataUrlFromExternalUrl","blob","type","webBlobToDataUrl","uint8ArrayToString","array","binary","arrayBufferToDataUrl","mimeType","uint8Array","binaryString","b64","svgToDataUrl","svgString","dataUrlToArrayBuffer","dataUrl","uri","firstComma","meta","base64","data","c","e","target","localCustomerToken","applicationKey","setApplicationKey","getApplicationKey","bearerAuthenticationToken","setBearerAuthenticationToken","token","getHubAuthentication","onAuthenticationReceived","event","getServerAuth","localAuthObj","followRedirectFetch","moonlightUrl","result","GraphQlManager","client","httpLink","createHttpLink","authLink","setContext","_request","operationContext","headers","newHeaders","auth","bearer","useBeta","partnerId","activeIntegration","transactionOwnerId","customerToken","bundleOwnerId","hub","traceHeaders","value","errorLink","onError","operation","graphQLErrors","networkError","errors","context","removeTypenameLink","removeTypenameFromVariables","ApolloClient","from","InMemoryCache","graphQlManager","createCanvasInternal","loadImageInternal","createCanvas","width","height","module","documentCanvasModule","setCanvasModule","loadImage","src","allowCrossOrigin","throwOnError","_type","canvas","image","getDomParser","supportsAutoOrientation","getExifOrientation","exifOrientation","orientation","requiresCanvasOrientation","img","canvasDims","aspectRatio","getScaledAndOrientedCanvas","canvasWidth","canvasHeight","orientedWidth","orientedHeight","ctx","getAttributesFromArrayBuffer","pmsValues","hexValues","rgbValues","h","pmsToRgb","color","idx","rgbToPms","matchHexToPms","hex","maxDistance","pmsColors","distances","match","g","b","r1","g1","b1","dist","it","a","pmsHexData","pms","fuse","Fuse","findPmsColors","limit","colorContext","browserColorToHex","sanitizeHexCode","sanitized","hexCode","colorDefinitionPrintValue","colorDefinition","spot","spotColorDefinitionString","spotColorDefinition","profileNameStrWithoutSpaces","amountToSlice","svgColorValueToDefinition","parts","matchedFunctionArgs","params","fillableTagNames","replaceableStyleNames","traverse","node","f","child","checkAncestors","candidate","parent","matchingSelector","selector","sanitizeSvgTree","root","preserveAspectRatio","rules","parse","rule","nodeStyle","styles","style","trimmed","field","fieldDowncased","decl","sanitizeSVGDimensions","nonPixelUnitsRegex","viewBox","svgStringToElement","svg","setSvgDimensions","svgRoot","setSvgColors","colors","includeSpotColors","fill","className","stroke","svgElementToString","modifySVGWithElementProperties","modifySVGColors","parseSvg","svgBody","svgRegex","svgMatches","generateSVGWithUnknownColors","ancestorFill","inlineFill","attribute","fillValue","alphanumericFill","strokeValue","rebuiltSvg","assetMetadataFragment","gql","assetFragment","includeMetadata","getAssetsQuery","materialFragment","getMaterialsQuery","createAssetMutation","removeBackgroundFromAssetMutation","getAssets","assetKeys","getMaterials","ids","createAsset","name","anonymous","temporary","AssetService","file","attributes","dataUrlToBlob","assetKey","resolver","material","id","assetType","onProgress","creationResponse","req","responseData","AssetStorage","processedInfo","fileInfo","originalKey","BGRMStorage","removeResponse","text","assetResponse","ext","extension","ASSET_PERSISTENCE_KEY","_AssetStorage","newPersistentAssetsMap","oldPersistentAssets","uploadedAssetsMap","entryToRemove","m","cb","BGRM_ASSET_PERSISTENCE_KEY","bgRemovedKey","cache","map","assetService","PromiseCache","keyString","promiseCache","optionMinimalFragment","optionFragment","getOptionsQuery","getTagsQuery","getOptionsInternal","option","findOptionFromPromise","getOptions","promises","uncachedIds","batchPromise","getAssetImageUrl","v","findDefaultVariant","variants","overrideDefaultVariantId","OptionService","existingVariants","assetIds","materialIds","stepData","thumbnailUrl","optionService","activeIntegrationFragment","additionalProductFragment","recipientFragment","conversionConfigurationFragment","createManyTransactionsMutation","stakeholderFragment","transactionShareActionFragment","readIntegrationProductsQuery","readTransactionsQuery","updateTransactionWorkflowStateQuery","updateTransactionQuantityQuery","updateTransactionWorkflowQuery","getConversionConfigurationQuery","getTransactionQuery","getTransactionShareActionsQuery","confirmWorkflowStates","getIntegrationProductFragment","fetchIntegrationProducts","getIntegrationProductsQuery","includeIntegrations","getIntegrationProductFromExternalIdsQuery","getTransactionStakeholdersQuery","finalizeUpdateTransactionMutation","regionFragment","lookAtAnimationFragment","renderingPipelineConfigurationFragment","modelAnimationFragment","getWorkflowsQuery","includeAssetMetadata","marketplaceThemeInstallConfigurationFragment","getMarketplaceThemeInstallConfigurationQuery","currentIntegrationQuery","getTransactionForMarketplaceThemeQuery","getBundleForMarketplaceThemeQuery","createOrderMutation","currencyConversionQuery","silentStepTypes","getAllScenes","workflow","scenes","group","findGroupForStep","existingScene","scene","finishSceneTitle","stepName","stepGroups","stepConditionsAreSatisfied","stepSelections","condition","originatingStepData","selectedVariants","reqVariant","selVariant","filterSceneByConditions","filteredScene","getActiveScenes","allScenes","getRenderableRelevantScenes","singleVariantsRenderable","activeScenes","stepsWithRenderableConfiguration","variantAmount","renderableScenes","renderableScene","QueueablePromise","PromiseQueue","queueMaxSize","enabled","queueLength","item","generate","s4","SVGLayout","backgroundColor","outlineColor","borderRadius","configuration","elements","maxHeight","maxWidth","outlineArea","position","rx","strokeScale","calculatedViewbox","viewboxString","maskId","defs","jsx","colorProfileElements","index","elementsWithConfiguration","el","sortedElements","sortElementsByLayersWithIndex","jsxs","elementFactory","getAxisAlignedBoundingBox","x","y","rotation","rotationRadians","degreesToRadians","halfX","halfY","midX","midY","sin","cos","c1x","c2x","c1y","c2y","transformedC1X","transformedC2X","transformC1Y","transformedC2Y","extentX","extentY","findAngle","bc","ac","degrees","isCloseToValue","allowableDistance","getTrueCoordinates","point","pointOfRotation","s","getPointOfRotation","nwPoint","sePoint","getNWPoint","bounds","element","scaleX","scaleY","getNEPoint","getSEPoint","turnRightClockwise","dir","currentDirection","originalDirection","getElementVertices","canvasBounds","scale","radians","unrotatedTopLeft","unrotatedTopRight","unrotatedBottomRight","unrotatedBottomLeft","rotateAroundPoint","p","angleRadians","mmPerPixel","cmPerPixel","Image","props","angleInRadians","rotC","rotS","Group","clipPathId","buildDefinitions","Fragment","Frame","patternLinkId","thresholdFilterId","getFrameContentSrc","modifiedSvg","thresholdTableValues","renderDefinitions","getFrameContent","patternX","patternY","patternWidth","patternHeight","patternScaleX","patternScaleY","patternRotation","metricCache","FontMetrics","oldGlyphs","newGlyphs","glyphs","ascent","descent","glyph","metrics","valuesForFirst","valueForSecond","isDataURL","loadFontCache","loadFont","getFontMetrics","opentypeParse","cacheFontMetrics","buffer","_loadFontExternalDataURL","assetUrl","oldCache","newCache","outlineFontsInSvg","parser","parsedSvg","fontMap","fontFamily","d","tspans","tspan","textAncestor","gAncestor","decode","strokeWidth","pathToMeasure","offset","anchor","path","pathString","pathElement","t","clampWidth","lines","currentWidth","fontScale","charWidth","getLines","fontSize","lineHeight","lh","defaultLineHeightFactor","processedLines","line","splitLineUntilFit","calculatedLines","li","allChars","regionWidth","initialWidth","textWidth","middle","splitA","splitB","allWords","firstWordIndex","firstWord","split","tempWords","lastWordIndex","fits","nextWord","wordsWidth","calcFontSize","desiredWidth","lineWidth","desiredHeight","fontSizeW","fontSizeH","refitTextbox","updatedText","updatedElement","previousElement","fallbackLines","oneAxisChange","recalculateTextboxRegion","currentRegion","fontData","textLines","align","candidateRegion","requiredWidth","zip","lineA","lineB","fontSizeStep","kerningValue","transformationDefaults","applyTextTransformations","options","xs","ys","getTextAlignment","isVertical","getAnchor","recomputeTextOnElement","newText","oldEl","calculatedText","renderTextTemplateForWorkflow","workflowManager","renderTextTemplate","Handlebars","Textbox","curvedPathId","textFillId","xTranslation","yTranslation","getFill","TextPath","TextSpan","calcLineHeight","getX","getY","halfBoxHeight","reverseIdx","middleLineIdx","targetId","getStartOffset","Illustration","transform","CommandContext","command","leaveOffUndoStack","mostRecentCommand","undoneState","mostImminentCommand","sequenceId","initialState","layoutId","transactionState","layout","els","layoutNamesWithDupes","getSvgElement","layouts","reloadedState","newState","CreateLayoutCommand","state","renderingConfiguration","filteredElements","items","aLayer","bLayer","aLayerIndex","bLayerIndex","patternImageDataCache","frameDataCache","frameDataPromiseCache","generateFrameSVG","generateDefaultRectangleFrameSvg","getVariant","designInputStepData","getFrameData","frameSvg","frameDataPromise","frameDocument","viewBoxElems","viewBoxHeight","viewBoxWidth","elementById","elementByClass","calculateOffsets","imageData","frameData","nondefaults","forceImageCover","frameAspectRatio","imageAspectRatio","scaleFactor","frameCenterHorizontal","frameCenterVertical","defaultLeft","left","defaultTop","top","getPatternImageData","parsed","dataUriToBuffer","svgStringDimensions","svgData","GetSVGDimensions","svgText","lengthToPixels","length","svgElement","viewBoxValues","str","nextIndexForLayer","layer","maxIndex","getIllustrationBody","svgPromiseCache","svgObjectURL","getCanvasObjectURLAsync","pith","Pith","widthString","heightString","cachedIllustrationQuality","aspect","centralRegion","link","opts","coords","lesserDim","size","oldHeight","calculatedTextWidth","LayoutElementFactory","fontSrc","designInputStep","inputText","replacedText","recomputedElement","fittedRegion","elementKey","objectURL","ElementNotFoundError","findElement","findLayoutForElement","layoutForElement","layoutState","updatedLayoutForElement","updatedElements","layeredElements","rehydrateSerializedLayout","layoutNames","layoutName","illustration","illustrationBody","frame","layoutKey","illustrations","fonts","CanvasCommand","UpdateWorkflowStateCommand","serializableWorkflow","MoveCommand","updatedLayout","RotateCommand","angle","ResizeCommand","textbox","GroupCommand","commands","accumulatedState","curCommand","CreateElementCommand","currentElementsInLayout","newElements","finalElement","productOverlay","updatedLayoutsForElement","newIndex","elementArray","lastIndexOfLayer","DeleteElementCommand","elementFound","filteredLayouts","finalLayouts","FontColorCommand","textFillSpotColor","FontImageFillCommand","imageFill","FontSizeCommand","FontSourceCommand","FontAlignmentCommand","UpdateFramePattern","offsets","targetLayout","existingPattern","newLayout","UpdateFrameThresholdSettingsCommand","useThreshold","invertThreshold","threshold","thresholdSaturation","UpdateImageSourceCommand","TextChangeCommand","TextStrokeCommand","strokeColor","strokeThickness","IllustrationColorCommand","newColors","oldColor","IllustrationCacheCommand","BringToFrontCommand","l","fromIndex","BringToBackCommand","BringForwardCommand","toIndex","SendBackwardsCommand","SilentStepHandler","config","product","assetFromProduct","newElement","shortenUrl","longUrl","shortenerUrl","Poller","predicate","onSuccess","onFailure","interval","maxAttempts","DigitalContentStepService","reducerState","serializedStep","regionElements","shortUrl","getMpegLink","videoLink","linkData","protocolPrefix","urlBuilder","builtUrl","createElementForRegion","regionIndex","dataUri","urlToString","regionElement","digitalContentStepService","FrameStepService","reducerStep","initialPatternOverride","bundle","stateManager","uploadAspect","defaultVariant","frameSvgs","finish","storageColors","patternSrc","frameService","variantId","_workflowManager","recalculateOffsets","assetSrc","existingSrc","svgVersion","setFrameIsUpdating","colorSafeSvg","originalSvg","matches","svgAndColors","newFills","colorData","unique","newFill","colorOption","maxColors","loadedPattern","initZoom","createdData","r","newFrameData","existingImage","removeExistingCommands","newOffsets","pattern","newElementId","createCommands","cdnLink","updateId","frameStepService","IllustrationStepService","regionEls","elementsForStep","illustrationWidth","illustrationHeight","layoutElement","spotColor","pmsValue","colorsForCommand","setIsUpdating","deleteCommands","elementsWithCommands","commandList","targetElements","defaultColorVariants","modifiedColors","cn","availableColors","colorEntries","singleColor","entry","illustrationStepService","MaterialStepService","modelContainer","variantPromises","matName","setApplying","materialStepService","ModelStepService","highlightedRef","modelRef","modelStepService","ModuleStepService","setError","profanityFilter","validationResult","createElementFromRegion","existingKey","results","maxLength","words","word","profanity","moduleStepService","PictureStepService","deletionCommands","pictureStepService","QuestionStepService","questionStepService","ShapeStepService","manager","stepElement","colourOption","existingColor","getColor","updateCommand","newColor","shapeStepService","Toast","errorMessage","errorType","toast","linesThatFit","linesToBreak","amountLines","widthsPerLine","couldStillFit","textboxWidth","idxWidestLine","iMax","arr","widestLine","foundGoodSpacing","idxOfSpace","splitLine","splitWidths","determineCorrectFontSizeAndLines","curFontSize","sizeRange","nonUserMin","calculatedFontSize","defaultFontSize","FontLoadError","allowableGlyphs","RegionLayoutMissingError","TextStepService","filteredText","badCharacterCodes","opentypeFont","searchableGlyphs","char","renderedText","errorData","defaultImageFillVariant","imageFillLink","imageFillDataRaw","imageFillData","defaultStroke","strokeData","aspectText","cached","alignment","commandDispatcher","imageFillOption","imageFillUrls","fillImage","strokeOption","customiseAllText","injectedText","storage","processedText","correctFontSizes","correctLineLists","newFontSize","newLines","setHelperText","colorProfileAsset","finalFilteredName","fontSourceCommands","groupCommand","com","textStepService","fontAsset","fontUrl","shouldReturnResult","wrappedSetError","imageFillCommands","strokeCommands","sizingCommand","newlyCreatedData","currentText","transformedText","addFontToRegion","elementId","defaultColor","startingFill","sizingCommands","newCommand","newElementData","InformationMessageType","correctFontSize","textChangeCommand","fontSizeCommand","curFontData","setFlashRedError","existingRegionEls","newHelperText","msg","ModuleProduct","fontTtfDataUrl","svgElem","svgRect","dropShadow","dx","dy","blur","shadow","feOffset","feGaussianBlur","feBlend","fixCase","transformTextEnclosure","textEnclosure","textBbox","boundsHeight","boundsWidth","heightPaddingFactor","widthPaddingFactor","heightPadFactor","widthPadFactor","textRect","boundsScaleFactor","shiftLeft","shiftTop","textRectHeight","textRectWidth","heightRatio","widthRatio","segmentSchemas","Warp","pathElements","pathData","transformer","prevType","segment","output","outputType","first","schema","property","outputValue","segmentExpr","numberExpr","segmentMatch","numbers","relative","segmentData","j","pointGroups","oldPoints","newPoints","newPath","Vegemite","parsedtext","basePath","pathSvg","box","pathWidth","textSvg","gdefs","thick","layer0","layer1","layer2","layer3","rootElement","boundsRect","textGroup","svgPathBbox","moduleResolver","moduleName","handleDigitalContentStep","digitalContentStep","baseUrl","videoSource","finalUrl","urlToQrString","regions","handleFrameStep","frameStep","createFrameAndPattern","handleIllustrationStep","illustrationStep","fillName","replacementColors","k","handleModuleStep","moduleStep","handlePictureStep","pictureStep","handleShapeStep","shapeStep","handleSilentStep","silentStep","productOverlayImageUrl","assetSource","fetchedSrc","sanitizeSvg","rawSvg","handleTextStep","textStep","textAlign","getFontUrl","getDefaultColor","newBaseElement","correctLines","generateCommands","designInputSteps","workflowStep","LayoutPreviewService","LayoutPreviewBridge","handleCompleteRender","calculateNonPOTSupport","_reject","gl","nonPotTexSupport","service","panelSize","getWorkflowManager","dirty","clonedLayouts","cloneDeep","staticContext","RenderQueuePromise","nonPOTSupport","onRender","originalSize","maxSize","minAspectRatio","layoutWidth","layoutHeight","renderDims","targetWidth","targetHeight","targetRatio","boundedSize","templatingContext","svgStr","cvg","stepAspectValuesToDesignInputSteps","stepAspectValues","stepAspectValue","generateStateFromDesignInputSteps","globalPropertyStateAspectFragment","createGlobalPropertyStateMutation","updateGlobalPropertyStateMutation","getGlobalPropertyStateQuery","getGlobalPropertyStateForBundle","bundleId","productFields","filterWorkflows","productCollectionProductFieldsFragment","productCollectionFieldsFragment","eagerFetchProducts","bundleBaseFieldsFragment","getBundleQuery","getBundleStakeholdersQuery","getBundlesAndStakeholdersForCustomerQuery","getProductCollectionProductsQuery","getProductCollectionProductsFilteredQuery","getProductCollectionProductsFeedQuery","createBundleMutation","duplicateBundleMutation","updateBundleMutation","bundleAddTransactionMutation","bundleAddTransactionsMutation","bundleRemoveTransactionMutation","bundleRemoveTransactionsMutation","bundleAddStakeholderMutation","bundleRemoveStakeholderMutation","bundleUpdateStakeholdersMutation","bundleUpdateTransactionOrderMutation","bundleAssignProductCollectionMutation","bundleAssignGlobalPropertyConfiguration","customerBundlesFeedQuery","finalizeUpdateBundleMutation","bundleApprovalQuery","bundleRejectionQuery","transactionApprovalQuery","transactionRejectionQuery","createRecipientQuery","updateRecipientQuery","transactionAttachRecipientQuery","deleteBundleQuery","findBundleForTransactionsQuery","sortKeysReplacer","sorted","dehydrateState","lay","deleteFieldNameFromObjectRecursive","obj","fieldName","STATE_DEBOUNCE_TIME","WorkflowStatePromise","update","createLayoutsFromPanels","panels","panel","getInitialLayouts","transaction","serializedState","initialReducerState","_InternalWorkflowManager","experience","updateTransaction","graphQlClient","readOnly","isReloadedTransaction","delayWorkflowStateSync","ps","previewHandles","previewBridge","recipient","ConversionDataType","firstName","lastName","address","suburb","email","postalCode","country","mobile","company","apartment","customField1","customField2","customField3","customField4","customField5","conversionConfigurationId","prevalidated","WorkflowExperienceEventType","createRecipientResult","existingPromise","fireReloadAnimation","finalConfig","lookAt","modelAnim","requiredInitialOptions","acc","initialOptionsPromise","conversionConfigPromise","introducedSilentSteps","silentStepElements","silentCommands","existingSelections","optionIds","simulatedSelections","previousActiveStepCount","activeSteps","defaultVariantId","poller","customer","details","container","selections","stepStorage","stepNames","stepInitialised","up","status","stepId","error","changed","stepErrors","previewService","refocusCamera","newStorage","isEqual","workflowCommand","steps","stepStructure","workflowState","fullState","deepClone","dehydrated","alphabetizedModificationIds","hashBuffer","filterOutAllElementsFromSteps","existingStepElements","stepsWithoutOldElements","newListOfStepElements","regionElementToRemove","currentRegionElement","selectionsToRemove","invalidVariants","handlingReload","executeSilentStep","uninitializedSteps","silentStepPromises","silentStepResults","stepResult","serializedSteps","shareActions","note","oldSelections","total","current","vs","oldScenes","newScenes","oldSilentSteps","newStep","oldStep","invalidCanvasRegions","regionEl","invalidModelVariants","removalPromises","im","stepsPerScene","stepPromises","stepCwfs","cwf","followups","followup","traversableScenes","InternalWorkflowManager","Variant","locales","thumb","full","_StepHandle","tags","variantResource","configurationId","immediate","preview","modelAnimation","lookAtAnimation","StepHandle","IllustrationStepHandle","elementColors","assetConfiguration","newFillMap","MaterialStepHandle","ModelStepHandle","PictureStepHandle","QuestionStepHandle","ShapeStepHandle","colorVariant","TextStepHandle","stepElements","shouldCustomizeAll","customiseableText","userInput","layoutElements","filteredUserInput","inputLength","maxLengthExceeded","regionless","candidateMetadata","helperData","defaultText","_color","InformationStepHandle","DigitalContentStepHandle","ModuleStepHandle","StepHandleFactory","FrameStepHandle","createDesignTransactionFragment","createDesignsMutation","isTokenExpired","expiry","createDesignsGqlCall","designDetails","spiffClient","extraHeaders","jwtTokenKey","_","jwtToken","designDetail","formatMetadata","metadata","forCart","metadataObjectForStep","formattedMetadata","stepMetadata","colorString","prepareExportedData","designWorkflowMetadata","exportedData","distinctStepTitles","stepTitle","selection","createDesignMessage","generatedSku","lineItemImageLink","processExecutionId","baseCost","optionsCost","ownerId","msgObject","createDesignDetails","getReducerState","workflowSelections","designName","createPreviewImage","workflowMetadata","forceFlushState","cameraOrientation","shouldUploadThreeDimPreview","cartMetadata","designMetadata","getSelections","stepOption","cartSelectionsWithPrices","cartSelections","designSelectionsWithPrices","designSelections","previewImageUrl","previewImageBlob","metadataList","selectionsList","createDesigns","unsyncedStates","transactions","chunkedTransactions","chunk","failedStates","serverWorkflowStates","createDesignResults","createDesignsResponse","design","createDesignResult","upToDateTransaction","DesignService","func","persistedString","transactionId","newDesigns","listener","title","designs","designService","addTransactionStakeholderMutation","addAddressToTransactionMutation","addOrganizationToTransactionMutation","transactionUpdateIntegrationProductMutation","WorkflowExperienceImpl","experienceOptions","debounce","request","callbackOptions","workflowScene","newSteps","integrationProductId","newProduct","collectionProduct","defaultWorkflow","getWorkflow","streetAddress","city","postCode","isThreeD","resolution","res","defaultPanelIndex","targetPanel","defaultLayout","objectUrl","cachedHandle","createdHandle","sg","disablePriceBreaks","totalSelectionCost","includeAdditionalProduct","basePrice","additionalPrice","integrationProduct","additionalProductPrice","subUnits","percentage","finalPrice","priceBreaks","totalQuantity","exp","pb","updatedPriceBreak","wfe","transactionIdA","transactionIdB","productIdA","productIdB","filter","bundleProperties","filterIds","targetSteps","originatingSteps","getGlobalPropertyFromConfig","targetStep","uniqueProperties","propertyConfigurations","originatingStep","properties","actualProperty","requiredProperty","curVariant","stakeholder","transactionCustomerIds","saveData","existingTitle","savedWorkflowState","capturePreviewImage","show3D","stepSelection","curStepExportedData","stepHasExportableSelection","stepmd","quantity","events","evt","selectionConfiguredToExport","GlobalPropertyHandleService","handle","handles","targetAspect","FileUploadGlobalPropertyHandle","ColorOptionGlobalPropertyHandle","OptionGlobalPropertyHandle","TextGlobalPropertyHandle","GlobalPropertyHandle","targetExperiences","applyNewAsset","bgRemoved","updatedStorage","stateValue","originalImage","existingStorage","targetKey","updateUsingBg","bgRemovedImage","colorMap","sharedSteps","fills","useAsOriginalImage","updateFrameOffsets","experiencesUpdates","aspectValue","optionResource","channel","customColor","currentColor","getStepsForAspect","aspectName","stepType","experiences","globalConfig","ex","amtChannelsForAspect","channelAmts","omitDeep","blacklist","omitDeepOnOwnProps","isObject","o","isNil","omit","calculateMandatoryStates","globalPropertyState","mandatoryFulfilledAspects","cloneStateFromNetwork","GlobalPropertyStateManagerImpl","onGlobalPropertyStateChange","bundleOptions","existingState","names","aspects","previousState","configAspect","aspectIndex","storageInput","createResponse","BundleStateManager","stateData","metafieldsQuery","MetafieldManager","entityId","keys","loadedKeys","entityIds","queryResponse","entityFields","lf","ef","metafieldManager","ProductCollectionProductSortKey","ProductCollection","collection","products","pcp","CollectionProduct","productIds","filters","sortKey","sortDescending","currentProducts","filteredResults","productFilters","quickSearch","workflowFilters","filteredProducts","abortController","signal","observable","fetched","subscription","productCollectionProduct","externalId","ip","hasType","typeMatches","externalIdMatches","workflows","configuredDefault","found","ProductWorkflow","price","getCollectionsQuery","getProductCollections","EventEmitter","payload","addAddressToBundleMutation","addOrganizationToBundleMutation","generateQuoteIdMutation","BundleImpl","entity","graphqlOptions","transactionLoadProgressCallback","defaultGlobalPropertyConfiguration","stateString","idsToRemove","quoteId","dd","po","fileHandle","assets","colorHandle","optionHandle","partialSum","we","aspectNames","matchingAspect","channelNumbers","defaultColors","amtChannelsInitialized","uniqueChannelNumbers","channelNumber","dc","globalProperties","transactionIds","existing","ownerMap","existingOwnerIds","initializeExperience","updateArray","existingOwnerId","removed","removedExp","indices","removedExperiences","oldExperience","temp","sortFunc","customerDetails","stakeholderType","stakeholders","emailAddress","updatedStakeholders","onProgressUpdate","shouldRender3D","orderItems","globalPropertyConfigurationId","productCollectionId","globalPropertyConfiguration","selected","integrationProductIds","productCollection","ipId","previousHandles","newHandles","oldAspects","newHandle","resultingState","nextHandles","completed","remaining","previousMandatory","fulfilled","stakeholderId","executeProcessFlow","FlowService","inputs","executionId","delay","ms","repeats","flowResult","FlowExecutionResult","maxRepeats","execution","n","FlowExecutionNodeResult","FlowExecutionInput","ObjectInputType","TextInput","ObjectInput","uuid","ArrayInput","IntegrationProduct","additionalIP","getCustomerQuery","customerCreateMutation","customerGenerateVerificationCodeMutation","customerMetafieldsQuery","GraphQlClientWrapper","base","UserPoolManager","spiffRegion","userPoolRegion","userPoolClientId","CognitoIdentityProviderClient","InitiateAuthCommand","code","RespondToAuthChallengeCommand","existingTokensString","existingTokens","userPoolManager","CurrencyService","currency","amount","currencyFormatSettings","Dinero","currencyCode","currencyCodeData","CurrencyCodes","currencyService","CurrencyContext","rateFrom","rateTo","partnerCurrency","presentmentCurrency","units","getWorkflowsInternal","pickWorkflowFromPromise","getWorkflows","existingPromises","_id","getWorkflowsPromise","uncachedPromises","filteredPromises","getIntegrationProducts","SpiffCommerceClient","conversionResponse","getIntegration","addonHandle","transactionCustomers","transactionStakeholder","graphqlClient","createdCustomer","authResult","lastRefreshed","nowSeconds","expired","collectionId","initialMetadata","bundleEntity","_idx","bundlePartnerMap","newBundle","contextHeaders","bundleWrapper","template","duplicateTransactions","getContextHeadersForBundle","bundleOwnerMap","variables","previewServiceConstructor","instantiatedWorkflow","optionsArray","transactionInitializedCallback","indexedOptions","transactionOptions","createOptions","batchSize","batchedReadTransactions","batchedCreateOptions","amtLoaded","readTransactions","batch","reason","createTransactions","transactionResults","workflowIds","integrationProducts","integrationProductMap","workflowMap","experienceOptionsPromises","transactionResult","workflowId","graphQlClientWrapper","workflowExperienceOptions","sortedExperienceOptions","partnerCustomerMap","fetchIntegrationsOnProduct","externalIntegrationId","externalProductId","orderCreateResponse","themeConfigurationId","getTransaction","getOverrideThemeConfiguration","overrideThemeConfigurationId","overrideThemeInstallId","getBundleThemeConfiguration","getTransactionThemeConfiguration","getAuthHeaders","getContextHeadersForTransaction","deleteBundle","bundleContextHeaders","getBundleIdForTransaction","transactionContextHeaders","getBoundedOffsets","mustCover","newWidth","newHeight","covering","zoomMinimumBound","boundedWidth","boundedHeight","boundToRange","bounded","min","max","FrameService","initialZoom","frameStorage","frameSource","existingFrameData","frameDataChangeListener","paths","zoom","cX","cY","onComplete","calculatedOffsets","xoff","yoff","dX","dY","zoomChangeListener","forceUpdate","patternData","settings","newListener","thresholdSettings","elementID","offsetIndex","minimumScale","MockWorkflowManager","_firstName","_lastName","_address","_suburb","_state","_email","_postalCode","_country","_mobile","_company","_apartment","_customField1","_customField2","_customField3","_customField4","_customField5","_conversionConfigurationId","_note","_getReducerState","_poller","_callback","_stepName","_command","_serializedSteps","_stepNames","_update","_stepId","_status","_results","_variants","_elements","_previewService","_enabled","_field","_error","FrameStep","frameStepData","storeAsOriginal","uploading","imageUploadComplete","getCurrentUserDetailsQuery","getCustomerTransactionsQuery","setTransactionDesignName","duplicateTransactionMutation","getCustomerBundlesQuery","getTransactionsForBundleQuery","setBundleName","getTemplateBundlesQuery","nameBundle","nameTransaction","duplicateBundle","duplicateTransaction","getCustomer","getCustomerBundles","customerId","getTransactionsForBundle","getUnorderedTransactions","getOrderedTransactions","getTemplateTransactions","getTemplateBundles","Ie","Oe","u","G","ue","Se","O","ae","le","ce","fe","pe","ze","F","K","Ze","de","addressValidationResultFragment","addressValidationJobFragment","addressValidationJobsQuery","recipientAddressValidationJobsQuery","recipientValidateMutation","recipientValidateBatchMutation","recipientOverrideAddressMutation","AddressValidationResultConfirmationLevel","AddressValidationJobStatus","getValidationJobsForWorkflowExperiences","workflowExperiences","getAddressValidationJobs","validateWorkflowExperienceRecipient","workflowExperience","validateWorkflowExperienceRecipients","overrideWorkflowExperienceRecipientAddress"],"mappings":"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Cf,MACJ,IAAK,GACDA,EAAI,OAAO,IAAO,KAAK,EAAE,EACzBA,EAAI,MAAM,GAAI,CAAC,EACf,MACJ,IAAK,GACDA,EAAI,OAAO,IAAO,KAAK,EAAE,EACzBA,EAAI,UAAU,CAACF,EAAe,CAAC,EAC/B,MACJ,IAAK,GACDE,EAAI,OAAO,IAAO,KAAK,EAAE,EACzBA,EAAI,UAAU,CAACF,EAAeC,CAAc,EAC5CC,EAAI,MAAM,EAAG,EAAE,EACf,MACJ,IAAK,GACDA,EAAI,OAAO,GAAM,KAAK,EAAE,EACxBA,EAAI,UAAU,EAAG,CAACD,CAAc,EAChC,KAEA,CAGR,OAAAC,EAAI,UAAUR,EAAK,EAAG,EAAGM,EAAeC,CAAc,EAC/Cf,CACX,EAEaiB,GAA+B,MAAO/G,GAA6B,CAC5E,MAAM8F,EAAS,MAAMW,GAA2BzG,CAAW,EAE3D,OADqBD,GAAyBC,CAAW,IACpC,aACV,CACH,QAAS8F,EAAO,UAAU,aAAc,CAAG,EAC3C,OAAQA,EAAO,OACf,MAAOA,EAAO,KAAA,EAGf,CACH,QAASA,EAAO,UAAA,EAChB,OAAQA,EAAO,OACf,MAAOA,EAAO,KAAA,CAEtB,ECnKMkB,GAAY,CACd,WACA,eACA,eACA,aACA,YACA,eACA,kBACA,WACA,WACA,aACA,gBACA,iBACA,UACA,UACA,gBACA,aACA,iBACA,gBACA,cACA,eACA,eACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,kBACA,kBACA,eACA,eACA,SACA,kBACA,cACA,gBACA,iBACA,kBACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,gBACA,iBACA,iBACA,YACA,YACA,YACA,YACA,YACA,WACJ,EAEMC,GAAY,CACd,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,QACJ,EAEMC,GAAYD,GAAU,IAAKE,GAAM,CACnC,SAASA,EAAE,UAAU,EAAG,CAAC,EAAG,EAAE,EAC9B,SAASA,EAAE,UAAU,EAAG,CAAC,EAAG,EAAE,EAC9B,SAASA,EAAE,UAAU,EAAG,CAAC,EAAG,EAAE,CAClC,CAAC,EAED,SAASC,GAASC,EAAe,CAC7B,MAAMC,EAAMN,GAAU,QAAQK,CAAK,EACnC,OAAOC,GAAO,EAAIL,GAAUK,CAAG,EAAI,EACvC,CAEA,SAA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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAqY1BG,GAA+C3G,EAAAA;AAAAA,MAC/CiF,EAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","x_google_ignoreList":[96]}
|