@applicaster/zapp-react-native-utils 14.0.0-alpha.1054425138 → 14.0.0-alpha.1118824347

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.
Files changed (69) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +82 -53
  2. package/analyticsUtils/AnalyticsEvents/helper.ts +81 -0
  3. package/analyticsUtils/AnalyticsEvents/sendOnClickEvent.ts +14 -4
  4. package/analyticsUtils/__tests__/analyticsUtils.test.js +14 -0
  5. package/analyticsUtils/events.ts +8 -0
  6. package/appUtils/HooksManager/Hook.ts +4 -4
  7. package/appUtils/HooksManager/index.ts +11 -1
  8. package/appUtils/accessibilityManager/index.ts +5 -2
  9. package/appUtils/contextKeysManager/contextResolver.ts +1 -15
  10. package/appUtils/focusManager/__tests__/__snapshots__/focusManager.test.js.snap +4 -0
  11. package/appUtils/focusManager/__tests__/focusManager.test.js +1 -1
  12. package/appUtils/focusManager/index.ts +81 -9
  13. package/appUtils/focusManagerAux/utils/index.ts +48 -2
  14. package/appUtils/playerManager/OverlayObserver/OverlaysObserver.ts +0 -15
  15. package/appUtils/playerManager/useChapterMarker.tsx +0 -1
  16. package/appUtils/playerManager/usePlayerControllerSetup.tsx +16 -0
  17. package/arrayUtils/__tests__/isEmptyArray.test.ts +63 -0
  18. package/arrayUtils/__tests__/isFilledArray.test.ts +1 -1
  19. package/arrayUtils/index.ts +8 -3
  20. package/audioPlayerUtils/__tests__/getArtworkImage.test.ts +144 -0
  21. package/audioPlayerUtils/__tests__/getBackgroundImage.test.ts +72 -0
  22. package/audioPlayerUtils/__tests__/getImageFromEntry.test.ts +110 -0
  23. package/audioPlayerUtils/assets/index.ts +2 -0
  24. package/audioPlayerUtils/index.ts +242 -0
  25. package/componentsUtils/__tests__/isTabsScreen.test.ts +38 -0
  26. package/componentsUtils/index.ts +4 -1
  27. package/conf/player/__tests__/selectors.test.ts +34 -0
  28. package/conf/player/selectors.ts +10 -0
  29. package/configurationUtils/__tests__/configurationUtils.test.js +0 -31
  30. package/configurationUtils/__tests__/getMediaItems.test.ts +65 -0
  31. package/configurationUtils/__tests__/imageSrcFromMediaItem.test.ts +34 -0
  32. package/configurationUtils/__tests__/manifestKeyParser.test.ts +547 -0
  33. package/configurationUtils/index.ts +63 -34
  34. package/configurationUtils/manifestKeyParser.ts +57 -32
  35. package/focusManager/FocusManager.ts +26 -16
  36. package/focusManager/Tree.ts +25 -21
  37. package/focusManager/__tests__/FocusManager.test.ts +50 -8
  38. package/manifestUtils/_internals/getDefaultConfiguration.js +28 -0
  39. package/manifestUtils/{_internals.js → _internals/index.js} +2 -25
  40. package/manifestUtils/createConfig.js +4 -1
  41. package/manifestUtils/defaultManifestConfigurations/player.js +1239 -200
  42. package/manifestUtils/progressBar/__tests__/mobileProgressBar.test.js +0 -30
  43. package/manifestUtils/sharedConfiguration/screenPicker/stylesFields.js +1 -2
  44. package/package.json +2 -2
  45. package/playerUtils/__tests__/configurationUtils.test.ts +1 -65
  46. package/playerUtils/__tests__/getPlayerActionButtons.test.ts +54 -0
  47. package/playerUtils/_internals/__tests__/utils.test.ts +71 -0
  48. package/playerUtils/_internals/index.ts +1 -0
  49. package/playerUtils/_internals/utils.ts +31 -0
  50. package/playerUtils/configurationUtils.ts +0 -44
  51. package/playerUtils/getPlayerActionButtons.ts +17 -0
  52. package/playerUtils/index.ts +59 -0
  53. package/playerUtils/useValidatePlayerConfig.tsx +22 -19
  54. package/reactHooks/cell-click/index.ts +1 -5
  55. package/reactHooks/feed/useBatchLoading.ts +3 -3
  56. package/reactHooks/feed/useFeedLoader.tsx +6 -13
  57. package/reactHooks/feed/usePipesCacheReset.ts +1 -1
  58. package/reactHooks/layout/isTablet/index.ts +12 -5
  59. package/reactHooks/navigation/index.ts +7 -3
  60. package/reactHooks/navigation/useIsScreenActive.ts +9 -5
  61. package/reactHooks/screen/useScreenContext.ts +1 -1
  62. package/reactHooks/state/__tests__/ZStoreProvider.test.tsx +2 -1
  63. package/riverComponetsMeasurementProvider/index.tsx +1 -1
  64. package/services/js2native.ts +1 -0
  65. package/time/BackgroundTimer.ts +5 -3
  66. package/utils/index.ts +16 -1
  67. package/actionsExecutor/ScreenActions.ts +0 -90
  68. package/actionsExecutor/StorageActions.ts +0 -110
  69. package/playerUtils/configurationGenerator.ts +0 -2572
