@teambit/install 1.0.228 → 1.0.230

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.
@@ -0,0 +1,4 @@
1
+ import { BitError } from '@teambit/bit-error';
2
+ export declare class DependencyTypeNotSupportedInPolicy extends BitError {
3
+ constructor(type: string);
4
+ }
@@ -0,0 +1 @@
1
+ export { DependencyTypeNotSupportedInPolicy } from './dependency-type-not-supported-in-policy';
@@ -0,0 +1,5 @@
1
+ import { InstallAspect } from './install.aspect';
2
+ export { getAnotherInstallRequiredOutput } from './install.cmd';
3
+ export type { InstallMain } from './install.main.runtime';
4
+ export default InstallAspect;
5
+ export { InstallAspect };
@@ -0,0 +1,2 @@
1
+ import { Aspect } from '@teambit/harmony';
2
+ export declare const InstallAspect: Aspect;
@@ -0,0 +1,54 @@
1
+ import { Command, CommandOptions } from '@teambit/cli';
2
+ import { WorkspaceDependencyLifecycleType } from '@teambit/dependency-resolver';
3
+ import { Logger } from '@teambit/logger';
4
+ import { Workspace } from '@teambit/workspace';
5
+ import { InstallMain } from './install.main.runtime';
6
+ type InstallCmdOptions = {
7
+ type: WorkspaceDependencyLifecycleType;
8
+ skipDedupe: boolean;
9
+ skipImport: boolean;
10
+ skipCompile: boolean;
11
+ skipWriteConfigFiles: boolean;
12
+ update: boolean;
13
+ updateExisting: boolean;
14
+ savePrefix: string;
15
+ addMissingDeps: boolean;
16
+ addMissingPeers: boolean;
17
+ noOptional: boolean;
18
+ recurringInstall: boolean;
19
+ lockfileOnly: boolean;
20
+ };
21
+ export default class InstallCmd implements Command {
22
+ private install;
23
+ /**
24
+ * workspace extension.
25
+ */
26
+ private workspace;
27
+ /**
28
+ * logger extension.
29
+ */
30
+ private logger;
31
+ name: string;
32
+ description: string;
33
+ extendedDescription: string;
34
+ helpUrl: string;
35
+ arguments: {
36
+ name: string;
37
+ description: string;
38
+ }[];
39
+ alias: string;
40
+ group: string;
41
+ options: CommandOptions;
42
+ constructor(install: InstallMain,
43
+ /**
44
+ * workspace extension.
45
+ */
46
+ workspace: Workspace,
47
+ /**
48
+ * logger extension.
49
+ */
50
+ logger: Logger);
51
+ report([packages]: [string[]], options: InstallCmdOptions): Promise<string>;
52
+ }
53
+ export declare function getAnotherInstallRequiredOutput(recurringInstall?: boolean, oldNonLoadedEnvs?: string[]): string;
54
+ export {};
@@ -0,0 +1,183 @@
1
+ import { CompilerMain } from '@teambit/compiler';
2
+ import { CLIMain } from '@teambit/cli';
3
+ import { Workspace } from '@teambit/workspace';
4
+ import { GenerateResult, GeneratorMain } from '@teambit/generator';
5
+ import { ApplicationMain } from '@teambit/application';
6
+ import { VariantsMain } from '@teambit/variants';
7
+ import { Component, ComponentMap } from '@teambit/component';
8
+ import { SlotRegistry } from '@teambit/harmony';
9
+ import { CodemodResult, NodeModulesLinksResult } from '@teambit/workspace.modules.node-modules-linker';
10
+ import { EnvsMain } from '@teambit/envs';
11
+ import { IpcEventsMain } from '@teambit/ipc-events';
12
+ import { WorkspaceDependencyLifecycleType, DependencyResolverMain, LinkingOptions, LinkResults, WorkspacePolicy } from '@teambit/dependency-resolver';
13
+ import { WorkspaceConfigFilesMain } from '@teambit/workspace-config-files';
14
+ import { Logger, LoggerMain } from '@teambit/logger';
15
+ import { IssuesMain } from '@teambit/issues';
16
+ export type WorkspaceLinkOptions = LinkingOptions & {
17
+ rootPolicy?: WorkspacePolicy;
18
+ linkToBitRoots?: boolean;
19
+ includePeers?: boolean;
20
+ };
21
+ export type WorkspaceLinkResults = {
22
+ legacyLinkResults?: NodeModulesLinksResult[];
23
+ legacyLinkCodemodResults?: CodemodResult[];
24
+ } & LinkResults;
25
+ export type WorkspaceInstallOptions = {
26
+ addMissingDeps?: boolean;
27
+ addMissingPeers?: boolean;
28
+ lifecycleType?: WorkspaceDependencyLifecycleType;
29
+ dedupe?: boolean;
30
+ import?: boolean;
31
+ copyPeerToRuntimeOnRoot?: boolean;
32
+ copyPeerToRuntimeOnComponents?: boolean;
33
+ updateExisting?: boolean;
34
+ skipIfExisting?: boolean;
35
+ savePrefix?: string;
36
+ compile?: boolean;
37
+ includeOptionalDeps?: boolean;
38
+ updateAll?: boolean;
39
+ recurringInstall?: boolean;
40
+ optimizeReportForNonTerminal?: boolean;
41
+ lockfileOnly?: boolean;
42
+ writeConfigFiles?: boolean;
43
+ skipPrune?: boolean;
44
+ };
45
+ export type ModulesInstallOptions = Omit<WorkspaceInstallOptions, 'updateExisting' | 'lifecycleType' | 'import'>;
46
+ type PreLink = (linkOpts?: WorkspaceLinkOptions) => Promise<void>;
47
+ type PreInstall = (installOpts?: WorkspaceInstallOptions) => Promise<void>;
48
+ type PostInstall = () => Promise<void>;
49
+ type PreLinkSlot = SlotRegistry<PreLink>;
50
+ type PreInstallSlot = SlotRegistry<PreInstall>;
51
+ type PostInstallSlot = SlotRegistry<PostInstall>;
52
+ export declare class InstallMain {
53
+ private dependencyResolver;
54
+ private logger;
55
+ private workspace;
56
+ private variants;
57
+ private compiler;
58
+ private envs;
59
+ private wsConfigFiles;
60
+ private app;
61
+ private generator;
62
+ private preLinkSlot;
63
+ private preInstallSlot;
64
+ private postInstallSlot;
65
+ private ipcEvents;
66
+ private visitedAspects;
67
+ constructor(dependencyResolver: DependencyResolverMain, logger: Logger, workspace: Workspace, variants: VariantsMain, compiler: CompilerMain, envs: EnvsMain, wsConfigFiles: WorkspaceConfigFilesMain, app: ApplicationMain, generator: GeneratorMain, preLinkSlot: PreLinkSlot, preInstallSlot: PreInstallSlot, postInstallSlot: PostInstallSlot, ipcEvents: IpcEventsMain);
68
+ /**
69
+ * Install dependencies for all components in the workspace
70
+ *
71
+ * @returns
72
+ * @memberof Workspace
73
+ */
74
+ install(packages?: string[], options?: WorkspaceInstallOptions): Promise<ComponentMap<string>>;
75
+ registerPreLink(fn: PreLink): void;
76
+ registerPreInstall(fn: PreInstall): void;
77
+ registerPostInstall(fn: PostInstall): void;
78
+ onComponentCreate(generateResults: GenerateResult[]): Promise<void>;
79
+ private _addPackages;
80
+ private _installModules;
81
+ private _getComponentsManifestsAndRootPolicy;
82
+ /**
83
+ * The function `tryWriteConfigFiles` attempts to write workspace config files, and if it fails, it logs an error
84
+ * message.
85
+ * @returns If the condition `!shouldWrite` is true, then nothing is being returned. Otherwise, if the `writeConfigFiles`
86
+ * function is successfully executed, nothing is being returned. If an error occurs during the execution of
87
+ * `writeConfigFiles`, an error message is being returned.
88
+ */
89
+ private tryWriteConfigFiles;
90
+ private addConfiguredAspectsToWorkspacePolicy;
91
+ private addConfiguredGeneratorEnvsToWorkspacePolicy;
92
+ private _addMissingPackagesToRootPolicy;
93
+ private _getMissingPackagesWithoutRootDeps;
94
+ private _getAllMissingPackages;
95
+ private _getComponentsManifests;
96
+ /**
97
+ * This function returns a list of old non-loaded environments names.
98
+ * @returns an array of strings called `oldNonLoadedEnvs`. This array contains the names of environment variables that
99
+ * failed to load as extensions and are also don't have an env.jsonc file.
100
+ * If this list is not empty, then the user might need to run another install to make sure all dependencies resolved
101
+ * correctly
102
+ */
103
+ getOldNonLoadedEnvs(): string[];
104
+ private _updateRootDirs;
105
+ private _getRootManifests;
106
+ private _getEnvManifests;
107
+ private _getEnvDependencies;
108
+ /**
109
+ * Return the package name of the env with its version.
110
+ * (only if the env is not a core env and is not in the workspace)
111
+ * @param envId
112
+ * @returns
113
+ */
114
+ private _getEnvPackage;
115
+ private _getAppManifests;
116
+ private _getAllUsedEnvIds;
117
+ /**
118
+ * Updates out-of-date dependencies in the workspace.
119
+ *
120
+ * @param options.all {Boolean} updates all outdated dependencies without showing a prompt.
121
+ */
122
+ updateDependencies(options: {
123
+ forceVersionBump?: 'major' | 'minor' | 'patch' | 'compatible';
124
+ patterns?: string[];
125
+ all: boolean;
126
+ }): Promise<ComponentMap<string> | null>;
127
+ addDuplicateComponentAndPackageIssue(components: Component[]): Promise<void>;
128
+ private _getComponentsWithDependencyPolicies;
129
+ private _variantPatternsToDepPolicesDict;
130
+ private _updateComponentsConfig;
131
+ private _updateVariantsPolicies;
132
+ /**
133
+ * Uninstall the specified packages from dependencies.
134
+ *
135
+ * @param {string[]} the list of packages that should be removed from dependencies.
136
+ */
137
+ uninstallDependencies(packages: string[]): Promise<ComponentMap<string>>;
138
+ /**
139
+ * This function returns all the locations of the external links that should be created inside node_modules.
140
+ * This information may then be passed to the package manager, which will create the links on its own.
141
+ */
142
+ calculateLinks(options?: WorkspaceLinkOptions): Promise<{
143
+ linkResults: WorkspaceLinkResults;
144
+ linkedRootDeps: Record<string, string>;
145
+ }>;
146
+ linkCodemods(compDirMap: ComponentMap<string>, options?: {
147
+ rewire?: boolean;
148
+ }): Promise<{
149
+ linksResults: NodeModulesLinksResult[];
150
+ codemodResults: any;
151
+ }>;
152
+ link(options?: WorkspaceLinkOptions): Promise<WorkspaceLinkResults>;
153
+ private _linkAllComponentsToBitRoots;
154
+ private getRootComponentDirByRootId;
155
+ /**
156
+ * Generate a filter to pass to the installer
157
+ * This will filter deps which are come from remotes which defined in scope.json
158
+ * those components comes from local remotes, usually doesn't have a package in a registry
159
+ * so no reason to try to install them (it will fail)
160
+ */
161
+ private generateFilterFnForDepsFromLocalRemote;
162
+ private getComponentsDirectory;
163
+ private onRootAspectAddedSubscriber;
164
+ private onAspectsResolveSubscriber;
165
+ static slots: (((registerFn: () => string) => SlotRegistry<PreLinkSlot>) | ((registerFn: () => string) => SlotRegistry<PreInstallSlot>))[];
166
+ static dependencies: import("@teambit/harmony").Aspect[];
167
+ static runtime: import("@teambit/harmony").RuntimeDefinition;
168
+ static provider([dependencyResolver, workspace, loggerExt, variants, cli, compiler, issues, envs, app, ipcEvents, generator, wsConfigFiles,]: [
169
+ DependencyResolverMain,
170
+ Workspace,
171
+ LoggerMain,
172
+ VariantsMain,
173
+ CLIMain,
174
+ CompilerMain,
175
+ IssuesMain,
176
+ EnvsMain,
177
+ ApplicationMain,
178
+ IpcEventsMain,
179
+ GeneratorMain,
180
+ WorkspaceConfigFilesMain
181
+ ], _: any, [preLinkSlot, preInstallSlot, postInstallSlot]: [PreLinkSlot, PreInstallSlot, PostInstallSlot]): Promise<InstallMain>;
182
+ }
183
+ export default InstallMain;
@@ -0,0 +1,7 @@
1
+ import { NodeModulesLinksResult } from '@teambit/workspace.modules.node-modules-linker';
2
+ type ComponentListLinksProps = {
3
+ componentListLinks?: NodeModulesLinksResult[];
4
+ verbose: boolean;
5
+ };
6
+ export declare function ComponentListLinks({ componentListLinks, verbose }: ComponentListLinksProps): string;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ import { CoreAspectLinkResult } from '@teambit/dependency-resolver';
2
+ type CoreAspectsLinksProps = {
3
+ coreAspectsLinks?: CoreAspectLinkResult[];
4
+ verbose: boolean;
5
+ };
6
+ export declare function CoreAspectsLinks({ coreAspectsLinks, verbose }: CoreAspectsLinksProps): string;
7
+ export {};
@@ -0,0 +1 @@
1
+ export declare function getPackageNameFromTarget(targetPath: string): string;
@@ -0,0 +1 @@
1
+ export { LinkCommand } from './link.cmd';
@@ -0,0 +1,12 @@
1
+ type LinkRowProps = {
2
+ title: string;
3
+ target: string;
4
+ padding?: number;
5
+ };
6
+ export declare function LinkRow({ title, target, padding }: LinkRowProps): string;
7
+ type VerboseLinkRowProps = {
8
+ from: string;
9
+ to: string;
10
+ };
11
+ export declare function VerboseLinkRow({ from, to }: VerboseLinkRowProps): string;
12
+ export {};
@@ -0,0 +1,2 @@
1
+ import { LinkToDirResult } from '@teambit/dependency-resolver';
2
+ export declare function linkToDir(links?: LinkToDirResult[]): string;
@@ -0,0 +1,46 @@
1
+ import { Command, CommandOptions } from '@teambit/cli';
2
+ import { Logger } from '@teambit/logger';
3
+ import { Workspace } from '@teambit/workspace';
4
+ import { InstallMain, WorkspaceLinkResults } from '../install.main.runtime';
5
+ type LinkCommandOpts = {
6
+ rewire: boolean;
7
+ verbose: boolean;
8
+ target: string;
9
+ skipFetchingObjects?: boolean;
10
+ peers?: boolean;
11
+ };
12
+ export declare class LinkCommand implements Command {
13
+ private install;
14
+ /**
15
+ * workspace extension.
16
+ */
17
+ private workspace;
18
+ /**
19
+ * logger extension.
20
+ */
21
+ private logger;
22
+ name: string;
23
+ alias: string;
24
+ description: string;
25
+ helpUrl: string;
26
+ extendedDescription: string;
27
+ group: string;
28
+ private: boolean;
29
+ arguments: {
30
+ name: string;
31
+ description: string;
32
+ }[];
33
+ options: CommandOptions;
34
+ constructor(install: InstallMain,
35
+ /**
36
+ * workspace extension.
37
+ */
38
+ workspace: Workspace,
39
+ /**
40
+ * logger extension.
41
+ */
42
+ logger: Logger);
43
+ report([ids]: [string[]], opts: LinkCommandOpts): Promise<string>;
44
+ json([ids]: [string[]], opts: LinkCommandOpts): Promise<WorkspaceLinkResults>;
45
+ }
46
+ export {};
@@ -0,0 +1,7 @@
1
+ import { NestedNMDepsLinksResult } from '@teambit/dependency-resolver';
2
+ type NestedComponentLinksLinksProps = {
3
+ nestedDepsInNmLinks?: NestedNMDepsLinksResult[];
4
+ verbose: boolean;
5
+ };
6
+ export declare function NestedComponentLinksLinks({ nestedDepsInNmLinks, verbose }: NestedComponentLinksLinksProps): string;
7
+ export {};
@@ -0,0 +1,6 @@
1
+ import { CodemodResult } from '@teambit/workspace.modules.node-modules-linker';
2
+ type RewireRowProps = {
3
+ legacyCodemodResults?: CodemodResult[];
4
+ };
5
+ export declare function RewireRow({ legacyCodemodResults }: RewireRowProps): string;
6
+ export {};
@@ -0,0 +1,12 @@
1
+ import { MergedOutdatedPkg } from '@teambit/dependency-resolver';
2
+ /**
3
+ * Lets the user pick the packages that should be updated.
4
+ */
5
+ export declare function pickOutdatedPkgs(outdatedPkgs: MergedOutdatedPkg[]): Promise<MergedOutdatedPkg[]>;
6
+ /**
7
+ * Groups the outdated packages and makes choices for enquirer's prompt.
8
+ */
9
+ export declare function makeOutdatedPkgChoices(outdatedPkgs: MergedOutdatedPkg[]): {
10
+ message: string;
11
+ choices: unknown;
12
+ }[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Command, CommandOptions } from '@teambit/cli';
2
+ import { InstallMain } from './install.main.runtime';
3
+ export default class UninstallCmd implements Command {
4
+ private install;
5
+ name: string;
6
+ description: string;
7
+ alias: string;
8
+ group: string;
9
+ options: CommandOptions;
10
+ constructor(install: InstallMain);
11
+ report([packages]: [string[]]): Promise<string>;
12
+ }
@@ -0,0 +1,26 @@
1
+ import { Command, CommandOptions } from '@teambit/cli';
2
+ import { InstallMain } from './install.main.runtime';
3
+ type UpdateCmdOptions = {
4
+ yes?: boolean;
5
+ patterns?: string[];
6
+ major?: boolean;
7
+ minor?: boolean;
8
+ patch?: boolean;
9
+ semver?: boolean;
10
+ };
11
+ export default class UpdateCmd implements Command {
12
+ private install;
13
+ name: string;
14
+ description: string;
15
+ helpUrl: string;
16
+ alias: string;
17
+ group: string;
18
+ arguments: {
19
+ name: string;
20
+ description: string;
21
+ }[];
22
+ options: CommandOptions;
23
+ constructor(install: InstallMain);
24
+ report([patterns]: [string[]], options: UpdateCmdOptions): Promise<string>;
25
+ }
26
+ export {};
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@teambit/install",
3
- "version": "1.0.228",
3
+ "version": "1.0.230",
4
4
  "homepage": "https://bit.cloud/teambit/workspace/install",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.workspace",
