@m2c2kit/core 0.3.17 → 0.3.18

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Canvas, Typeface, TypefaceFontProvider, Image, CanvasKit, Surface, Font, Paint, ParagraphBuilder, Paragraph, FontMgr, Path, PaintStyle } from 'canvaskit-wasm';
1
+ import { Canvas, Typeface, TypefaceFontProvider, Image, Paint, CanvasKit, Surface, Font, ParagraphBuilder, Paragraph, FontMgr, Path, PaintStyle } from 'canvaskit-wasm';
2
2
 
3
3
  declare class GlobalVariables {
4
4
  now: number;
@@ -175,6 +175,13 @@ interface Layout {
175
175
  */
176
176
  type RgbaColor = [number, number, number, number];
177
177
 
178
+ /**
179
+ * Map of placeholders to values for use in string interpolation.
180
+ */
181
+ interface StringInterpolationMap {
182
+ [placeholder: string]: string;
183
+ }
184
+
178
185
  interface TextOptions {
179
186
  /** Text to be displayed */
180
187
  text?: string;
@@ -184,6 +191,10 @@ interface TextOptions {
184
191
  fontColor?: RgbaColor;
185
192
  /** Size of text. Default is Constants.DEFAULT_FONT_SIZE (16) */
186
193
  fontSize?: number;
194
+ /** Map of placeholders to values for use in string interpolation during localization. */
195
+ interpolation?: StringInterpolationMap;
196
+ /** If true, try to use a localized version of the text. Default is true. */
197
+ localize?: boolean;
187
198
  }
188
199
 
189
200
  /**
@@ -224,7 +235,9 @@ declare enum M2NodeType {
224
235
  Label = "Label",
225
236
  TextLine = "TextLine",
226
237
  Shape = "Shape",
227
- Composite = "Composite"
238
+ Composite = "Composite",
239
+ SoundPlayer = "SoundPlayer",
240
+ SoundRecorder = "SoundRecorder"
228
241
  }
229
242
 
230
243
  type EasingFunction = (
@@ -551,15 +564,15 @@ interface IDataStore {
551
564
  /** Sets the value of an item. The key will be saved to the store as provided;
552
565
  * if namespacing or other formatting is desired, it must be done before
553
566
  * calling this method. activityId can be used by the store for indexing. */
554
- setItem(key: string, value: string | number | boolean | object | undefined | null, activityId: string): Promise<string>;
567
+ setItem(key: string, value: string | number | boolean | object | undefined | null, activityPublishUuid: string): Promise<string>;
555
568
  /** Gets the value of an item by its key. */
556
569
  getItem<T extends string | number | boolean | object | undefined | null>(key: string): Promise<T>;
557
570
  /** Deletes an item by its key. */
558
571
  deleteItem(key: string): Promise<void>;
559
572
  /** Deletes all items. */
560
- clearItemsByActivityId(activityId: string): Promise<void>;
573
+ clearItemsByActivityPublishUuid(activityPublishUuid: string): Promise<void>;
561
574
  /** Returns keys of all items. */
562
- itemsKeysByActivityId(activityId: string): Promise<string[]>;
575
+ itemsKeysByActivityPublishUuid(activityPublishUuid: string): Promise<string[]>;
563
576
  /** Determines if the key exists. */
564
577
  itemExists(key: string): Promise<boolean>;
565
578
  }
@@ -621,14 +634,20 @@ interface Activity {
621
634
  * @param options - options for the callback.
622
635
  */
623
636
  onData(callback: (activityResultsEvent: ActivityResultsEvent) => void, options?: CallbackOptions): void;
624
- /** The activity's parent session unique identifier. */
637
+ /** The activity's parent session unique identifier. This is newly generated each session. */
625
638
  sessionUuid: string;
626
- /** The activity's unique identifier. NOTE: This is newly generated each session. The uuid for an activity will vary across sessions. */
639
+ /** The activity's unique identifier. This is newly generated each session. The UUID for an activity will vary across sessions. */
627
640
  uuid: string;
628
641
  /** Human-friendly name of this activity */
629
642
  name: string;
630
643
  /** Short identifier of this activity */
631
644
  id: string;
645
+ /** Persistent unique identifier (UUID) of the activity. Required for games. Optional or empty string if a survey. */
646
+ publishUuid: string;
647
+ /** The ID of the study (protocol, experiment, or other aggregate) that contains the repeated administrations of this activity. The ID should be short, url-friendly, human-readable text (no spaces, special characters, or slashes), e.g., `nyc-aging-cohort`. */
648
+ studyId?: string;
649
+ /** Unique identifier (UUID) of the study (protocol, experiment, or other aggregate) that contains the administration of this activity. */
650
+ studyUuid?: string;
632
651
  /** The value of performance.now() immediately before the activity begins */
633
652
  beginTimestamp: number;
634
653
  /** The value of new Date().toISOString() immediately before the activity begins */
@@ -659,9 +678,13 @@ interface BrowserImage {
659
678
  /** URL of image asset (svg, png, jpg) to render and load */
660
679
  url?: string;
661
680
  /** If true, the image will not be fully loaded until it is needed. Default
662
- * is false. Lazy loading is useful for localized images or large "banks"
663
- * of images. These should be lazy loaded because they may not be needed. */
681
+ * is false. Lazy loading is useful for large "banks" of images. These should
682
+ * be lazy loaded because they may not be needed. */
664
683
  lazy?: boolean;
684
+ /** If true, try to use a localized version of the image. Localized images
685
+ * are loaded on demand and are not preloaded. Only an image whose asset
686
+ * is provided as a URL can be localized. Default is false. */
687
+ localize?: boolean;
665
688
  }
666
689
 
667
690
  /**
@@ -689,27 +712,6 @@ interface DefaultParameter extends JsonSchema {
689
712
  default: any;
690
713
  }
691
714
 
692
- /**
693
- * Translations is a map of a locale to a map of keys to translations.
694
- *
695
- * @example
696
- * ```
697
- * const translations: Translations = {
698
- * "en-US": {
699
- * "NEXT_BUTTON": "Next"
700
- * },
701
- * "es-MX": {
702
- * "NEXT_BUTTON": "Siguiente"
703
- * }
704
- * }
705
- * ```
706
- */
707
- interface Translations {
708
- [locale: string]: {
709
- [key: string]: string;
710
- };
711
- }
712
-
713
715
  /**
714
716
  * Font url and raw data that has been shared with other games in the session.
715
717
  *
@@ -754,14 +756,207 @@ interface ModuleMetadata {
754
756
  };
755
757
  }
756
758
 
759
+ interface SoundAsset {
760
+ /** Name of the sound to use when referring to it within m2c2kit, such as
761
+ * when creating a `SoundPlayer` node. */
762
+ soundName: string;
763
+ /** URL of sound to load */
764
+ url: string;
765
+ /** If true, the sound will not be fully loaded until it is needed. Default
766
+ * is false. Lazy loading is useful for sounds involved in localization.
767
+ * These should be lazy loaded because they may not be needed.
768
+ */
769
+ lazy?: boolean;
770
+ }
771
+
772
+ /**
773
+ * A map of a locale to a map of keys to translated text and font information.
774
+ *
775
+ * @remarks When it comes to fonts, the `Translation` object only specifies
776
+ * which fonts to use for text. The actual fonts must be provided as part of
777
+ * the `GameOptions` object with names that match the names specified in the
778
+ * `Translation` object.
779
+ *
780
+ * The below example defines a translation object for use in three locales:
781
+ * en-US, es-MX, and hi-IN.
782
+ *
783
+ * In the `configuration` object, the `baseLocale` property is en-US. This
784
+ * means that the en-US locale is the locale from which the "native"
785
+ * resources originate.
786
+ *
787
+ * The property `localeName` is human-readable text of the locale that can
788
+ * be displayed to the user. For example, `en-US` might have the locale name
789
+ * `English`. The property `localeSvg` is an image of the locale, as an SVG
790
+ * string and its height and width. This is so the locale can be displayed to
791
+ * the user if the locale uses a script that is not supported in the default
792
+ * font, and a locale-specific font is not yet loaded.
793
+ *
794
+ * For en-US and es-MX, the game's default font will be used for all text
795
+ * because the `fontName` property is not specified for these locales. For
796
+ * hi-IN, the `devanagari` font will be used for all text.
797
+ *
798
+ * `EMOJI_WELCOME` uses an emoji, and it will not display properly unless an
799
+ * `emoji` font is added. The `additionalFontName` property is used to
800
+ * specify an additional font or fonts to use as well as the locale's font.
801
+ * For en-US and es-MX, the `emoji` font plus the game's default font will be
802
+ * used for the `EMOJI_WELCOME` text. For hi-IN, the `emoji` font plus the
803
+ * `devanagari` font will be used for the `EMOJI_WELCOME` text.
804
+ *
805
+ * `OK_BUTTON` uses the game's default font for all locales. Because hi-IN
806
+ * specified a font name, the `overrideFontName` property with a value of
807
+ * `default` is used to specify that the game's default font should be used
808
+ * instead of the locale's font, devanagari.
809
+ *
810
+ * `BYE` uses interpolation. `{{name}}` is a placeholder that will be replaced,
811
+ * at runtime, with the value of the `name` key in the `options` object passed
812
+ * to the `t` or `tf` methods of the `I18n` object. If the placeholder is not
813
+ * found in `options`, an error will be thrown.
814
+ *
815
+ * @example
816
+ *
817
+ * ```
818
+ * const translation: Translation = {
819
+ * "configuration": {
820
+ * "baseLocale": "en-US"
821
+ * },
822
+ * "en-US": {
823
+ * localeName: "English",
824
+ * "NEXT_BUTTON": "Next"
825
+ * "EMOJI_WELCOME": {
826
+ * text: "👋 Hello",
827
+ * additionalFontName: ["emoji"]
828
+ * },
829
+ * "OK_BUTTON": "OK",
830
+ * "BYE": "Goodbye, {{name}}."
831
+ * },
832
+ * "es-MX": {
833
+ * localeName: "Español",
834
+ * "NEXT_BUTTON": "Siguiente"
835
+ * "EMOJI_WELCOME": {
836
+ * text: "👋 Hola",
837
+ * additionalFontName: ["emoji"]
838
+ * },
839
+ * "OK_BUTTON": "OK",
840
+ * "BYE": "Adiós, {{name}}."
841
+ * },
842
+ * "hi-IN": {
843
+ * localeName: "Hindi",
844
+ * localeSvg: {
845
+ * // from https://commons.wikimedia.org/wiki/File:Hindi.svg, not copyrighted
846
+ * // note: To save space, the next line is not the full, working SVG string from the above URL.
847
+ * svgString: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 304 168" xml:space="preserve"><path d="m45.223..."/></svg>`,
848
+ * height: 44,
849
+ * width: 80,
850
+ * },
851
+ * fontName: "devanagari",
852
+ * "NEXT_BUTTON": "अगला"
853
+ * "EMOJI_WELCOME": {
854
+ * text: "👋 नमस्कार",
855
+ * additionalFontName: ["emoji"]
856
+ * },
857
+ * "OK_BUTTON": {
858
+ * text: "OK",
859
+ * overrideFontName: "default"
860
+ * },
861
+ * "BYE": "अलविदा {{name}}."
862
+ * }
863
+ * }
864
+ *
865
+ * ...
866
+ *
867
+ * const nextButton = new Button({
868
+ * text: "NEXT_BUTTON"
869
+ * ...
870
+ * })
871
+ *
872
+ * const byeLabel = new Label({
873
+ * text: "BYE",
874
+ * interpolation: {
875
+ * name: "Alice"
876
+ * }
877
+ * ...
878
+ * }
879
+ * ```
880
+ */
881
+ type Translation = LocaleTranslationMap & {
882
+ configuration?: TranslationConfiguration;
883
+ };
884
+ interface TranslationConfiguration {
885
+ /** The locale from which translations and adaptations are made to adjust to different regions and languages. This is the locale from which the base or unlocalized resources originate. */
886
+ baseLocale: string;
887
+ }
888
+ interface LocaleSvg {
889
+ /** The HTML SVG tag, in string form, that will be rendered and loaded.
890
+ * Must begin with &#60;svg> and end with &#60;/svg> */
891
+ svgString: string;
892
+ /** Height to scale image to */
893
+ height: number;
894
+ /** Width to scale image to */
895
+ width: number;
896
+ }
897
+ type LocaleTranslationMap = {
898
+ [locale: string]: {
899
+ /** The font name or names to use for all text in the locale. If omitted,
900
+ * the game's default font will be used. */
901
+ fontName?: string | string[];
902
+ /** Human-readable text of the locale that can be displayed to the user. For example, `en-US` might have the locale name `English` */
903
+ localeName?: string;
904
+ /** Image of the locale, as an SVG string, that can be displayed to the user. Some locales, in their native script, might not be supported in the default font. For example, Hindi script cannot be displayed in Roboto font. It would be inefficient to load all the possible extra fonts simply to display the locale to the user. Thus, in lieu of a string, the locale can be displayed to the user as an SVG. Only if that locale is selected, the font supporting that locale will be loaded. */
905
+ localeSvg?: LocaleSvg;
906
+ } & {
907
+ /** The translated text or the translated text with custom font information. Note: `LocaleSvg` is included in the union only to satisfy TypeScript compiler. */
908
+ [key: string]: string | TextWithFontCustomization | LocaleSvg;
909
+ };
910
+ };
911
+ /**
912
+ * A translated string with custom font information to be applied only to this
913
+ * string.
914
+ */
915
+ interface TextWithFontCustomization {
916
+ /** The translated string. */
917
+ text: string;
918
+ /** Font name(s) to _add to_ the locale's font name(s) when displaying text. */
919
+ additionalFontName?: string | Array<string>;
920
+ /** Font name(s) to use _in place of_ the locale's font name(s) when
921
+ * displaying text. Use `default` to indicate that the game's default font
922
+ * should be used instead of the locale's font names(s) */
923
+ overrideFontName?: string | Array<string>;
924
+ }
925
+ interface TextAndFont {
926
+ /** The translated string. */
927
+ text?: string;
928
+ /** Font name to use when displaying the text. */
929
+ fontName?: string;
930
+ /** Font names to use when displaying the text. */
931
+ fontNames?: Array<string>;
932
+ }
933
+
934
+ /**
935
+ * Localization information that is passed to the I18n constructor.
936
+ */
937
+ interface LocalizationOptions {
938
+ /** Locale to use for localization when running the game, or "auto" to request from the environment. */
939
+ locale?: string;
940
+ /** Locale to use if requested locale translation is not available, or if "auto" locale was requested and environment cannot provide a locale. Default is `en-US`.*/
941
+ fallbackLocale?: string;
942
+ /** Font color for strings or outline color for images when a requested locale's translation or image is missing. This is useful in development to call attention to missing localization assets. */
943
+ missingLocalizationColor?: RgbaColor;
944
+ /** Translation for localization. */
945
+ translation?: Translation;
946
+ /** Additional translation for localization. This will typically be provided through `setParameters()` at runtime. This translation be merged into the existing translation and will overwrite any existing translation with the same key-value pairs. Thus, this can be used to modify an existing translation, either in whole or in part. */
947
+ additionalTranslation?: Translation;
948
+ }
949
+
757
950
  /**
758
951
  * Options to specify HTML canvas, set game canvas size, and load game assets.
759
952
  */
760
- interface GameOptions {
953
+ interface GameOptions extends LocalizationOptions {
761
954
  /** Human-friendly name of this game */
762
955
  name: string;
763
- /** Short identifier of this game; unique among published games and url-friendly (no spaces, special characters, or slashes)*/
956
+ /** Short identifier of this game; unique among published games and url-friendly (no spaces, special characters, or slashes). */
764
957
  id: string;
958
+ /** Persistent unique identifier (UUID) of this game; unique among published games. The m2c2kit CLI will generate this property automatically, and you should not change it. If not using the CLI, use a website like https://www.uuidgenerator.net/version4 to generate this value. */
959
+ publishUuid: string;
765
960
  /** Version of this game */
766
961
  version: string;
767
962
  /** Uri (repository, webpage, or other location where full information about the game can be found) */
@@ -786,6 +981,8 @@ interface GameOptions {
786
981
  fonts?: Array<FontAsset>;
787
982
  /** Array of BrowserImage objects to render and load */
788
983
  images?: Array<BrowserImage>;
984
+ /** Array of SoundAsset objects to fetch and decode */
985
+ sounds?: Array<SoundAsset>;
789
986
  /** Show FPS in upper left corner? Default is false */
790
987
  showFps?: boolean;
791
988
  /** Color of the html body, if the game does not fill the screen. Useful for showing scene boundaries. Default is the scene background color */
@@ -796,8 +993,6 @@ interface GameOptions {
796
993
  fpsMetricReportThreshold?: number;
797
994
  /** Advance through time step-by-step, for development and debugging */
798
995
  timeStepping?: boolean;
799
- /** Translations for localization. */
800
- translations?: Translations;
801
996
  /** Show logs for WebGl activity? */
802
997
  logWebGl?: boolean;
803
998
  /** Should games within a session share wasm and font assets that have identical filenames, in order to reduce bandwidth? Default is true. */
@@ -810,35 +1005,103 @@ interface GameData extends ActivityKeyValueData {
810
1005
  trials: Array<TrialData>;
811
1006
  }
812
1007
 
813
- /**
814
- * Localization information that is passed to the I18n constructor.
815
- */
816
- interface LocalizationOptions {
817
- /** Locale to use for localization, or "auto" to request from the environment. */
818
- locale: string;
819
- /** Locale to use if requested locale translation is not available, or if "auto" locale was requested and environment cannot provide a locale. */
820
- fallbackLocale?: string;
821
- /** Font color for strings that are missing translation and use the fallback locale or untranslated string. */
822
- missingTranslationFontColor?: RgbaColor;
823
- /** Translations for localization. */
824
- translations?: Translations;
825
- /** Additional translations for localization provided through game parameters. These will be merged into existing translations. */
826
- additionalTranslations?: Translations;
1008
+ interface TranslationOptions {
1009
+ [key: string]: unknown;
1010
+ }
1011
+ interface TextLocalizationResult {
1012
+ text: string;
1013
+ fontName?: string;
1014
+ fontNames?: string[];
1015
+ isFallbackOrMissingTranslation: boolean;
827
1016
  }
828
-
829
1017
  declare class I18n {
830
- private _translations;
1018
+ private _translation;
831
1019
  locale: string;
832
1020
  fallbackLocale: string;
833
- private environmentLocale;
834
- options: LocalizationOptions;
835
- static makeLocalizationParameters(): GameParameters;
836
- constructor(options: LocalizationOptions);
837
- t(key: string, useFallback?: boolean): string | undefined;
838
- get translations(): Translations;
839
- set translations(value: Translations);
1021
+ baseLocale: string;
1022
+ missingLocalizationColor: RgbaColor | undefined;
1023
+ game: Game;
1024
+ /**
1025
+ * The I18n class localizes text and images.
1026
+ *
1027
+ * @param game - game instance
1028
+ * @param options - {@link LocalizationOptions}
1029
+ */
1030
+ constructor(game: Game, options: LocalizationOptions);
1031
+ /**
1032
+ * Initializes the I18n instance and sets the initial locale.
1033
+ *
1034
+ * @remarks If the game instance has been configured to use a data store,
1035
+ * the previously used locale and fallback locale will be retrieved from the
1036
+ * data store if they have been previously set.
1037
+ */
1038
+ initialize(): Promise<void>;
1039
+ private configureInitialLocale;
1040
+ private localeTranslationAvailable;
1041
+ switchToLocale(locale: string): void;
1042
+ /**
1043
+ *
1044
+ * @param key - Translation key
1045
+ * @param interpolation - Interpolation keys and values to replace
1046
+ * placeholders in the translated text
1047
+ * @returns a `TextLocalizationResult` object with the localized text, font
1048
+ * information, and whether the translation is a fallback.
1049
+ */
1050
+ getTextLocalization(key: string, interpolation?: StringInterpolationMap): TextLocalizationResult;
1051
+ /**
1052
+ * Returns the translation text for the given key in the current locale.
1053
+ *
1054
+ * @remarks Optional interpolation keys and values can be provided to replace
1055
+ * placeholders in the translated text. Placeholders are denoted by double
1056
+ * curly braces.
1057
+ *
1058
+ * @param key - key to look up in the translation
1059
+ * @param options - `TranslationOptions`, such as interpolation keys/values
1060
+ * and whether to translate using the fallback locale
1061
+ * @returns the translation text for the key in the current locale, or
1062
+ * undefined if the key is not found
1063
+ *
1064
+ * @example
1065
+ *
1066
+ * ```
1067
+ * const translation: Translation = {
1068
+ * "en-US": {
1069
+ * "GREETING": "Hello, {{name}}."
1070
+ * }
1071
+ * }
1072
+ * ...
1073
+ * i18n.t("GREETING", { name: "World" }); // returns "Hello, World."
1074
+ *
1075
+ * ```
1076
+ */
1077
+ t(key: string, options?: TranslationOptions): string | undefined;
1078
+ /**
1079
+ * Returns the translation text and font information for the given key in the
1080
+ * current locale.
1081
+ *
1082
+ * @remarks Optional interpolation keys and values can be provided to replace
1083
+ * placeholders in the translated text. Placeholders are denoted by double
1084
+ * curly braces. See method {@link I18n.t()} for interpolation example.
1085
+ *
1086
+ * @param key - key to look up in the translation
1087
+ * @param options - `TranslationOptions`, such as interpolation keys/values
1088
+ * and whether to translate using the fallback locale
1089
+ * @returns the translation text and font information for the key in the
1090
+ * current locale, or undefined if the key is not found
1091
+ */
1092
+ tf(key: string, options?: TranslationOptions): TextAndFont | undefined;
1093
+ private getKeyText;
1094
+ private getKeyTextAndFont;
1095
+ private insertInterpolations;
1096
+ get translation(): Translation;
1097
+ set translation(value: Translation);
840
1098
  private getEnvironmentLocale;
841
- private mergeAdditionalTranslations;
1099
+ private mergeAdditionalTranslation;
1100
+ static makeLocalizationParameters(): GameParameters;
1101
+ private isTextWithFontCustomization;
1102
+ private isStringOrTextWithFontCustomization;
1103
+ private isStringArray;
1104
+ private isString;
842
1105
  }
843
1106
 
844
1107
  /**
@@ -995,13 +1258,26 @@ declare class FontManager {
995
1258
  * additional properties.
996
1259
  */
997
1260
  interface M2Image {
1261
+ /** Name of the image, as it will be referred to when creating a sprite. */
998
1262
  imageName: string;
1263
+ /** The image in CanvasKit format. */
999
1264
  canvaskitImage: Image | undefined;
1000
1265
  width: number;
1001
1266
  height: number;
1267
+ /** Status of the image: Deferred, Loading, Ready, or Error. */
1002
1268
  status: M2ImageStatus;
1269
+ /** For an image that will be fetched, this is the URL that will be attempted. This may have localization applied. */
1003
1270
  url?: string;
1271
+ /** Is this image a fallback localized image? */
1272
+ isFallback: boolean;
1273
+ /** For an image that will be fetched, the original URL before any localization. */
1274
+ originalUrl?: string;
1275
+ /** For a localized image that will be fetched, additional URLs to try if the URL in `url` fails. */
1276
+ fallbackLocalizationUrls?: Array<string>;
1277
+ /** An image defined by an SVG string. */
1004
1278
  svgString?: string;
1279
+ /** Try to localize the image by fetching a locale-specific image? Default is false. */
1280
+ localize: boolean;
1005
1281
  }
1006
1282
  declare const M2ImageStatus: {
1007
1283
  /** Image was set for lazy loading, and loading has not yet been requested. */
@@ -1026,6 +1302,7 @@ declare class ImageManager {
1026
1302
  private scale?;
1027
1303
  private game;
1028
1304
  private baseUrls;
1305
+ missingLocalizationImagePaint?: Paint;
1029
1306
  constructor(game: Game, baseUrls: GameBaseUrls);
1030
1307
  /**
1031
1308
  * Loads image assets and makes them ready to use during the game initialization.
@@ -1051,6 +1328,25 @@ declare class ImageManager {
1051
1328
  * @returns A promise that completes when all images have loaded
1052
1329
  */
1053
1330
  loadImages(browserImages: Array<BrowserImage>): Promise<void>;
1331
+ private configureImageLocalization;
1332
+ /**
1333
+ * Localizes the image URL by appending the locale to the image URL,
1334
+ * immediately before the file extension.
1335
+ *
1336
+ * @remarks For example, `https://url.com/file.png` in en-US locale
1337
+ * becomes `https://url.com/file.en-US.png`. A URL without an extension
1338
+ * will throw an error.
1339
+ *
1340
+ * @param url - url of the image
1341
+ * @param locale - locale in format of xx-YY, where xx is the language code
1342
+ * and YY is the country code
1343
+ * @returns localized url
1344
+ */
1345
+ private localizeImageUrl;
1346
+ /**
1347
+ * Sets an image to be re-rendered within the current locale.
1348
+ */
1349
+ reinitializeLocalizedImages(): void;
1054
1350
  private checkImageNamesForDuplicates;
1055
1351
  /**
1056
1352
  * Makes ready to the game a m2c2kit image ({@link M2Image}) that was
@@ -1113,6 +1409,142 @@ declare class ImageManager {
1113
1409
  private removeScratchCanvas;
1114
1410
  }
1115
1411
 
1412
+ interface M2Sound {
1413
+ soundName: string;
1414
+ data: ArrayBuffer | undefined;
1415
+ audioBuffer: AudioBuffer | undefined;
1416
+ url: string;
1417
+ status: M2SoundStatus;
1418
+ }
1419
+ declare const M2SoundStatus: {
1420
+ /** Sound was set for lazy loading, and loading has not yet been requested. */
1421
+ readonly Deferred: "Deferred";
1422
+ /** Sound is indicated for fetching, but fetching has not begun. */
1423
+ readonly WillFetch: "WillFetch";
1424
+ /** Sound is being fetched. */
1425
+ readonly Fetching: "Fetching";
1426
+ /** Sound has been fetched. */
1427
+ readonly Fetched: "Fetched";
1428
+ /** Sound is being decoded. */
1429
+ readonly Decoding: "Decoding";
1430
+ /** Sound has fully finished loading and is ready to use. */
1431
+ readonly Ready: "Ready";
1432
+ /** Error occurred in loading. */
1433
+ readonly Error: "Error";
1434
+ };
1435
+ type M2SoundStatus = (typeof M2SoundStatus)[keyof typeof M2SoundStatus];
1436
+
1437
+ /**
1438
+ * Fetches, loads, and provides sounds to the game.
1439
+ *
1440
+ * @internal For m2c2kit library use only
1441
+ */
1442
+ declare class SoundManager {
1443
+ private sounds;
1444
+ private game;
1445
+ private baseUrls;
1446
+ private _audioContext?;
1447
+ constructor(game: Game, baseUrls: GameBaseUrls);
1448
+ get audioContext(): AudioContext;
1449
+ /**
1450
+ * Loads sound assets during the game initialization.
1451
+ *
1452
+ * @internal For m2c2kit library use only
1453
+ *
1454
+ * @remarks Typically, a user won't call this because the m2c2kit
1455
+ * framework will call this automatically. At initialization, sounds can
1456
+ * only be fetched, not decoded because the AudioContext can not yet
1457
+ * be created (it requires a user interaction).
1458
+ *
1459
+ * @param soundAssets - array of SoundAsset objects
1460
+ */
1461
+ initializeSounds(soundAssets: Array<SoundAsset> | undefined): Promise<void>;
1462
+ /**
1463
+ * Loads an array of sound assets and makes them ready for the game.
1464
+ *
1465
+ * @remarks Loading a sound consists of 1) fetching the sound file and 2)
1466
+ * decoding the sound data. The sound is then ready to be played. Step 1
1467
+ * can be done at any time, but step 2 requires an `AudioContext`, which
1468
+ * can only be created after a user interaction. If a play `Action` is
1469
+ * attempted before the sound is ready (either it has not been fetched or
1470
+ * decoded), the play `Action` will log a warning to the console and the
1471
+ * loading process will continue in the background, and the sound will play
1472
+ * when ready. This `loadSounds()` method **does not** have to be awaited.
1473
+ *
1474
+ * @param soundAssets - an array of {@link SoundAsset}
1475
+ * @returns A promise that completes when all sounds have loaded
1476
+ */
1477
+ loadSounds(soundAssets: Array<SoundAsset>): Promise<void>;
1478
+ private fetchSounds;
1479
+ /**
1480
+ * Fetches a m2c2kit sound ({@link M2Sound}) that was previously
1481
+ * initialized with lazy loading.
1482
+ *
1483
+ * @internal For m2c2kit library use only
1484
+ *
1485
+ * @param m2Sound - M2Sound to fetch
1486
+ * @returns A promise that completes when sounds have been fetched
1487
+ */
1488
+ fetchDeferredSound(m2Sound: M2Sound): Promise<void>;
1489
+ /**
1490
+ * Checks if the SoundManager has sounds needing decoding.
1491
+ *
1492
+ * @internal For m2c2kit library use only
1493
+ *
1494
+ * @returns true if there are sounds that have been fetched and are waiting
1495
+ * to be decoded (status is `M2SoundStatus.Fetched`)
1496
+ */
1497
+ hasSoundsToDecode(): boolean;
1498
+ /**
1499
+ * Decodes all fetched sounds from bytes to an `AudioBuffer`.
1500
+ *
1501
+ * @internal For m2c2kit library use only
1502
+ *
1503
+ * @remarks This method will be called after the `AudioContext` has been
1504
+ * created and if there are fetched sounds waiting to be decoded.
1505
+ *
1506
+ * @returns A promise that completes when all fetched sounds have been decoded
1507
+ */
1508
+ decodeFetchedSounds(): Promise<void[]>;
1509
+ /**
1510
+ * Decodes a sound from bytes to an `AudioBuffer`.
1511
+ *
1512
+ * @param sound - sound to decode
1513
+ */
1514
+ private decodeSound;
1515
+ /**
1516
+ * Returns a m2c2kit sound ({@link M2Sound}) that has been entered into the
1517
+ * SoundManager.
1518
+ *
1519
+ * @internal For m2c2kit library use only
1520
+ *
1521
+ * @remarks Typically, a user won't need to call this because sound
1522
+ * initialization and processing is handled by the framework.
1523
+ *
1524
+ * @param soundName - sound's name as defined in the game's sound assets
1525
+ * @returns a m2c2kit sound
1526
+ */
1527
+ getSound(soundName: string): M2Sound;
1528
+ /**
1529
+ * Frees up resources allocated by the SoundManager.
1530
+ *
1531
+ * @internal For m2c2kit library use only
1532
+ *
1533
+ * @remarks This will be done automatically by the m2c2kit library; the
1534
+ * end-user must not call this.
1535
+ */
1536
+ dispose(): void;
1537
+ /**
1538
+ * Gets names of sounds entered in the `SoundManager`.
1539
+ *
1540
+ * @remarks These are sounds that the `SoundManager` is aware of. The sounds
1541
+ * may not be ready to play (may not have been fetched or decoded yet).
1542
+ *
1543
+ * @returns array of sound names
1544
+ */
1545
+ getSoundNames(): Array<string>;
1546
+ }
1547
+
1116
1548
  /** Key value pairs of file URLs and hashed file URLs */
1117
1549
  type Manifest = {
1118
1550
  [originalUrl: string]: string;
@@ -1133,6 +1565,9 @@ declare class Game implements Activity {
1133
1565
  uuid: string;
1134
1566
  name: string;
1135
1567
  id: string;
1568
+ publishUuid: string;
1569
+ studyId?: string;
1570
+ studyUuid?: string;
1136
1571
  moduleMetadata: ModuleMetadata;
1137
1572
  readonly canvasKitWasmVersion = "__CANVASKITWASM_VERSION__";
1138
1573
  options: GameOptions;
@@ -1155,6 +1590,7 @@ declare class Game implements Activity {
1155
1590
  };
1156
1591
  private _fontManager?;
1157
1592
  private _imageManager?;
1593
+ private _soundManager?;
1158
1594
  manifest?: Manifest;
1159
1595
  /**
1160
1596
  * The base class for all games. New games should extend this class.
@@ -1205,6 +1641,22 @@ declare class Game implements Activity {
1205
1641
  set fontManager(fontManager: FontManager);
1206
1642
  get imageManager(): ImageManager;
1207
1643
  set imageManager(imageManager: ImageManager);
1644
+ get soundManager(): SoundManager;
1645
+ set soundManager(soundManager: SoundManager);
1646
+ /**
1647
+ * Adds prefixes to a key to ensure that keys are unique across activities
1648
+ * and studies.
1649
+ *
1650
+ * @remarks When a value is saved to the key-value data store, the key must
1651
+ * be prefixed with additional information to ensure that keys are unique.
1652
+ * The prefixes will include the activity id and publish UUID, and possibly
1653
+ * the study id and study UUID, if they are set (this is so that keys are
1654
+ * unique across different studies that might use the same activity).
1655
+ *
1656
+ * @param key - item key to add prefixes to
1657
+ * @returns the item key with prefixes added
1658
+ */
1659
+ private addPrefixesToKey;
1208
1660
  /**
1209
1661
  * Saves an item to the activity's key-value store.
1210
1662
  *
@@ -1308,6 +1760,7 @@ declare class Game implements Activity {
1308
1760
  storeItemExists(key: string, globalStore?: boolean): Promise<boolean>;
1309
1761
  get dataStores(): IDataStore[];
1310
1762
  set dataStores(dataStores: IDataStore[]);
1763
+ hasDataStores(): boolean;
1311
1764
  private getLocalizationOptionsFromGameParameters;
1312
1765
  private isLocalizationRequested;
1313
1766
  setParameters(additionalParameters: unknown): void;
@@ -1627,7 +2080,23 @@ declare class Game implements Activity {
1627
2080
  * @param plugin - Plugin to register
1628
2081
  */
1629
2082
  registerPlugin(plugin: Plugin): Promise<void>;
2083
+ /**
2084
+ * Updates active scenes and executes plugins.
2085
+ *
2086
+ */
1630
2087
  private update;
2088
+ /**
2089
+ * Updates all active scenes and their children.
2090
+ */
2091
+ private updateScenes;
2092
+ /**
2093
+ * Executes all active plugins before scenes are updated.
2094
+ */
2095
+ private executeBeforeUpdatePlugins;
2096
+ /**
2097
+ * Executes all active plugins after scenes have been updated.
2098
+ */
2099
+ private executeAfterUpdatePlugins;
1631
2100
  private draw;
1632
2101
  private calculateFps;
1633
2102
  private takeCurrentSceneSnapshot;
@@ -1789,7 +2258,7 @@ declare abstract class M2Node implements M2NodeOptions {
1789
2258
  _scale: number;
1790
2259
  alpha: number;
1791
2260
  _zRotation: number;
1792
- isUserInteractionEnabled: boolean;
2261
+ protected _isUserInteractionEnabled: boolean;
1793
2262
  draggable: boolean;
1794
2263
  hidden: boolean;
1795
2264
  layout: Layout;
@@ -1803,7 +2272,6 @@ declare abstract class M2Node implements M2NodeOptions {
1803
2272
  absoluteAlphaChange: number;
1804
2273
  actions: Action[];
1805
2274
  queuedAction?: Action;
1806
- originalActions: Action[];
1807
2275
  eventListeners: M2NodeEventListener<M2NodeEvent>[];
1808
2276
  readonly uuid: string;
1809
2277
  needsInitialization: boolean;
@@ -2092,6 +2560,8 @@ declare abstract class M2Node implements M2NodeOptions {
2092
2560
  set zRotation(zRotation: number);
2093
2561
  get scale(): number;
2094
2562
  set scale(scale: number);
2563
+ get isUserInteractionEnabled(): boolean;
2564
+ set isUserInteractionEnabled(isUserInteractionEnabled: boolean);
2095
2565
  /**
2096
2566
  * For a given directed acyclic graph, topological ordering of the vertices will be identified using BFS
2097
2567
  * @param adjList Adjacency List that represent a graph with vertices and edges
@@ -2155,8 +2625,27 @@ interface RotateActionOptions {
2155
2625
  runDuringTransition?: boolean;
2156
2626
  }
2157
2627
 
2158
- interface IActionContainer {
2159
- children?: Array<Action>;
2628
+ interface PlayActionOptions {
2629
+ /** Should the action run during screen transitions? Default is no */
2630
+ runDuringTransition?: boolean;
2631
+ }
2632
+
2633
+ /**
2634
+ * An ActionContainer is an Action that can contain other actions.
2635
+ *
2636
+ * @remarks An ActionContainer is a parent action that can have other
2637
+ * actions as children. The `Sequence`, `Group`, `Repeat,` and
2638
+ * `RepeatForever` actions implement `ActionContainer`.
2639
+ */
2640
+ interface ActionContainer extends Action {
2641
+ /**
2642
+ * Immediate children of a parent action.
2643
+ */
2644
+ children: Array<Action>;
2645
+ /**
2646
+ * All children of a parent action and those children's children, recursively.
2647
+ */
2648
+ descendants: Array<Action>;
2160
2649
  }
2161
2650
 
2162
2651
  /** The type of action */
@@ -2168,7 +2657,140 @@ declare enum ActionType {
2168
2657
  Move = "Move",
2169
2658
  Scale = "Scale",
2170
2659
  FadeAlpha = "FadeAlpha",
2171
- Rotate = "Rotate"
2660
+ Rotate = "Rotate",
2661
+ Play = "Play",
2662
+ Repeat = "Repeat",
2663
+ RepeatForever = "RepeatForever"
2664
+ }
2665
+
2666
+ /**
2667
+ * A class for for working with numeric values that may be currently unknown,
2668
+ * but may be known in the future.
2669
+ *
2670
+ * @remarks Most m2c2kit actions have a known duration, such as waiting for a
2671
+ * given duration or moving a node to a specific position across a specific
2672
+ * duration: the duration is explicitly provided when the `Action` is created.
2673
+ * However, some actions have a duration that is not known when the `Action` is
2674
+ * created, but it will be known in the future. So far, the only action that
2675
+ * requires this is the `play` action. In the browser, a sound file cannot be
2676
+ * decoded by the `AudioContext` interface (which will calculate the duration)
2677
+ * until the user has interacted with the page, which could be after the
2678
+ * `Action` has been created. This is a problem because a `sequence` action
2679
+ * needs to know the duration of all its children in order to calculate its own
2680
+ * duration and when each of the child actions will start. To solve this
2681
+ * problem, the `Futurable` class is a simple implementation of the Composite
2682
+ * pattern that allows for the creation of a numeric value that may be known in
2683
+ * the future. If a value is not known at creation time, it is represented by
2684
+ * `Infinity`. The `Futurable` class supports addition and subtraction of
2685
+ * another `Futurable` and numbers. When the numeric value of a `Futurable` is
2686
+ * requested, it evaluates the expression and returns the numeric value. If any
2687
+ * of the terms in the expression is a `Futurable`, it will recursively
2688
+ * evaluate them. If any of the terms are unknown (represented by `Infinity`),
2689
+ * it will return `Infinity`. If a previous unknown value becomes known, any
2690
+ * other `Futurable` that depends on it will also become known.
2691
+ */
2692
+ declare class Futurable {
2693
+ /** The numbers, operators, and other Futurables that represent a value. */
2694
+ private expression;
2695
+ /** Log a warning to console if a expression is this length. */
2696
+ private readonly WARNING_EXPRESSION_LENGTH;
2697
+ constructor(value?: Futurable | number);
2698
+ /**
2699
+ * Appends a number or another Futurable to this Futurable's expression.
2700
+ *
2701
+ * @remarks This method does a simple array push, but checks the length of
2702
+ * the expression array and warns if it gets "too long." This may indicate
2703
+ * a logic error, unintended recursion, etc. because our use cases will
2704
+ * likely not have expressions that are longer than
2705
+ * `Futural.WARNING_EXPRESSION_LENGTH` elements.
2706
+ *
2707
+ * @param value - value to add to the expression.
2708
+ */
2709
+ private pushToExpression;
2710
+ /**
2711
+ * Assigns a value, either known or Futurable, to this Futurable.
2712
+ *
2713
+ * @remarks This method clears the current expression.
2714
+ *
2715
+ * @param value - value to assign to this Futurable.
2716
+ */
2717
+ assign(value: number | Futurable): void;
2718
+ /**
2719
+ * Performs addition on this Futurable.
2720
+ *
2721
+ * @remarks This method modifies the Futurable by adding the term(s) to the
2722
+ * Futurable's expression.
2723
+ *
2724
+ * @param terms - terms to add to this Futurable.
2725
+ * @returns the modified Futurable.
2726
+ */
2727
+ add(...terms: Array<Futurable | number>): this;
2728
+ /**
2729
+ * Performs subtraction on this Futurable.
2730
+ *
2731
+ * @remarks This method modifies the Futurable by subtracting the term(s)
2732
+ * from the Futurable's expression.
2733
+ *
2734
+ * @param terms - terms to subtract from this Futurable.
2735
+ * @returns the modified Futurable.
2736
+ */
2737
+ subtract(...terms: Array<Futurable | number>): this;
2738
+ /**
2739
+ * Adds an operation (an operator and term(s)) to the Futurable's
2740
+ * expression.
2741
+ *
2742
+ * @param operator - Add or Subtract.
2743
+ * @param terms - terms to add to the expression.
2744
+ */
2745
+ private appendOperation;
2746
+ /**
2747
+ * Gets the numeric value of this Futurable.
2748
+ *
2749
+ * @remarks This method evaluates the expression of the Futurable and
2750
+ * returns the numeric value. If any of the terms in the expression are
2751
+ * Futurables, it will recursively evaluate them. If any of the terms are
2752
+ * unknown (represented by Infinity), it will return Infinity.
2753
+ *
2754
+ * @returns the numeric value of this Futurable.
2755
+ */
2756
+ get value(): number;
2757
+ }
2758
+
2759
+ /**
2760
+ * An extension of `ActionContainer` that can repeat another action.
2761
+ *
2762
+ * @remarks A `RepeatingActionContainer` is a parent action that repeats
2763
+ * another action for a specified number of repetitions, as provided in the
2764
+ * `count` property. The `Repeat` and `RepeatForever` actions implement
2765
+ * `RepeatingActionContainer`.
2766
+ */
2767
+ interface RepeatingActionContainer extends ActionContainer {
2768
+ /** Number of times the action will repeat. */
2769
+ count: number;
2770
+ /** Number of completions done. */
2771
+ completedRepetitions: number;
2772
+ /** How long, in milliseconds, the repeating action has run. This is updated
2773
+ * only at the end of a repetition. */
2774
+ cumulativeDuration: number;
2775
+ /** Returns true when the action is running and the action's children have
2776
+ * just completed a repetition */
2777
+ repetitionHasCompleted: boolean;
2778
+ }
2779
+
2780
+ interface RepeatActionOptions {
2781
+ /** Action to repeat */
2782
+ action: Action;
2783
+ /** Number of times to repeat the action */
2784
+ count: number;
2785
+ /** Should the action run during screen transitions? Default is no */
2786
+ runDuringTransition?: boolean;
2787
+ }
2788
+
2789
+ interface RepeatForeverActionOptions {
2790
+ /** Action to repeat */
2791
+ action: Action;
2792
+ /** Should the action run during screen transitions? Default is no */
2793
+ runDuringTransition?: boolean;
2172
2794
  }
2173
2795
 
2174
2796
  /**
@@ -2177,151 +2799,362 @@ declare enum ActionType {
2177
2799
  */
2178
2800
  declare abstract class Action {
2179
2801
  abstract type: ActionType;
2180
- startOffset: number;
2181
- endOffset: number;
2802
+ startOffset: Futurable;
2182
2803
  started: boolean;
2183
2804
  running: boolean;
2184
- completed: boolean;
2805
+ private _completed;
2806
+ /**
2807
+ * Start time of a running action is always known; it is not a `Futurable`.
2808
+ * -1 indicates that the root action has not yet started running.
2809
+ */
2185
2810
  runStartTime: number;
2186
- duration: number;
2811
+ duration: Futurable;
2187
2812
  runDuringTransition: boolean;
2188
- parent?: Action;
2189
- isParent: boolean;
2190
- isChild: boolean;
2813
+ parent?: ActionContainer;
2191
2814
  key?: string;
2192
2815
  constructor(runDuringTransition?: boolean);
2816
+ /**
2817
+ * Prepares the Action for evaluation.
2818
+ *
2819
+ * @remarks Calculates start times for all actions in the hierarchy
2820
+ * and returns a copy of the action that is prepared for evaluation during
2821
+ * the update loop.
2822
+ *
2823
+ * @param key - optional string to identify an action
2824
+ * @returns action prepared for evaluation
2825
+ */
2826
+ initialize(key?: string): Action;
2827
+ /**
2828
+ * Clones the action, and any actions it contains, recursively.
2829
+ *
2830
+ * @remarks We need to clone an action before running it because actions
2831
+ * have state that is updated over time such as whether they are running or
2832
+ * not, etc. If we didn't clone actions, two nodes reusing the same action
2833
+ * would share state. On `Action`, this method is abstract and is
2834
+ * implemented in each subclass.
2835
+ *
2836
+ * @returns a clone of the action
2837
+ */
2838
+ abstract clone(): Action;
2839
+ /**
2840
+ * Parses the action hierarchy and assigns each action its parent and
2841
+ * root action.
2842
+ *
2843
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
2844
+ * actions within parent actions. When this method is called from the
2845
+ * `initialize()` method, the root action is both the `action` and the
2846
+ * `rootAction`. This is because the action is the top-level action in the
2847
+ * hierarchy. When the method calls itself recursively, the `rootAction`
2848
+ * remains the same, but the `action` is a child action or the action of a
2849
+ * repeating action.
2850
+ *
2851
+ * @param action - the action to assign parents to
2852
+ * @param rootAction - top-level action passed to the run method
2853
+ * @param key - optional string to identify an action. The key is assigned
2854
+ * to every action in the hierarchy.
2855
+ */
2856
+ private assignParents;
2857
+ /**
2858
+ * Sets the runDuringTransition property based on descendants.
2859
+ *
2860
+ * @remarks This ensures that a parent action has its `runDuringTransition`
2861
+ * property set to true if any of its descendants have their
2862
+ * `runDuringTransition` property set to true. Parent actions do not have a
2863
+ * way for the user to set this property directly; it is inferred (propagated
2864
+ * up) from the descendants.
2865
+ *
2866
+ * @param action to propagate runDuringTransition property to
2867
+ */
2868
+ private propagateRunDuringTransition;
2869
+ /**
2870
+ * Assigns durations to all actions in the hierarchy.
2871
+ *
2872
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
2873
+ * actions within parent actions.
2874
+ *
2875
+ * @param action - the action to assign durations to
2876
+ */
2877
+ private assignDurations;
2878
+ /**
2879
+ * Calculates the duration of an action, including any children actions
2880
+ * the action may contain.
2881
+ *
2882
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
2883
+ * actions within parent actions
2884
+ *
2885
+ * @param action
2886
+ * @returns the calculated duration
2887
+ */
2888
+ private calculateDuration;
2889
+ /**
2890
+ * Assigns start offsets to all actions in the hierarchy.
2891
+ *
2892
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
2893
+ * actions within parent actions.
2894
+ *
2895
+ * @param action - the action to assign start offsets to
2896
+ */
2897
+ private assignStartOffsets;
2898
+ /**
2899
+ * Calculates the start offset. This is when an action should start,
2900
+ * relative to the start time of its parent (if it has a parent).
2901
+ *
2902
+ * @param action - the action to calculate the start offset for
2903
+ * @returns the start offset as a Futurable
2904
+ */
2905
+ private calculateStartOffset;
2906
+ /**
2907
+ * Evaluates an action, updating the node's properties as needed.
2908
+ *
2909
+ * @remarks This method is called every frame by the M2Node's `update()`
2910
+ * method.
2911
+ *
2912
+ * @param action - the Action to be evaluated and possibly run
2913
+ * @param node - the `M2Node` that the action will be run on
2914
+ * @param now - the current elapsed time, from `performance.now()`
2915
+ * @param dt - the time since the last frame (delta time)
2916
+ */
2917
+ static evaluateAction(action: Action, node: M2Node, now: number, dt: number): void;
2918
+ private static evaluateRepeatingActions;
2919
+ private static evaluateRotateAction;
2920
+ private static evaluateFadeAlphaAction;
2921
+ private static evaluateScaleAction;
2922
+ private static evaluateMoveAction;
2923
+ private static evaluateWaitAction;
2924
+ private static evaluatePlayAction;
2925
+ private static evaluateCustomAction;
2926
+ /**
2927
+ * Assigns RunStartTime to all actions in the hierarchy.
2928
+ *
2929
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
2930
+ * actions within parent actions.
2931
+ *
2932
+ * @param action - the action to assign RunStartTime to
2933
+ */
2934
+ assignRunStartTimes(action: Action, runStartTime: number): void;
2935
+ /**
2936
+ * Configures action to be run again.
2937
+ *
2938
+ * @remarks This method is called on a repeating action's children when they
2939
+ * need to be run again.
2940
+ *
2941
+ * @param action - action to restart
2942
+ * @param now - current time
2943
+ */
2944
+ restartAction(action: Action, now: number): void;
2945
+ /**
2946
+ * Determines if the action should be running.
2947
+ *
2948
+ * @remarks An action should be running if current time is in the interval
2949
+ * [ start time + start offset, start time + start offset + duration ]
2950
+ *
2951
+ * @param now - current time
2952
+ * @returns true if the action should be running
2953
+ */
2954
+ shouldBeRunning(now: number): boolean;
2193
2955
  /**
2194
2956
  * Creates an action that will move a node to a point on the screen.
2195
2957
  *
2196
2958
  * @param options - {@link MoveActionOptions}
2197
2959
  * @returns The move action
2198
2960
  */
2199
- static move(options: MoveActionOptions): Action;
2961
+ static move(options: MoveActionOptions): MoveAction;
2200
2962
  /**
2201
- * Creates an action that will wait a given duration before it is considered complete.
2963
+ * Creates an action that will wait a given duration before it is considered
2964
+ * complete.
2202
2965
  *
2203
2966
  * @param options - {@link WaitActionOptions}
2204
2967
  * @returns The wait action
2205
2968
  */
2206
- static wait(options: WaitActionOptions): Action;
2969
+ static wait(options: WaitActionOptions): WaitAction;
2207
2970
  /**
2208
2971
  * Creates an action that will execute a callback function.
2209
2972
  *
2210
2973
  * @param options - {@link CustomActionOptions}
2211
2974
  * @returns The custom action
2212
2975
  */
2213
- static custom(options: CustomActionOptions): Action;
2976
+ static custom(options: CustomActionOptions): CustomAction;
2977
+ /**
2978
+ * Creates an action that will play a sound.
2979
+ *
2980
+ * @remarks This action can only be used with a SoundPlayer node.
2981
+ * It will throw an error if used with any other node type.
2982
+ *
2983
+ * @param options - {@link PlayActionOptions}
2984
+ * @returns The play action
2985
+ */
2986
+ static play(options?: PlayActionOptions): PlayAction;
2214
2987
  /**
2215
2988
  * Creates an action that will scale the node's size.
2216
2989
  *
2217
- * @remarks Scaling is relative to any inherited scaling, which is multiplicative. For example, if the node's parent is scaled to 2.0 and this node's action scales to 3.0, then the node will appear 6 times as large as original.
2990
+ * @remarks Scaling is relative to any inherited scaling, which is
2991
+ * multiplicative. For example, if the node's parent is scaled to 2.0 and
2992
+ * this node's action scales to 3.0, then the node will appear 6 times as
2993
+ * large as original.
2218
2994
  *
2219
2995
  * @param options - {@link ScaleActionOptions}
2220
2996
  * @returns The scale action
2221
2997
  */
2222
- static scale(options: ScaleActionOptions): Action;
2998
+ static scale(options: ScaleActionOptions): ScaleAction;
2223
2999
  /**
2224
3000
  * Creates an action that will change the node's alpha (opacity).
2225
3001
  *
2226
- * @remarks Alpha has multiplicative inheritance. For example, if the node's parent is alpha .5 and this node's action fades alpha to .4, then the node will appear with alpha .2.
3002
+ * @remarks Alpha has multiplicative inheritance. For example, if the node's
3003
+ * parent is alpha .5 and this node's action fades alpha to .4, then the
3004
+ * node will appear with alpha .2.
2227
3005
  *
2228
3006
  * @param options - {@link FadeAlphaActionOptions}
2229
3007
  * @returns The fadeAlpha action
2230
3008
  */
2231
- static fadeAlpha(options: FadeAlphaActionOptions): Action;
3009
+ static fadeAlpha(options: FadeAlphaActionOptions): FadeAlphaAction;
2232
3010
  /**
2233
3011
  * Creates an action that will rotate the node.
2234
3012
  *
2235
- * @remarks Rotate actions are applied to their children. In addition to this node's rotate action, all ancestors' rotate actions will also be applied.
3013
+ * @remarks Rotate actions are applied to their children. In addition to this
3014
+ * node's rotate action, all ancestors' rotate actions will also be applied.
2236
3015
  *
2237
3016
  * @param options - {@link RotateActionOptions}
2238
3017
  * @returns The rotate action
2239
3018
  */
2240
- static rotate(options: RotateActionOptions): Action;
3019
+ static rotate(options: RotateActionOptions): RotateAction;
2241
3020
  /**
2242
3021
  * Creates an array of actions that will be run in order.
2243
3022
  *
2244
- * @remarks The next action will not begin until the current one has finished. The sequence will be considered completed when the last action has completed.
3023
+ * @remarks The next action will not begin until the current one has
3024
+ * finished. The sequence will be considered completed when the last action
3025
+ * has completed.
2245
3026
  *
2246
3027
  * @param actions - One or more actions that form the sequence
2247
3028
  * @returns
2248
3029
  */
2249
- static sequence(actions: Array<Action>): Action;
3030
+ static sequence(actions: Array<Action>): SequenceAction;
2250
3031
  /**
2251
3032
  * Create an array of actions that will be run simultaneously.
2252
3033
  *
2253
- * @remarks All actions within the group will begin to run at the same time. The group will be considered completed when the longest-running action has completed.
3034
+ * @remarks All actions within the group will begin to run at the same time.
3035
+ * The group will be considered completed when the longest-running action
3036
+ * has completed.
2254
3037
  *
2255
3038
  * @param actions - One or more actions that form the group
2256
3039
  * @returns
2257
3040
  */
2258
- static group(actions: Array<Action>): Action;
2259
- initialize(node: M2Node, key?: string): Array<Action>;
2260
- static cloneAction(action: Action, key?: string): Action;
2261
- static evaluateAction(action: Action, node: M2Node, now: number, dt: number): void;
3041
+ static group(actions: Array<Action>): GroupAction;
2262
3042
  /**
2263
- * Calculates the duration of an action, including any children actions
2264
- * the action may contain.
2265
- *
2266
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2267
- * actions within parent actions
3043
+ * Creates an action that will repeat another action a given number of times.
2268
3044
  *
2269
- * @param action
2270
- * @returns the calculated duration
3045
+ * @param options - {@link RepeatActionOptions}
3046
+ * @returns The repeat action
2271
3047
  */
2272
- private calculateDuration;
3048
+ static repeat(options: RepeatActionOptions): RepeatAction;
2273
3049
  /**
2274
- * Update each action's start and end offsets.
3050
+ * Creates an action that will repeat another action forever.
2275
3051
  *
2276
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2277
- * actions within parent actions.
3052
+ * @remarks A repeat forever action is a special case of a repeat action
3053
+ * where the count is set to infinity.
2278
3054
  *
2279
- * @param action that needs assigning start and end offsets
3055
+ * @param options - {@link RepeatForeverActionOptions}
3056
+ * @returns The repeat forever action
2280
3057
  */
2281
- private calculateStartEndOffsets;
3058
+ static repeatForever(options: RepeatForeverActionOptions): RepeatForeverAction;
2282
3059
  /**
2283
- * Takes an action hierarchy and flattens to an array of non-nested actions
3060
+ * Type guard that returns true if the action is a parent action.
2284
3061
  *
2285
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2286
- * actions within parent actions
3062
+ * @remarks Parent actions are Group, Sequence, Repeat, and RepeatForever
3063
+ * actions.
2287
3064
  *
2288
- * @param action - the action to flatten
2289
- * @param actions - the accumulator array of flattened actions. This will be
2290
- * undefined on the first call, and an array on recursive calls
2291
- * @returns flattened array of actions
3065
+ * @param action - action to check
3066
+ * @returns true if the action is a parent action
2292
3067
  */
2293
- private flattenActions;
3068
+ isParent(action: Action): action is ActionContainer;
2294
3069
  /**
2295
- * Parses the action hierarchy and assigns each action its parent and
2296
- * root action.
3070
+ * Type guard that returns true if the action can repeat.
2297
3071
  *
2298
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2299
- * actions within parent actions
3072
+ * @remarks Repeating actions are Repeat and RepeatForever actions.
2300
3073
  *
2301
- * @param action
2302
- * @param rootAction - top-level action passed to the run method
2303
- * @param key - optional string to identify an action
3074
+ * @param action - action to check
3075
+ * @returns true if the action is a RepeatAction or RepeatForeverAction
2304
3076
  */
2305
- private assignParents;
3077
+ private isRepeating;
3078
+ /**
3079
+ * Indicates whether the action has completed.
3080
+ */
3081
+ get completed(): boolean;
3082
+ set completed(value: boolean);
2306
3083
  }
2307
- declare class SequenceAction extends Action implements IActionContainer {
3084
+ declare class SequenceAction extends Action implements ActionContainer {
2308
3085
  type: ActionType;
2309
3086
  children: Array<Action>;
2310
3087
  constructor(actions: Array<Action>);
3088
+ clone(): SequenceAction;
3089
+ /**
3090
+ * Indicates whether the action has completed, taking into account all its
3091
+ * child actions.
3092
+ *
3093
+ * @remarks Is read-only for parent actions.
3094
+ */
3095
+ get completed(): boolean;
3096
+ get descendants(): Action[];
2311
3097
  }
2312
- declare class GroupAction extends Action implements IActionContainer {
3098
+ declare class GroupAction extends Action implements ActionContainer {
2313
3099
  type: ActionType;
2314
3100
  children: Action[];
2315
3101
  constructor(actions: Array<Action>);
3102
+ clone(): GroupAction;
3103
+ /**
3104
+ * Indicates whether the action has completed, taking into account all its
3105
+ * child actions.
3106
+ *
3107
+ * @remarks Is read-only for parent actions.
3108
+ */
3109
+ get completed(): boolean;
3110
+ get descendants(): Action[];
3111
+ }
3112
+ declare class RepeatAction extends Action implements RepeatingActionContainer {
3113
+ type: ActionType;
3114
+ count: number;
3115
+ children: Array<Action>;
3116
+ completedRepetitions: number;
3117
+ cumulativeDuration: number;
3118
+ constructor(action: Action, count: number, runDuringTransition?: boolean);
3119
+ clone(): RepeatAction;
3120
+ /**
3121
+ * Indicates whether the action has completed, taking into account all its
3122
+ * child actions and the number of repetitions.
3123
+ *
3124
+ * @remarks Is read-only for parent actions.
3125
+ */
3126
+ get completed(): boolean;
3127
+ get descendantsAreCompleted(): boolean;
3128
+ /**
3129
+ * Indicates whether a single repetition of a repeating action has just
3130
+ * completed.
3131
+ *
3132
+ * @returns returns true if a repetition has completed
3133
+ */
3134
+ get repetitionHasCompleted(): boolean;
3135
+ get descendants(): Action[];
3136
+ }
3137
+ declare class RepeatForeverAction extends RepeatAction {
3138
+ type: ActionType;
3139
+ count: number;
3140
+ constructor(action: Action, runDuringTransition?: boolean);
3141
+ clone(): RepeatForeverAction;
2316
3142
  }
2317
3143
  declare class CustomAction extends Action {
2318
3144
  type: ActionType;
2319
3145
  callback: () => void;
2320
3146
  constructor(callback: () => void, runDuringTransition?: boolean);
3147
+ clone(): CustomAction;
3148
+ }
3149
+ declare class PlayAction extends Action {
3150
+ type: ActionType;
3151
+ constructor(runDuringTransition?: boolean);
3152
+ clone(): PlayAction;
2321
3153
  }
2322
3154
  declare class WaitAction extends Action {
2323
3155
  type: ActionType;
2324
- constructor(duration: number, runDuringTransition: boolean);
3156
+ constructor(duration: Futurable, runDuringTransition: boolean);
3157
+ clone(): WaitAction;
2325
3158
  }
2326
3159
  declare class MoveAction extends Action {
2327
3160
  type: ActionType;
@@ -2330,19 +3163,22 @@ declare class MoveAction extends Action {
2330
3163
  dx: number;
2331
3164
  dy: number;
2332
3165
  easing: EasingFunction;
2333
- constructor(point: Point, duration: number, easing: EasingFunction, runDuringTransition: boolean);
3166
+ constructor(point: Point, duration: Futurable, easing: EasingFunction, runDuringTransition: boolean);
3167
+ clone(): MoveAction;
2334
3168
  }
2335
3169
  declare class ScaleAction extends Action {
2336
3170
  type: ActionType;
2337
3171
  scale: number;
2338
3172
  delta: number;
2339
- constructor(scale: number, duration: number, runDuringTransition?: boolean);
3173
+ constructor(scale: number, duration: Futurable, runDuringTransition?: boolean);
3174
+ clone(): ScaleAction;
2340
3175
  }
2341
3176
  declare class FadeAlphaAction extends Action {
2342
3177
  type: ActionType;
2343
3178
  alpha: number;
2344
3179
  delta: number;
2345
- constructor(alpha: number, duration: number, runDuringTransition?: boolean);
3180
+ constructor(alpha: number, duration: Futurable, runDuringTransition?: boolean);
3181
+ clone(): FadeAlphaAction;
2346
3182
  }
2347
3183
  declare class RotateAction extends Action {
2348
3184
  type: ActionType;
@@ -2351,7 +3187,8 @@ declare class RotateAction extends Action {
2351
3187
  shortestUnitArc?: boolean;
2352
3188
  delta: number;
2353
3189
  finalValue: number;
2354
- constructor(byAngle: number | undefined, toAngle: number | undefined, shortestUnitArc: boolean | undefined, duration: number, runDuringTransition?: boolean);
3190
+ constructor(byAngle: number | undefined, toAngle: number | undefined, shortestUnitArc: boolean | undefined, duration: Futurable, runDuringTransition?: boolean);
3191
+ clone(): RotateAction;
2355
3192
  }
2356
3193
 
2357
3194
  interface ActivityCallbacks {
@@ -2760,6 +3597,8 @@ interface IText {
2760
3597
  fontName?: string;
2761
3598
  fontColor?: RgbaColor;
2762
3599
  fontSize?: number;
3600
+ interpolation?: StringInterpolationMap;
3601
+ localize?: boolean;
2763
3602
  }
2764
3603
 
2765
3604
  declare enum LabelHorizontalAlignmentMode {
@@ -2793,15 +3632,18 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
2793
3632
  private _fontNames;
2794
3633
  private _fontColor;
2795
3634
  private _fontSize;
3635
+ private _interpolation;
2796
3636
  private _horizontalAlignmentMode;
2797
3637
  private _preferredMaxLayoutWidth;
2798
3638
  private _backgroundColor?;
3639
+ private _localize;
2799
3640
  private paragraph?;
2800
3641
  private paraStyle?;
2801
3642
  private builder?;
2802
3643
  private _fontPaint?;
2803
3644
  private _backgroundPaint?;
2804
- private _translatedText;
3645
+ private localizedFontName;
3646
+ private localizedFontNames;
2805
3647
  /**
2806
3648
  * Single or multi-line text formatted and rendered on the screen.
2807
3649
  *
@@ -2825,7 +3667,8 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
2825
3667
  dispose(): void;
2826
3668
  get text(): string;
2827
3669
  set text(text: string);
2828
- get translatedText(): string;
3670
+ get interpolation(): StringInterpolationMap;
3671
+ set interpolation(interpolation: StringInterpolationMap);
2829
3672
  get fontName(): string | undefined;
2830
3673
  set fontName(fontName: string | undefined);
2831
3674
  get fontNames(): Array<string> | undefined;
@@ -2840,6 +3683,8 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
2840
3683
  set preferredMaxLayoutWidth(preferredMaxLayoutWidth: number | undefined);
2841
3684
  get backgroundColor(): RgbaColor | undefined;
2842
3685
  set backgroundColor(backgroundColor: RgbaColor | undefined);
3686
+ get localize(): boolean;
3687
+ set localize(localize: boolean);
2843
3688
  private get backgroundPaint();
2844
3689
  private set backgroundPaint(value);
2845
3690
  private get fontPaint();
@@ -3213,6 +4058,131 @@ declare class Shape extends M2Node implements IDrawable, ShapeOptions {
3213
4058
  set strokeColorPaintNotAntialiased(value: Paint);
3214
4059
  }
3215
4060
 
4061
+ interface SoundPlayerOptions extends M2NodeOptions {
4062
+ /** Name of sound to play. Must have been previously loaded */
4063
+ soundName: string;
4064
+ }
4065
+
4066
+ declare class SoundPlayer extends M2Node implements SoundPlayerOptions {
4067
+ readonly type = M2NodeType.SoundPlayer;
4068
+ isDrawable: boolean;
4069
+ soundName: string;
4070
+ /**
4071
+ * Node for playing sounds.
4072
+ *
4073
+ * @param options - {@link SoundPlayerOptions}
4074
+ */
4075
+ constructor(options: SoundPlayerOptions);
4076
+ initialize(): void;
4077
+ dispose(): void;
4078
+ /**
4079
+ * Duplicates a node using deep copy.
4080
+ *
4081
+ * @remarks This is a deep recursive clone (node and children).
4082
+ * The uuid property of all duplicated nodes will be newly created,
4083
+ * because uuid must be unique.
4084
+ *
4085
+ * @param newName - optional name of the new, duplicated node. If not
4086
+ * provided, name will be the new uuid
4087
+ */
4088
+ duplicate(newName?: string): SoundPlayer;
4089
+ }
4090
+
4091
+ interface SoundRecorderOptions extends M2NodeOptions {
4092
+ /** Preferred MIME type to use for recording audio. `audio/webm` or `audio/mp4` is recommended. If omitted, it will use any MIME type supported by the device. */
4093
+ mimeType?: string;
4094
+ /** Additional MIME types to use for recording audio, in order of preference, if preferred type is not supported. `["audio/webm", "audio/mp4"]` is recommended. */
4095
+ backupMimeTypes?: Array<string>;
4096
+ /** Maximum duration, in milliseconds, to allow recording. If recording lasts longer than this duration, it will automatically be paused. This can be used to prevent excessively long recording and memory usage. */
4097
+ maximumDuration?: number;
4098
+ /** Additional audio constraints to be applied when requesting the audio device.
4099
+ * see https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
4100
+ * @remarks Use with caution. All kinds of constraints may not be supported
4101
+ * on all browsers, and specifying too restrictive constraints will result in
4102
+ * no available user audio device and an exception. Unusual constraints may
4103
+ * also result in an unexpected device being selected.
4104
+ * @example
4105
+ * audioTrackConstraints: {
4106
+ * channelCount: 1,
4107
+ * noiseSuppression: { ideal: true },
4108
+ * }
4109
+ * */
4110
+ audioTrackConstraints?: MediaTrackConstraints;
4111
+ }
4112
+
4113
+ interface SoundRecorderResults {
4114
+ /** The MIME type of the recorded audio, possibly including the codec. */
4115
+ mimeType: string;
4116
+ /** The ISO 8601 device timestamp when the recording began. */
4117
+ beginIso8601Timestamp: string;
4118
+ /** The ISO 8601 device timestamp when the recording ended. */
4119
+ endIso8601Timestamp: string;
4120
+ /** The duration of the recording in milliseconds. @remarks The duration may be different from the timestamp end minus begin times if the recording was paused. */
4121
+ duration: number;
4122
+ /** The settings of the audio tracks when the recording began. */
4123
+ audioTrackSettings?: Array<MediaTrackSettings>;
4124
+ /** The recorded audio as a base 64 string. */
4125
+ audioBase64: string;
4126
+ /** The recorded audio as a Blob. */
4127
+ audioBlob: Blob;
4128
+ }
4129
+
4130
+ declare class SoundRecorder extends M2Node implements Omit<SoundRecorderOptions, "backupMimeTypes"> {
4131
+ readonly type = M2NodeType.SoundRecorder;
4132
+ isDrawable: boolean;
4133
+ mimeType?: string;
4134
+ audioTrackConstraints?: MediaTrackConstraints;
4135
+ maximumDuration?: number;
4136
+ private _isRecording;
4137
+ private _isPaused;
4138
+ private mediaRecorder?;
4139
+ private audioChunks;
4140
+ private mediaTrackSettings?;
4141
+ private beginIso8601Timestamp?;
4142
+ private endIso8601Timestamp?;
4143
+ private timerUuid;
4144
+ /**
4145
+ * Node for recording sounds.
4146
+ *
4147
+ * @param options - {@link SoundRecorderOptions}
4148
+ */
4149
+ constructor(options?: SoundRecorderOptions);
4150
+ initialize(): void;
4151
+ start(): Promise<void>;
4152
+ stop(): Promise<SoundRecorderResults>;
4153
+ pause(): void;
4154
+ resume(): void;
4155
+ /** Is the `SoundRecorder` currently recording? */
4156
+ get isRecording(): boolean;
4157
+ /** Is the `SoundRecorder` currently paused? */
4158
+ get isPaused(): boolean;
4159
+ update(): void;
4160
+ /**
4161
+ * Returns an array of supported audio MIME types for MediaRecorder.
4162
+ *
4163
+ * @remarks Adapted from https://stackoverflow.com/a/68236494
4164
+ * License: https://creativecommons.org/licenses/by-sa/4.0/
4165
+ *
4166
+ * @returns
4167
+ */
4168
+ private getMediaRecorderSupportedAudioMimeTypes;
4169
+ private blobToBase64;
4170
+ private getMimeTypeWithoutCodecs;
4171
+ private getSupportedBackupMimeType;
4172
+ dispose(): void;
4173
+ /**
4174
+ * Duplicates a node using deep copy.
4175
+ *
4176
+ * @remarks This is a deep recursive clone (node and children).
4177
+ * The uuid property of all duplicated nodes will be newly created,
4178
+ * because uuid must be unique.
4179
+ *
4180
+ * @param newName - optional name of the new, duplicated node. If not
4181
+ * provided, name will be the new uuid
4182
+ */
4183
+ duplicate(newName?: string): SoundRecorder;
4184
+ }
4185
+
3216
4186
  interface SpriteOptions extends M2NodeOptions, DrawableOptions {
3217
4187
  /** Name of image to use for sprite. Must have been previously loaded */
3218
4188
  imageName?: string;
@@ -3257,6 +4227,18 @@ declare class Sprite extends M2Node implements IDrawable, SpriteOptions {
3257
4227
  update(): void;
3258
4228
  draw(canvas: Canvas): void;
3259
4229
  warmup(canvas: Canvas): void;
4230
+ /**
4231
+ * Draws a rectangle border around the image to indicate that a fallback
4232
+ * image is being used.
4233
+ *
4234
+ * @remarks The size of the rectangle is the same as the image, but because
4235
+ * the stroke width of the paint is wider than 1 pixel (see method
4236
+ * `configureImageLocalization()` in `ImageManager.ts`), the rectangle will
4237
+ * be larger than the image and thus be visible.
4238
+ *
4239
+ * @param canvas - CanvasKit canvas to draw on
4240
+ */
4241
+ private drawFallbackImageBorder;
3260
4242
  }
3261
4243
 
3262
4244
  interface StoryOptions {
@@ -3284,11 +4266,16 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3284
4266
  private _fontName;
3285
4267
  private _fontColor;
3286
4268
  private _fontSize;
4269
+ private _interpolation;
4270
+ private _localize;
3287
4271
  private paint?;
3288
4272
  private font?;
3289
4273
  private typeface;
3290
- private _translatedText;
3291
- private missingTranslationPaint?;
4274
+ private tryMissingTranslationPaint;
4275
+ private textForDraw;
4276
+ private fontForDraw?;
4277
+ private localizedFontName;
4278
+ private localizedFontNames;
3292
4279
  /**
3293
4280
  * Single-line text rendered on the screen.
3294
4281
  *
@@ -3297,16 +4284,6 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3297
4284
  * @param options - {@link TextLineOptions}
3298
4285
  */
3299
4286
  constructor(options?: TextLineOptions);
3300
- get text(): string;
3301
- set text(text: string);
3302
- get translatedText(): string;
3303
- get fontName(): string | undefined;
3304
- set fontName(fontName: string | undefined);
3305
- get fontColor(): RgbaColor;
3306
- set fontColor(fontColor: RgbaColor);
3307
- get fontSize(): number;
3308
- set fontSize(fontSize: number);
3309
- update(): void;
3310
4287
  initialize(): void;
3311
4288
  /**
3312
4289
  * Determines the M2Font object that needs to be ready in order to draw
@@ -3319,6 +4296,20 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3319
4296
  * @returns a M2Font object that is required for the TextLine
3320
4297
  */
3321
4298
  private getRequiredTextLineFont;
4299
+ private createFontPaint;
4300
+ private createFont;
4301
+ get text(): string;
4302
+ set text(text: string);
4303
+ get fontName(): string | undefined;
4304
+ set fontName(fontName: string | undefined);
4305
+ get fontColor(): RgbaColor;
4306
+ set fontColor(fontColor: RgbaColor);
4307
+ get fontSize(): number;
4308
+ set fontSize(fontSize: number);
4309
+ get interpolation(): StringInterpolationMap;
4310
+ set interpolation(interpolation: StringInterpolationMap);
4311
+ get localize(): boolean;
4312
+ set localize(localize: boolean);
3322
4313
  dispose(): void;
3323
4314
  /**
3324
4315
  * Duplicates a node using deep copy.
@@ -3331,6 +4322,7 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3331
4322
  * provided, name will be the new uuid
3332
4323
  */
3333
4324
  duplicate(newName?: string): TextLine;
4325
+ update(): void;
3334
4326
  draw(canvas: Canvas): void;
3335
4327
  warmup(canvas: Canvas): void;
3336
4328
  }
@@ -3447,6 +4439,15 @@ declare class Timer {
3447
4439
 
3448
4440
  declare class Uuid {
3449
4441
  static generate(): string;
4442
+ /**
4443
+ * Tests if a string is a valid UUID.
4444
+ *
4445
+ * @remarks Will match UUID versions 1 through 8, plus the nil UUID.
4446
+ *
4447
+ * @param uuid - the string to test
4448
+ * @returns true if the string is a valid UUID
4449
+ */
4450
+ static isValid(uuid: string | undefined | null): boolean;
3450
4451
  }
3451
4452
 
3452
4453
  declare class WebColors {
@@ -3611,4 +4612,4 @@ declare class WebGlInfo {
3611
4612
  static dispose(): void;
3612
4613
  }
3613
4614
 
3614
- export { Action, type Activity, type ActivityCallbacks, type ActivityEvent, type ActivityEventListener, type ActivityKeyValueData, type ActivityLifecycleEvent, type ActivityResultsEvent, ActivityType, type BrowserImage, type CallbackOptions, CanvasKitHelpers, ColorfulMutablePath, Composite, type CompositeOptions, Constants, ConstraintType, type Constraints, CustomAction, type CustomActionOptions, type DefaultParameter, Dimensions, type DrawableOptions, type EasingFunction, Easings, Equals, FadeAlphaAction, type FadeAlphaActionOptions, type FontAsset, type FontData, FontManager, Game, type GameData, type GameEvent, type GameOptions, type GameParameters, GlobalVariables, GroupAction, I18n, type IDataStore, type IDrawable, type IText, ImageManager, Label, LabelHorizontalAlignmentMode, type LabelOptions, type Layout, LayoutConstraint, LegacyTimer, type M2ColorfulPath, type M2DragEvent, type M2Event, type M2EventListener, M2EventType, type M2Image, M2ImageStatus, M2Node, type M2NodeEvent, type M2NodeEventListener, type M2NodeOptions, M2NodeType, type M2Path, type M2PointerEvent, M2c2KitHelpers, MoveAction, type MoveActionOptions, MutablePath, NoneTransition, type Plugin, type PluginEvent, type Point, RandomDraws, type RectOptions, type RgbaColor, RotateAction, ScaleAction, type ScaleActionOptions, Scene, type SceneOptions, SceneTransition, SequenceAction, Shape, type ShapeOptions, ShapeType, type Size, SlideTransition, type SlideTransitionOptions, Sprite, type SpriteOptions, Story, type StoryOptions, type TapEvent, TextLine, type TextLineOptions, type TextOptions, Timer, Transition, TransitionDirection, TransitionType, type Translations, type TrialData, type TrialSchema, Uuid, WaitAction, type WaitActionOptions, WebColors, WebGlInfo, handleInterfaceOptions };
4615
+ export { Action, type Activity, type ActivityCallbacks, type ActivityEvent, type ActivityEventListener, type ActivityKeyValueData, type ActivityLifecycleEvent, type ActivityResultsEvent, ActivityType, type BrowserImage, type CallbackOptions, CanvasKitHelpers, ColorfulMutablePath, Composite, type CompositeOptions, Constants, ConstraintType, type Constraints, CustomAction, type CustomActionOptions, type DefaultParameter, Dimensions, type DrawableOptions, type EasingFunction, Easings, Equals, FadeAlphaAction, type FadeAlphaActionOptions, type FontAsset, type FontData, FontManager, Game, type GameData, type GameEvent, type GameOptions, type GameParameters, GlobalVariables, GroupAction, I18n, type IDataStore, type IDrawable, type IText, ImageManager, Label, LabelHorizontalAlignmentMode, type LabelOptions, type Layout, LayoutConstraint, LegacyTimer, type LocaleSvg, type M2ColorfulPath, type M2DragEvent, type M2Event, type M2EventListener, M2EventType, type M2Image, M2ImageStatus, M2Node, type M2NodeEvent, type M2NodeEventListener, type M2NodeOptions, M2NodeType, type M2Path, type M2PointerEvent, type M2Sound, M2SoundStatus, M2c2KitHelpers, MoveAction, type MoveActionOptions, MutablePath, NoneTransition, PlayAction, type PlayActionOptions, type Plugin, type PluginEvent, type Point, RandomDraws, type RectOptions, RepeatAction, RepeatForeverAction, type RgbaColor, RotateAction, ScaleAction, type ScaleActionOptions, Scene, type SceneOptions, SceneTransition, SequenceAction, Shape, type ShapeOptions, ShapeType, type Size, SlideTransition, type SlideTransitionOptions, type SoundAsset, SoundManager, SoundPlayer, type SoundPlayerOptions, SoundRecorder, type SoundRecorderOptions, type SoundRecorderResults, Sprite, type SpriteOptions, Story, type StoryOptions, type StringInterpolationMap, type TapEvent, type TextAndFont, TextLine, type TextLineOptions, type TextLocalizationResult, type TextOptions, type TextWithFontCustomization, Timer, Transition, TransitionDirection, TransitionType, type Translation, type TranslationConfiguration, type TranslationOptions, type TrialData, type TrialSchema, Uuid, WaitAction, type WaitActionOptions, WebColors, WebGlInfo, handleInterfaceOptions };