@@ -1,4 +1,4 @@
1
- import { isNotNil } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
1
+ import { isNil } from "@applicaster/zapp-react-native-utils/utils";
2
2
  import { find, last, pathOr, startsWith } from "ramda";
3
3
  import {
4
4
  QUICK_BRICK_CONTENT,
@@ -9,6 +9,8 @@ import {
9
9
  // run this check too often could lead to performance penalty on low-end devices
10
10
  const HOW_OFTEN_TO_CHECK_CONDITION = 300; // ms
11
11
 
12
+ const TABS_GROUP_ID = "PickerSelector.sp-river";
13
+
12
14
  type Props = {
13
15
  maxTimeout: number;
14
16
  conditionFn: () => boolean;
@@ -49,7 +51,7 @@ export const waitForActiveScreen = (currentRoute: string, focusableTree) => {
49
51
 
50
52
  const route = find((route) => route.id === currentRoute, routes);
51
53
 
52
- return isNotNil(route);
54
+ return !isNil(route);
53
55
  };
54
56
 
55
57
  return waitUntil({
@@ -99,3 +101,47 @@ export const waitForContent = (focusableTree) => {
99
101
  conditionFn: contentHasAnyChildren,
100
102
  });
101
103
  };
104
+
105
+ export function isTabsScreen(focusableTree) {
106
+ const tabsGroup = focusableTree.findInTree(TABS_GROUP_ID);
107
+
108
+ return !!tabsGroup;
109
+ }
110
+
111
+ export const findSelectedTabId = (focusableTree) => {
112
+ // FIXME - find elegant way how to get ID of selected tab
113
+ const tabsGroup = focusableTree.findInTree(TABS_GROUP_ID);
114
+
115
+ const selectedTabId = tabsGroup.children.find(
116
+ (child) => child.component.props.preferredFocus // ?? selected
117
+ )?.id;
118
+
119
+ return selectedTabId;
120
+ };
121
+
122
+ export const findSelectedMenuId = (focusableTree) => {
123
+ // Set focus with back button context
124
+ const navbar = getNavbarNode(focusableTree);
125
+
126
+ const selectedMenuItemId = find(
127
+ (child) => child.component.props.selected,
128
+ navbar.children
129
+ )?.id;
130
+
131
+ return selectedMenuItemId;
132
+ };
133
+
134
+ export const isTabsMenuFocused = (node) => {
135
+ // FIXME - find elegant way how to get ID of selected tab
136
+ return node.parent.id === TABS_GROUP_ID;
137
+ };
138
+
139
+ export const isCurrentFocusOnMenu = (node) => {
140
+ // FIXME
141
+ return node.parent.id.startsWith(QUICK_BRICK_NAVBAR);
142
+ };
143
+
144
+ export const isCurrentFocusOnContent = (node) => {
145
+ // FIXME
146
+ return !isCurrentFocusOnMenu(node);
147
+ };
@@ -18,13 +18,6 @@ export const { log_verbose, log_debug, log_info, log_error } = createLogger({
18
18
  parent: utilsLogger,
19
19
  });
20
20
 
21
- type ActionChapter = {
22
- type: string;
23
- options?: {
24
- title: string;
25
- };
26
- };
27
-
28
21
  type ChapterMarkerOriginal = {
29
22
  id: string;
30
23
  title: string;
@@ -33,14 +26,6 @@ type ChapterMarkerOriginal = {
33
26
  actions: ActionChapter[];
34
27
  };
35
28
 
36
- export type ChapterMarkerEvent = {
37
- id: string;
38
- title: string;
39
- start_time: number;
40
- end_time: number;
41
- actions: ActionChapter[];
42
- };
43
-
44
29
  export type TitleSummaryEvent = {
45
30
  title: string | number;
46
31
  summary: string | number;
@@ -1,4 +1,3 @@
1
- import { ChapterMarkerEvent } from "./OverlayObserver/OverlaysObserver";
2
1
  import { usePlayer } from "./usePlayer";
3
2
  import * as React from "react";
4
3
 
@@ -5,6 +5,9 @@ import { playerManager } from "./index";
5
5
  import { useValidatePlayerConfig } from "../../playerUtils/useValidatePlayerConfig";
6
6
  import { PlayerRole } from "./conts";
7
7
  import { isAppleTV } from "@applicaster/zapp-react-native-ui-components/Helpers/Platform";
8
+ import { TVSeekController } from "../../reactHooks/player/TVSeekControlller/TVSeekController";
9
+ import { KeyInputHandler } from "../keyInputHandler/KeyInputHandler";
10
+ import { isTV } from "../../reactUtils";
8
11
 
9
12
  // TODO: Rename to ControllerType
10
13
  export const usePlayerControllerSetup = ({
@@ -76,5 +79,18 @@ export const usePlayerControllerSetup = ({
76
79
  };
77
80
  }, [playerId, playerController]);
78
81
 
82
+ useEffect(() => {
83
+ if (!isTV()) {
84
+ return;
85
+ }
86
+
87
+ if (playerController) {
88
+ const seekController = new TVSeekController(playerController);
89
+ playerController.seekController = seekController;
90
+
91
+ return KeyInputHandler.getInstance().addListener(seekController);
92
+ }
93
+ }, [playerController]);
94
+
79
95
  return playerController;
80
96
  };
@@ -0,0 +1,63 @@
1
+ import { isEmptyArray } from "..";
2
+
3
+ describe("isEmptyArray", () => {
4
+ it("non-empty array is not empty", () => {
5
+ const value = [1, 2, 3];
6
+
7
+ expect(isEmptyArray(value)).toBe(false);
8
+ });
9
+
10
+ it("empty array is empty", () => {
11
+ const value = [];
12
+
13
+ expect(isEmptyArray(value)).toBe(true);
14
+ });
15
+
16
+ it("number is not array", () => {
17
+ const value = 123;
18
+
19
+ expect(isEmptyArray(value)).toBe(false);
20
+ });
21
+
22
+ it("string is not array", () => {
23
+ const value = "vfnjdk";
24
+
25
+ expect(isEmptyArray(value)).toBe(false);
26
+ });
27
+
28
+ it("empty string is not array", () => {
29
+ const value = "";
30
+
31
+ expect(isEmptyArray(value)).toBe(false);
32
+ });
33
+
34
+ it("NaN is not array", () => {
35
+ const value = NaN;
36
+
37
+ expect(isEmptyArray(value)).toBe(false);
38
+ });
39
+
40
+ it("object is not array", () => {
41
+ const value = { test: 1 };
42
+
43
+ expect(isEmptyArray(value)).toBe(false);
44
+ });
45
+
46
+ it("empty object is not array", () => {
47
+ const value = {};
48
+
49
+ expect(isEmptyArray(value)).toBe(false);
50
+ });
51
+
52
+ it("undefined is not array", () => {
53
+ const value = undefined;
54
+
55
+ expect(isEmptyArray(value)).toBe(false);
56
+ });
57
+
58
+ it("null is not array", () => {
59
+ const value = null;
60
+
61
+ expect(isEmptyArray(value)).toBe(false);
62
+ });
63
+ });
@@ -32,7 +32,7 @@ describe("isFilledArray", () => {
32
32
  });
33
33
 
34
34
  it("NaN is not array", () => {
35
- const value = "";
35
+ const value = NaN;
36
36
 
37
37
  expect(isFilledArray(value)).toBe(false);
38
38
  });
@@ -93,18 +93,23 @@ export const isIndexInRange = (index: number, length: number): boolean => {
93
93
  export const makeListOfIndexes = (size: number): number[] =>
94
94
  Array.from({ length: size }, (_, index) => index);
95
95
 
96
- export const makeListOf = (value: unknown, size: number): number[] => {
96
+ export const makeListOf = <T>(value: T, size: number): T[] => {
97
97
  return Array(size).fill(value);
98
98
  };
99
99
 
100
100
  /** Checks if a value is a non-empty array */
101
101
  export function isFilledArray(value: unknown): boolean {
102
- return R.is(Array, value) && R.length(value) > 0;
102
+ return Array.isArray(value) && value.length > 0;
103
+ }
104
+
105
+ /** Checks if a value is a empty array */
106
+ export function isEmptyArray(value: unknown): boolean {
107
+ return Array.isArray(value) && value.length === 0;
103
108
  }
104
109
 
105
110
  // get random item from the list
106
111
  export const sample = (xs: unknown[]): unknown => {
107
- invariant(R.is(Array, xs), `input value is not a array: ${xs}`);
112
+ invariant(Array.isArray(xs), `input value is not an array: ${xs}`);
108
113
  invariant(isFilledArray(xs), `input array is empty: ${xs}`);
109
114
 
110
115
  const index = Math.floor(Math.random() * xs.length);
@@ -0,0 +1,144 @@
1
+ import { getArtworkImage } from "..";
2
+ import { DEFAULT_IMAGE } from "../assets";
3
+
4
+ describe("getArtworkImage", () => {
5
+ const entryWithImage = {
6
+ media_group: [
7
+ {
8
+ type: "image",
9
+ media_item: [
10
+ { key: "artwork_key", src: "image_from_entry" },
11
+ { key: "other_key", src: "other_image" },
12
+ ],
13
+ },
14
+ ],
15
+ extensions: {
16
+ artwork_key: "artwork_key",
17
+ },
18
+ };
19
+
20
+ const entryWithoutImage = {
21
+ media_group: [
22
+ {
23
+ type: "image",
24
+ media_item: [{ key: "other_key", src: "other_image" }],
25
+ },
26
+ ],
27
+ extensions: {
28
+ artwork_key: "artwork_key",
29
+ },
30
+ };
31
+
32
+ const pluginConfigWithImage = {
33
+ artwork_key: "plugin_artwork_key",
34
+ };
35
+
36
+ it("returns image from entry extensions key", () => {
37
+ const result = getArtworkImage({
38
+ key: "artwork_key",
39
+ entry: entryWithImage,
40
+ plugin_configuration: {},
41
+ });
42
+
43
+ expect(result).toBe("image_from_entry");
44
+ });
45
+
46
+ it("returns image from plugin configuration key if not in entry", () => {
47
+ const entryNoMatch = {
48
+ ...entryWithoutImage,
49
+ extensions: { artwork_key: "not_found_key" },
50
+ };
51
+
52
+ const pluginConfig = {
53
+ artwork_key: "plugin_artwork_key",
54
+ };
55
+
56
+ const entryWithPluginImage = {
57
+ ...entryNoMatch,
58
+ media_group: [
59
+ {
60
+ type: "image",
61
+ media_item: [{ key: "plugin_artwork_key", src: "image_from_plugin" }],
62
+ },
63
+ ],
64
+ };
65
+
66
+ const result = getArtworkImage({
67
+ key: "artwork_key",
68
+ entry: entryWithPluginImage,
69
+ plugin_configuration: pluginConfig,
70
+ });
71
+
72
+ expect(result).toBe("image_from_plugin");
73
+ });
74
+
75
+ it("returns DEFAULT_IMAGE if neither entry nor plugin configuration has image", () => {
76
+ const entryNoImage = {
77
+ media_group: [
78
+ {
79
+ type: "image",
80
+ media_item: [{ key: "other_key", src: "other_image" }],
81
+ },
82
+ ],
83
+ extensions: { artwork_key: "not_found_key" },
84
+ };
85
+
86
+ const pluginConfig = { artwork_key: "not_found_key" };
87
+
88
+ const result = getArtworkImage({
89
+ key: "artwork_key",
90
+ entry: entryNoImage,
91
+ plugin_configuration: pluginConfig,
92
+ });
93
+
94
+ expect(result).toBe(DEFAULT_IMAGE);
95
+ });
96
+
97
+ it("handles undefined key gracefully", () => {
98
+ const result = getArtworkImage({
99
+ key: undefined,
100
+ entry: entryWithImage,
101
+ plugin_configuration: pluginConfigWithImage,
102
+ });
103
+
104
+ expect(result).toBe(DEFAULT_IMAGE);
105
+ });
106
+
107
+ it("handles missing entry or plugin_configuration gracefully", () => {
108
+ const result = getArtworkImage({
109
+ key: "artwork_key",
110
+ entry: undefined,
111
+ plugin_configuration: undefined,
112
+ });
113
+
114
+ expect(result).toBe(DEFAULT_IMAGE);
115
+ });
116
+
117
+ it("handles empty media_group", () => {
118
+ const entryEmptyMedia = {
119
+ media_group: [],
120
+ extensions: { artwork_key: "artwork_key" },
121
+ };
122
+
123
+ const result = getArtworkImage({
124
+ key: "artwork_key",
125
+ entry: entryEmptyMedia,
126
+ plugin_configuration: pluginConfigWithImage,
127
+ });
128
+
129
+ expect(result).toBe(DEFAULT_IMAGE);
130
+ });
131
+
132
+ it("handles missing extensions/config keys", () => {
133
+ const entryNoExt = { media_group: [], extensions: {} };
134
+ const pluginConfig = {};
135
+
136
+ const result = getArtworkImage({
137
+ key: "artwork_key",
138
+ entry: entryNoExt,
139
+ plugin_configuration: pluginConfig,
140
+ });
141
+
142
+ expect(result).toBe(DEFAULT_IMAGE);
143
+ });
144
+ });
@@ -0,0 +1,72 @@
1
+ import { getBackgroundImage } from "..";
2
+ import { DEFAULT_IMAGE } from "../assets";
3
+
4
+ describe("getBackgroundImage", () => {
5
+ const entryBase = {
6
+ media_group: [
7
+ {
8
+ media_item: [
9
+ { key: "image_key_1", src: "image_src_1" },
10
+ { key: "image_key_2", src: "image_src_2" },
11
+ ],
12
+ type: "image",
13
+ },
14
+ ],
15
+ extensions: {},
16
+ };
17
+
18
+ const pluginConfigBase = {};
19
+
20
+ it("returns image from entry.extensions.image_key if present", () => {
21
+ const entry = {
22
+ ...entryBase,
23
+ extensions: { image_key: "image_key_2" },
24
+ };
25
+
26
+ const result = getBackgroundImage({
27
+ entry,
28
+ plugin_configuration: pluginConfigBase,
29
+ });
30
+
31
+ expect(result).toBe("image_src_2");
32
+ });
33
+
34
+ it("returns audio_player_background_image from entry.extensions if present and no image_key image", () => {
35
+ const entry = {
36
+ ...entryBase,
37
+ extensions: { audio_player_background_image: "audio_img_ext" },
38
+ };
39
+
40
+ const result = getBackgroundImage({
41
+ entry,
42
+ plugin_configuration: pluginConfigBase,
43
+ });
44
+
45
+ expect(result).toBe("audio_img_ext");
46
+ });
47
+
48
+ it("returns image from plugin_configuration.audio_player_image_key if present and not found in entry.extensions", () => {
49
+ const entry = { ...entryBase };
50
+ const plugin_configuration = { audio_player_image_key: "image_key_1" };
51
+ const result = getBackgroundImage({ entry, plugin_configuration });
52
+ expect(result).toBe("image_src_1");
53
+ });
54
+
55
+ it("returns audio_player_background_image from plugin_configuration if present and not found in entry/extensions", () => {
56
+ const entry = { ...entryBase };
57
+
58
+ const plugin_configuration = {
59
+ audio_player_background_image: "audio_img_conf",
60
+ };
61
+
62
+ const result = getBackgroundImage({ entry, plugin_configuration });
63
+ expect(result).toBe("audio_img_conf");
64
+ });
65
+
66
+ it("returns DEFAULT_IMAGE if nothing is found", () => {
67
+ const entry = { media_group: [], extensions: {} };
68
+ const plugin_configuration = {};
69
+ const result = getBackgroundImage({ entry, plugin_configuration });
70
+ expect(result).toBe(DEFAULT_IMAGE);
71
+ });
72
+ });
@@ -0,0 +1,110 @@
1
+ import { getImageFromEntry } from "..";
2
+
3
+ const entry = {
4
+ media_group: [
5
+ {
6
+ media_item: [
7
+ {
8
+ key: "image_base_key",
9
+ src: "image_base_src",
10
+ },
11
+ {
12
+ key: "thumb_1",
13
+ src: null,
14
+ },
15
+ {
16
+ key: "thumb_2",
17
+ src: null,
18
+ },
19
+ {
20
+ key: "thumb_3",
21
+ src: null,
22
+ },
23
+ ],
24
+ type: "image",
25
+ },
26
+ ],
27
+ };
28
+
29
+ describe("getImageFromEntry", () => {
30
+ it("returns the src value for existing key", () => {
31
+ const result = getImageFromEntry({
32
+ entry,
33
+ imageKey: "image_base_key",
34
+ });
35
+
36
+ expect(result).toEqual("image_base_src");
37
+ });
38
+
39
+ it("returns undefined for non-existing key", () => {
40
+ const result = getImageFromEntry({
41
+ entry,
42
+ imageKey: "non_existing_key",
43
+ });
44
+
45
+ expect(result).toBeUndefined();
46
+ });
47
+
48
+ it("returns undefined for undefined key", () => {
49
+ const result = getImageFromEntry({
50
+ entry,
51
+ imageKey: undefined,
52
+ });
53
+
54
+ expect(result).toBeUndefined();
55
+ });
56
+
57
+ it("returns undefined for non string src", () => {
58
+ const entryWithNonStringSrc = {
59
+ media_group: [
60
+ {
61
+ media_item: [
62
+ {
63
+ key: "image_base_key",
64
+ src: 123,
65
+ },
66
+ {
67
+ key: "thumb_1",
68
+ src: null,
69
+ },
70
+ ],
71
+ type: "image",
72
+ },
73
+ ],
74
+ };
75
+
76
+ const result = getImageFromEntry({
77
+ entry: entryWithNonStringSrc,
78
+ imageKey: "image_base_key",
79
+ });
80
+
81
+ expect(result).toBeUndefined();
82
+ });
83
+
84
+ it("returns undefined for empty src", () => {
85
+ const entryWithEmptySrc = {
86
+ media_group: [
87
+ {
88
+ media_item: [
89
+ {
90
+ key: "image_base_key",
91
+ src: "",
92
+ },
93
+ {
94
+ key: "thumb_1",
95
+ src: null,
96
+ },
97
+ ],
98
+ type: "image",
99
+ },
100
+ ],
101
+ };
102
+
103
+ const result = getImageFromEntry({
104
+ entry: entryWithEmptySrc,
105
+ imageKey: "image_base_key",
106
+ });
107
+
108
+ expect(result).toBeUndefined();
109
+ });
110
+ });
@@ -0,0 +1,2 @@
1
+ export const DEFAULT_IMAGE =
2
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABwgAAAP0CAYAAAC+jGj3AAAxj0lEQVR4AezdIWyd59nH4af9piKXbKAOGXJQpShGJTYacXisSUOxIo1FQZNmBWyaFCXSVBCltHLQpMpGIzYasVFJjUpiVJKgEhuN9Nv9tk7bKI59nnOOfY7/1yW9Ou2aej7PW/bTfT8f3Lp164cGAAAAAAAARPiwAQAAAAAAADEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAAAAAAAAQRCAEAAAAAACAIAIhAAAAAAAABBEIAQAAAAAAIIhACAAAAAAAAEEEQgAAAAAAAAgiEAIAAAAAAEAQgRAAAAAAAACCCIQAADQAAAAAcgiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAA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Odi7UrXWiT59+nTkVaqn72ReVrACAADMAoEQAADggmqt6DjTao8ePeoOWbW6c9bV/YA96kxrZWiv07WkAAAAXIxACAAAcAE1/TfOmtBScXB7e7v16I1vl6l3enDc8FoODg66JzQBAADSCIQAAAAX0Bv23lb35vVMEdb6zll38+bNNqoKg+OG11MVGgEAADifQAgAAHCOCno1oTapn1X37Y2qJ75dtp6I+fLlyzYpR0dH7iIEAAC4AIEQAADgHBWervrnLSwstFnXEwgnuRa04uC4q0oBAAASCIQAAADnOD4+bpPUM+U2D4Gwx6Qn/iY5kQgAAHBdCYQAAADnsLYSAACA60QgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAACc48aNG22SFhYWGtMx6XcFAABwHQmEAABAlJOTkzaqpaWlNkmLi4ttVK9fv26zrud3nPTZ9vy8nv8mAAAA5plACAAAROmJWDXxd/v27TYpq6urbVTzEAh7QlvPWZyl4mDPdOY8nC0AAMAkCYQAAECU3hg0qUBYP6dngvD4+LjNupcvX7ZR1VlM6mzX19dbj6OjowYAAJBEIAQAAKIcHh62HhWfesLe2x48eNB69P7el6k3tG1sbLRx1btZW1trPQRCAAAgjUAIAABEqTWYvWtGHz9+3MZRIaz3zr15CIS9v2NNEI4bCXvfTcVBdxACAABpBEIAACDO/v5+61Fxb3Nzs/W4c+dOu3fvXutRQXMeptzGiW11Nnfv3m096p30htdvvvmmAQAApBEIAQCAOAcHB61XrbH88ssvL7xutCYPa63oX//619arN2hehe3t7darzmmUScJ6B/UueleLlr29vQYAAJDmg1u3bv3QAAAAwjx79mxYbTmOiksVxN413VdhsO4trHg17t2Ff/zjH7vWol6F+q5fffVVG0d9162trWFl6bu+d7231dXV4WzrnHvVe7t//34DAABIIxACAACRKjJVJJyEWqtZsaliVgWrWnc5bhQ8tbu7254+fdrmySTi66nTtaV1tnWmdbbjRMFfevLkiQlCAAAgkkAIAADEmmTImpZ5mh48VRGvVn/OsjrTOlsAAIBE7iAEAABi1RrLWVbrS+ctDpaa+hvnLsLL8OjRowYAAJBKIAQAAGLVHXezGrIqDL548aLNq/rdZzVunnVvJAAAQAqBEAAAiDarIasm3OruvXlVv3vd8Tdr5j28AgAATIJACAAARKuQ9fDhw5mKhM+fP78WE241oVnfZVbUO653Pc/hFQAAYBL+75NPPvl7AwAACFbBqGLWH/7wh/bRRx+1q1T3Iv7rX/9q18W33347fC4vL7erVO/4L3/5S/vuu+8aAABAOoEQAADgf77//vv29ddft88++6wtLCy0q1Bx8Dquv6z4Wq4qEtbkYMVB9w4CAAD8SCAEAAD4SUXCg4ODtrq6eqmRsKbbPv/887azs9Ouq4qE9T0//fTTS53SPF0ranIQAADgZx/cunXrhwYAAMAbFQfv3bvX1tfX27TVVNujR49m6g7EaVpcXGzPnj0bPqdte3t7mMh05yAAAMCvCYQAAABnWFpaao8fP55KzKpoVStFr/PU4PvcvXt3CLDTONuaVqyzPV1tCgAAwK8JhAAAAOdYW1sbYlYFw3FVGKzJtgqD6ZNtFQfrbO/cuTORUCgMAgAAXIxACAAAcEEVCCtoLS8vjxQLKwTW3Ya7u7vi1RlWVlaGZ9T7H2s16/7+/nC+zhYAAOBiBEIAAIAOFbEqEtZT028ff/zxr/75q1evhnhV0SrlfsFJOT3T+rxx48av/tnx8fFwnqdn635BAACA0QmEAAAAAAAAEOTDBgAAAAAAAMQQCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAAAAAAAAggiEAAAAAAAAEEQgBAAAAAAAgCACIQAAAAAAAAQRCAEAAAAAACCIQAgAAAAAAABBBEIAAAAAAAAIIhACAAAAAABAEIEQAADg/9uzAwEAAAAAQf7Wg1waAQAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADAiCAEAAAAAACAEUEIAAAAAAAAI4IQAAAAAAAARgQhAAAAAAAAjAhCAAAAAAAAGBGEAAAAAAAAMCIIAQAAAAAAYEQQAgAAAAAAwIggBAAAAAAAgBFBCAAAAAAAACOCEAAAAAAAAEYEIQAAAAAAAIwIQgAAAAAAABgRhAAAAAAAADAiCAEAAAAAAGBEEAIAAAAAAMCIIAQAAAAAAIARQQgAAAAAAAAjghAAAAAAAABGBCEAAAAAAACMCEIAAAAAAAAYEYQAAAAAAAAwIggBAAAAAABgRBACAAAAAADASOotf98aH400AAAAAElFTkSuQmCC";