8
8
  "name": "install",
9
- "version": "1.0.228"
9
+ "version": "1.0.230"
10
10
  },
11
11
  "dependencies": {
12
12
  "chalk": "2.4.2",
@@ -22,23 +22,23 @@
22
22
  "@teambit/harmony": "0.4.6",
23
23
  "@teambit/bit-roots": "0.0.133",
24
24
  "@teambit/bit-error": "0.0.404",
25
- "@teambit/cli": "0.0.861",
26
- "@teambit/dependency-resolver": "1.0.228",
27
- "@teambit/logger": "0.0.954",
28
- "@teambit/workspace": "1.0.228",
29
- "@teambit/application": "1.0.228",
30
- "@teambit/compiler": "1.0.228",
31
- "@teambit/component-issues": "0.0.143",
25
+ "@teambit/cli": "0.0.862",
26
+ "@teambit/dependency-resolver": "1.0.230",
27
+ "@teambit/logger": "0.0.955",
28
+ "@teambit/workspace": "1.0.230",
29
+ "@teambit/application": "1.0.230",
30
+ "@teambit/compiler": "1.0.230",
31
+ "@teambit/component-issues": "0.0.144",
32
32
  "@teambit/component-package-version": "0.0.433",
33
- "@teambit/component": "1.0.228",
33
+ "@teambit/component": "1.0.230",
34
34
  "@teambit/dependencies.fs.linked-dependencies": "0.0.9",
35
- "@teambit/envs": "1.0.228",
36
- "@teambit/generator": "1.0.229",
37
- "@teambit/ipc-events": "1.0.228",
38
- "@teambit/issues": "1.0.228",
39
- "@teambit/variants": "0.0.1072",
40
- "@teambit/workspace-config-files": "1.0.228",
41
- "@teambit/workspace.modules.node-modules-linker": "0.0.167",
35
+ "@teambit/envs": "1.0.230",
36
+ "@teambit/generator": "1.0.231",
37
+ "@teambit/ipc-events": "1.0.230",
38
+ "@teambit/issues": "1.0.230",
39
+ "@teambit/variants": "0.0.1074",
40
+ "@teambit/workspace-config-files": "1.0.230",
41
+ "@teambit/workspace.modules.node-modules-linker": "0.0.168",
42
42
  "@teambit/toolbox.time.time-format": "0.0.496"
43
43
  },
44
44
  "devDependencies": {
@@ -49,7 +49,7 @@
49
49
  "chai": "4.3.0",
50
50
  "strip-ansi": "6.0.0",
51
51
  "@types/mocha": "9.1.0",
52
- "@teambit/harmony.envs.core-aspect-env": "0.0.30"
52
+ "@teambit/harmony.envs.core-aspect-env": "0.0.33"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@teambit/legacy": "1.0.624"
package/tsconfig.json CHANGED
@@ -20,8 +20,7 @@
20
20
  "emitDeclarationOnly": true,
21
21
  "strict": true,
22
22
  "strictPropertyInitialization": false,
23
- "noImplicitAny": false,
24
- "composite": true
23
+ "noImplicitAny": false
25
24
  },
26
25
  "exclude": [
27
26
  "artifacts",
@@ -36,43 +35,5 @@
36
35
  "include": [
37
36
  "**/*",
38
37
  "**/*.json"
39
- ],
40
- "references": [
41
- {
42
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.harmony_cli@0.0.861"
43
- },
44
- {
45
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.harmony_logger@0.0.954"
46
- },
47
- {
48
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.workspace_workspace@1.0.228"
49
- },
50
- {
51
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.harmony_application@1.0.228"
52
- },
53
- {
54
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.compilation_compiler@1.0.228"
55
- },
56
- {
57
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.component_component@1.0.228"
58
- },
59
- {
60
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.envs_envs@1.0.228"
61
- },
62
- {
63
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.generator_generator@1.0.229"
64
- },
65
- {
66
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.harmony_ipc-events@1.0.228"
67
- },
68
- {
69
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.component_issues@1.0.228"
70
- },
71
- {
72
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.workspace_variants@0.0.1072"
73
- },
74
- {
75
- "path": "/home/circleci/Library/Caches/Bit/capsules/8891be5ad3d35bfc38b9cd90c0e05b598a5a55af/teambit.workspace_workspace-config-files@1.0.228"
76
- }
77
38
  ]
78
39
  }