@crowdin/app-project-module 0.98.0-cf-1 → 0.98.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/out/index.js +10 -25
  2. package/out/middlewares/crowdin-client.d.ts +1 -1
  3. package/out/middlewares/integration-credentials.d.ts +1 -1
  4. package/out/middlewares/integration-credentials.js +1 -4
  5. package/out/middlewares/render-ui-module.d.ts +3 -3
  6. package/out/middlewares/render-ui-module.js +13 -9
  7. package/out/middlewares/ui-module.d.ts +1 -1
  8. package/out/middlewares/ui-module.js +1 -4
  9. package/out/modules/about.d.ts +1 -1
  10. package/out/modules/about.js +2 -8
  11. package/out/modules/ai-prompt-provider/handlers/compile.d.ts +1 -1
  12. package/out/modules/ai-prompt-provider/index.js +2 -4
  13. package/out/modules/ai-provider/handlers/chat-completions.d.ts +1 -1
  14. package/out/modules/ai-provider/handlers/get-model-list.d.ts +1 -1
  15. package/out/modules/ai-provider/index.js +2 -4
  16. package/out/modules/ai-request-processors/handler.d.ts +1 -1
  17. package/out/modules/ai-tools/handlers/tool-calls.d.ts +1 -1
  18. package/out/modules/ai-tools/index.js +1 -1
  19. package/out/modules/context-menu/index.js +2 -2
  20. package/out/modules/custom-mt/handlers/translate.d.ts +1 -1
  21. package/out/modules/custom-mt/index.js +1 -3
  22. package/out/modules/custom-spell-check/handlers/get-languages-list.d.ts +1 -1
  23. package/out/modules/custom-spell-check/handlers/spell-check.d.ts +1 -1
  24. package/out/modules/custom-spell-check/index.js +4 -4
  25. package/out/modules/editor-right-panel/index.js +1 -1
  26. package/out/modules/external-qa-check/handlers/validate.d.ts +1 -1
  27. package/out/modules/external-qa-check/index.js +2 -2
  28. package/out/modules/file-processing/handlers/custom-file-format.d.ts +1 -1
  29. package/out/modules/file-processing/handlers/file-download.d.ts +1 -1
  30. package/out/modules/file-processing/handlers/pre-post-process.d.ts +1 -1
  31. package/out/modules/form-data-display.d.ts +1 -1
  32. package/out/modules/form-data-save.d.ts +1 -1
  33. package/out/modules/install.d.ts +1 -1
  34. package/out/modules/integration/handlers/crowdin-file-progress.d.ts +1 -1
  35. package/out/modules/integration/handlers/crowdin-files.d.ts +1 -1
  36. package/out/modules/integration/handlers/crowdin-files.js +6 -4
  37. package/out/modules/integration/handlers/crowdin-project.d.ts +1 -1
  38. package/out/modules/integration/handlers/crowdin-update.d.ts +1 -1
  39. package/out/modules/integration/handlers/crowdin-update.js +18 -4
  40. package/out/modules/integration/handlers/crowdin-webhook.d.ts +1 -1
  41. package/out/modules/integration/handlers/integration-data.d.ts +1 -1
  42. package/out/modules/integration/handlers/integration-data.js +17 -13
  43. package/out/modules/integration/handlers/integration-login.d.ts +1 -1
  44. package/out/modules/integration/handlers/integration-logout.d.ts +1 -1
  45. package/out/modules/integration/handlers/integration-update.d.ts +1 -1
  46. package/out/modules/integration/handlers/integration-webhook.d.ts +1 -1
  47. package/out/modules/integration/handlers/invite-users.d.ts +1 -1
  48. package/out/modules/integration/handlers/job-cancel.d.ts +1 -1
  49. package/out/modules/integration/handlers/job-info.d.ts +1 -1
  50. package/out/modules/integration/handlers/main.d.ts +1 -1
  51. package/out/modules/integration/handlers/main.js +3 -13
  52. package/out/modules/integration/handlers/oauth-login.d.ts +1 -1
  53. package/out/modules/integration/handlers/oauth-login.js +2 -10
  54. package/out/modules/integration/handlers/oauth-polling.d.ts +1 -1
  55. package/out/modules/integration/handlers/oauth-url.d.ts +1 -1
  56. package/out/modules/integration/handlers/settings-save.d.ts +1 -1
  57. package/out/modules/integration/handlers/settings.d.ts +1 -1
  58. package/out/modules/integration/handlers/sync-settings-save.d.ts +1 -1
  59. package/out/modules/integration/handlers/sync-settings.d.ts +1 -1
  60. package/out/modules/integration/handlers/user-errors.d.ts +1 -1
  61. package/out/modules/integration/handlers/users.d.ts +1 -1
  62. package/out/modules/integration/index.js +21 -27
  63. package/out/modules/integration/types.d.ts +11 -1
  64. package/out/modules/integration/util/defaults.js +51 -45
  65. package/out/modules/integration/util/files.d.ts +1 -0
  66. package/out/modules/integration/util/files.js +52 -4
  67. package/out/modules/integration/util/job.d.ts +1 -1
  68. package/out/modules/integration/util/job.js +3 -2
  69. package/out/modules/integration/util/types.d.ts +2 -0
  70. package/out/modules/modal/index.js +2 -2
  71. package/out/modules/organization-menu/index.js +4 -6
  72. package/out/modules/organization-settings-menu/index.js +4 -6
  73. package/out/modules/profile-resources-menu/index.js +4 -6
  74. package/out/modules/profile-settings-menu/index.js +4 -6
  75. package/out/modules/project-menu/index.js +1 -1
  76. package/out/modules/project-menu-crowdsource/index.js +1 -1
  77. package/out/modules/project-reports/index.js +2 -4
  78. package/out/modules/project-tools/index.js +2 -4
  79. package/out/modules/status.d.ts +1 -1
  80. package/out/modules/subscription-paid.d.ts +1 -1
  81. package/out/modules/uninstall.d.ts +1 -1
  82. package/out/modules/webhooks/handlers/webhook-handler.d.ts +1 -1
  83. package/out/modules/workflow-step-type/handlers/delete-step.d.ts +1 -1
  84. package/out/modules/workflow-step-type/handlers/step-settings-save.d.ts +1 -1
  85. package/out/modules/workflow-step-type/index.js +2 -3
  86. package/out/storage/index.js +1 -8
  87. package/out/storage/mysql.d.ts +1 -1
  88. package/out/storage/mysql.js +9 -1
  89. package/out/storage/postgre.d.ts +1 -1
  90. package/out/storage/postgre.js +11 -4
  91. package/out/storage/sqlite.d.ts +1 -1
  92. package/out/storage/sqlite.js +10 -4
  93. package/out/types.d.ts +1 -11
  94. package/out/util/credentials-masker.d.ts +1 -1
  95. package/out/util/handlebars.d.ts +1 -0
  96. package/out/util/handlebars.js +46 -0
  97. package/out/util/index.d.ts +0 -2
  98. package/out/util/index.js +2 -14
  99. package/out/views/about.handlebars +102 -0
  100. package/out/views/error.handlebars +54 -0
  101. package/out/views/form.handlebars +30 -0
  102. package/out/views/install.handlebars +16 -0
  103. package/out/views/login.handlebars +331 -0
  104. package/out/views/main.handlebars +1901 -0
  105. package/out/views/oauth.handlebars +11 -0
  106. package/out/views/partials/head.handlebars +53 -0
  107. package/out/views/subscription.handlebars +26 -0
  108. package/package.json +11 -12
  109. package/out/storage/d1.d.ts +0 -99
  110. package/out/storage/d1.js +0 -769
  111. package/out/util/jsx-renderer.d.ts +0 -6
  112. package/out/util/jsx-renderer.js +0 -13
  113. package/out/util/static-files.d.ts +0 -19
  114. package/out/util/static-files.js +0 -80
  115. package/out/views/AboutPage.d.ts +0 -9
  116. package/out/views/AboutPage.js +0 -79
  117. package/out/views/ErrorPage.d.ts +0 -18
  118. package/out/views/ErrorPage.js +0 -56
  119. package/out/views/FormPage.d.ts +0 -13
  120. package/out/views/FormPage.js +0 -27
  121. package/out/views/InstallPage.d.ts +0 -10
  122. package/out/views/InstallPage.js +0 -22
  123. package/out/views/LoginPage.d.ts +0 -33
  124. package/out/views/LoginPage.js +0 -199
  125. package/out/views/MainPage.d.ts +0 -79
  126. package/out/views/MainPage.js +0 -1613
  127. package/out/views/OAuthPage.d.ts +0 -7
  128. package/out/views/OAuthPage.js +0 -17
  129. package/out/views/SubscriptionPage.d.ts +0 -7
  130. package/out/views/SubscriptionPage.js +0 -26
  131. package/out/views/index.d.ts +0 -13
  132. package/out/views/index.js +0 -25
  133. package/out/views/layout/Head.d.ts +0 -9
  134. package/out/views/layout/Head.js +0 -54
package/out/types.d.ts CHANGED
@@ -10,8 +10,6 @@ import { IntegrationLogic } from './modules/integration/types';
10
10
  import { Storage } from './storage';
11
11
  import { MySQLStorageConfig } from './storage/mysql';
12
12
  import { PostgreStorageConfig } from './storage/postgre';
13
- import { D1StorageConfig } from './storage/d1';
14
- import type { Fetcher } from '@cloudflare/workers-types';
15
13
  import { ApiModule } from './modules/api/types';
16
14
  import { LogErrorFunction, LogFunction } from './util/logger';
17
15
  import { AiProviderModule } from './modules/ai-provider/types';
@@ -102,14 +100,6 @@ export interface ClientConfig extends ImagePath {
102
100
  * config to configure MySQL as a storage
103
101
  */
104
102
  mysqlConfig?: MySQLStorageConfig;
105
- /**
106
- * config to configure Cloudflare D1 as a storage
107
- */
108
- d1Config?: D1StorageConfig;
109
- /**
110
- * Cloudflare Workers Assets Fetcher
111
- */
112
- assets?: Fetcher;
113
103
  /**
114
104
  * integration module logic
115
105
  */
@@ -278,7 +268,7 @@ export interface Environments {
278
268
  }
279
269
  type Environment = 'crowdin' | 'crowdin-enterprise';
280
270
  export type Config = ClientConfig & {
281
- baseUrl?: string;
271
+ baseUrl: string;
282
272
  clientId: string;
283
273
  clientSecret: string;
284
274
  port: number;
@@ -6,5 +6,5 @@ declare function getRequestCredentialsMasker({ moduleConfig, dataPath, }: {
6
6
  moduleConfig?: UiModule;
7
7
  dataPath?: string;
8
8
  }): (req: Request | CrowdinClientRequest, res: Response, next: Function) => any;
9
- declare function postRequestCredentialsMasker(moduleConfig?: UiModule, credentialsExtractor?: Function): (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>> | CrowdinClientRequest, res: Response<any, Record<string, any>>, next: Function) => void;
9
+ declare function postRequestCredentialsMasker(moduleConfig?: UiModule, credentialsExtractor?: Function): (req: CrowdinClientRequest | Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: Function) => void;
10
10
  export { getRequestCredentialsMasker, postRequestCredentialsMasker, maskKey };
@@ -0,0 +1 @@
1
+ export declare const engine: (path: string, options: object, callback: (e: any, rendered: string) => void) => void;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.engine = void 0;
7
+ const express_handlebars_1 = __importDefault(require("express-handlebars"));
8
+ exports.engine = (0, express_handlebars_1.default)({
9
+ layoutsDir: '',
10
+ defaultLayout: '',
11
+ helpers: {
12
+ ifeq: function (a, b, options) {
13
+ if (a === b) {
14
+ return options.fn(this);
15
+ }
16
+ return options.inverse(this);
17
+ },
18
+ checkLength: function (a, b, options) {
19
+ if (a.length > b) {
20
+ return options.fn(this);
21
+ }
22
+ return options.inverse(this);
23
+ },
24
+ in: function (a, b, options) {
25
+ if (a !== undefined && a !== null && b !== undefined && b !== null) {
26
+ let bArray;
27
+ if (Array.isArray(b)) {
28
+ bArray = b.map((item) => item.toString());
29
+ }
30
+ else {
31
+ bArray = b.toString().split(' ');
32
+ }
33
+ if (bArray.includes(a === null || a === void 0 ? void 0 : a.toString())) {
34
+ return options.fn(this);
35
+ }
36
+ }
37
+ return options.inverse(this);
38
+ },
39
+ or: function (a, b, options) {
40
+ return a || b ? options.fn(this) : options.inverse(this);
41
+ },
42
+ incrementedIndex: function (index) {
43
+ return index + 1;
44
+ },
45
+ },
46
+ });
@@ -1,11 +1,9 @@
1
1
  import { Request, Response } from 'express';
2
2
  import { Config, CrowdinClientRequest, ImagePath, UnauthorizedConfig } from '../types';
3
- export { renderJSX } from './jsx-renderer';
4
3
  export declare class CodeError extends Error {
5
4
  code: number | undefined;
6
5
  constructor(message: string, code?: number);
7
6
  }
8
- export declare function extractBaseUrlFromRequest(req: Request): string;
9
7
  export declare function runAsyncWrapper(callback: Function): (req: Request | CrowdinClientRequest, res: Response, next: Function) => void;
10
8
  export declare function encryptData(config: Config, data: string): string;
11
9
  export declare function decryptData(config: Config, data: string): string;
package/out/util/index.js CHANGED
@@ -32,16 +32,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
32
32
  });
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.getFormattedDate = exports.validateEmail = exports.prepareFormDataMetadataId = exports.getPreviousDate = exports.isJson = exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.extractBaseUrlFromRequest = exports.CodeError = exports.renderJSX = void 0;
35
+ exports.getFormattedDate = exports.validateEmail = exports.prepareFormDataMetadataId = exports.getPreviousDate = exports.isJson = exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
36
36
  const crypto = __importStar(require("crypto-js"));
37
37
  const storage_1 = require("../storage");
38
38
  const types_1 = require("../types");
39
39
  const logger_1 = require("./logger");
40
40
  const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
41
- const jsx_renderer_1 = require("./jsx-renderer");
42
- const views_1 = require("../views");
43
- var jsx_renderer_2 = require("./jsx-renderer");
44
- Object.defineProperty(exports, "renderJSX", { enumerable: true, get: function () { return jsx_renderer_2.renderJSX; } });
45
41
  class CodeError extends Error {
46
42
  constructor(message, code) {
47
43
  super(message);
@@ -49,12 +45,6 @@ class CodeError extends Error {
49
45
  }
50
46
  }
51
47
  exports.CodeError = CodeError;
52
- function extractBaseUrlFromRequest(req) {
53
- const protocol = req.protocol;
54
- const host = req.get('host');
55
- return `${protocol}://${host}`;
56
- }
57
- exports.extractBaseUrlFromRequest = extractBaseUrlFromRequest;
58
48
  function isCrowdinClientRequest(req) {
59
49
  return req.crowdinContext;
60
50
  }
@@ -71,9 +61,7 @@ function handleError(err, req, res) {
71
61
  if (!res.headersSent) {
72
62
  const errorMessage = { message: (0, logger_1.getErrorMessage)(err), code };
73
63
  if ('integrationCredentials' in req) {
74
- const html = (0, jsx_renderer_1.renderJSX)(views_1.ErrorPage, errorMessage);
75
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
76
- res.send(html);
64
+ res.render('error', errorMessage);
77
65
  }
78
66
  else {
79
67
  res.status(code).send({ error: errorMessage });
@@ -0,0 +1,102 @@
1
+ <html>
2
+ <head>
3
+ <title>{{name}}</title>
4
+ <meta charset="utf-8" />
5
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+
8
+ {{#if storeLink}}
9
+ <link rel="canonical" href="{{storeLink}}">
10
+ {{/if}}
11
+
12
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
13
+ <link href="/assets/css/about.css" media="screen" rel="stylesheet" type="text/css">
14
+ </head>
15
+ <body>
16
+ <header id="header" class="navbar navbar-expand-lg fixed-top crowdin-navbar">
17
+ <a itemprop="url" class="navbar-brand crowdin-navbar__logo" href="https://crowdin.com" title="Crowdin — Localization Management Platform">
18
+ <svg class="d-none d-md-block d-lg-block default-logo" width="180" height="54" aria-labelledby="crowdinLogoTitle">
19
+ <title id="crowdinLogoTitle">Crowdin</title>
20
+ <image class="d-none d-md-block d-lg-block" href="/assets/img/crowdin.svg" width="180" height="54" alt="Crowdin" />
21
+ </svg>
22
+ <svg class="d-block d-md-none d-lg-none default-logo" width="173" height="32">
23
+ <image class="d-block d-md-none d-lg-none" href="/assets/img/crowdin_small.svg" width="173" height="32" alt="Crowdin"/>
24
+ </svg>
25
+ </a>
26
+ <div class="flex-nowrap justify-content-lg-end ml-auto my-lg-0">
27
+ <div class="pr-0 ml-2 my-2">
28
+ <span class="crowdin-navbar__nav-link contact ">
29
+ <a title="Contact" href="https://crowdin.com/contacts">Contact</a>
30
+ </span>
31
+ </div>
32
+ </div>
33
+ </header>
34
+ <div class="main">
35
+ <div class="container">
36
+ <div class="row crwd__product-template__header align-items-center">
37
+
38
+ <div class="offset-lg-1 col-lg-2 product-single__photo-wrapper crwd__product-single__photo-wrapper">
39
+ <div class="product-single__photo text-center mb-3 mb-lg-0">
40
+ <div class="image-holder">
41
+ <img width="200" src="{{logo}}" alt="{{name}}" id="FeaturedImage-product-template" class="img-fluid lazyloaded ls-is-cached product-featured-img" style="position: unset;">
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <div class=" col-lg-8 crwd__product-template__header__title-container">
46
+ <div class="product-single__meta">
47
+ <div class="section-header">
48
+ <h1 class="product-single__title text-center text-lg-left">
49
+ <span>{{name}}</span>
50
+ </h1>
51
+ <div class="description">
52
+ {{name}} extends the default functionality available in Crowdin and Crowdin Enterprise by providing additional capabilities to enhance your localization workflows.
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ <div class="row">
59
+ <div class="offset-lg-1 col-lg-10">
60
+ <p>To install this app, you can use either of the following methods: </p>
61
+ <ol>
62
+ <li>Install it directly from the <a href="https://store.crowdin.com/" target="_blank">Crowdin Store</a>, if available.</li>
63
+ <li>Install it manually using the manifest URL below.</li>
64
+ </ol>
65
+ <p>For detailed steps, follow the <a href="https://support.crowdin.com/developer/crowdin-apps-installation/" target="_blank">App Installation</a></p>
66
+
67
+ <div class="mb-3">
68
+ <label for="manifest-url" class="form-label">Paste the following manifest URL when prompted during manual installation:</label>
69
+ <div class="input-group">
70
+ <input
71
+ type="text"
72
+ class="form-control"
73
+ id="manifest-url"
74
+ value="{{manifest}}"
75
+ readonly
76
+ >
77
+ <button class="btn btn-outline-secondary" type="button" id="copy-button">
78
+ Copy
79
+ </button>
80
+ </div>
81
+ </div>
82
+
83
+
84
+
85
+ {{#if storeLink}}
86
+ <div>Read more about <a href="{{storeLink}}" target="_blank" title="{{name}} on Crowdin Store">{{name}}</a>.</div>
87
+ {{/if}}
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </body>
93
+ <script>
94
+ document.getElementById('copy-button').addEventListener('click', async () => {
95
+ const text = document.getElementById('manifest-url').value;
96
+ await navigator.clipboard.writeText(text);
97
+ const btn = document.getElementById('copy-button');
98
+ btn.textContent = 'Copied!';
99
+ setTimeout(() => btn.textContent = 'Copy', 1500);
100
+ });
101
+ </script>
102
+ </html>
@@ -0,0 +1,54 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ {{> head}}
4
+
5
+ <body>
6
+ <div class="i_w">
7
+ <div class="error-page">
8
+ <div>
9
+ <div class="error-page-message">
10
+ <crowdin-h3>{{ message }}</crowdin-h3>
11
+ {{#if owners}}
12
+ <crowdin-p>This integration allows only one connection per project to ensure consistent configuration and prevent file import or synchronization issues.</crowdin-p>
13
+ {{#if owners.[1]}}
14
+ <crowdin-p class="mt-2">Managed by:</crowdin-p>
15
+ <ul>
16
+ {{#each owners}}
17
+ <li><crowdin-a href="#" onclick="contactUser({{this.id}})">{{this.name}}</crowdin-a></li>
18
+ {{/each}}
19
+ </ul>
20
+ <crowdin-p class="mt-2">To request access, please contact one of the project members listed above.</crowdin-p>
21
+ {{else}}
22
+ <crowdin-p class="mt-2">Managed by: <crowdin-a href="#" onclick="contactUser({{owners.[0].id}})">{{owners.[0].name}}</crowdin-a></crowdin-p>
23
+ <crowdin-p class="mt-2">To request access, please contact the project member listed above.</crowdin-p>
24
+ {{/if}}
25
+ {{/if}}
26
+ </div>
27
+ {{#unless hideActions}}
28
+ <div class="error-page-action">
29
+ <crowdin-button outlined onclick="integrationLogout()">Log out</crowdin-button>
30
+ <span> or <crowdin-a href="https://crowdin.com/contacts" target="_blank">contact us</crowdin-a> for help</span>
31
+ </div>
32
+ {{/unless}}
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </body>
37
+
38
+ </html>
39
+ <script>
40
+ function integrationLogout() {
41
+ checkOrigin()
42
+ .then(queryParams => fetch(`api/logout${queryParams}`, { method: 'POST' }))
43
+ .then(checkResponse)
44
+ .then(reloadLocation)
45
+ .then(localStorage.removeItem('revised_{{name}}'))
46
+ .catch(e => catchRejection(e, 'Looks like you are not logged in'));
47
+ }
48
+
49
+ function contactUser(userId) {
50
+ AP.getContext(function(context) {
51
+ AP.redirect(`${context.organization_id ? '/u' : ''}/messages/create/${userId}`);
52
+ });
53
+ }
54
+ </script>
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ {{> head}}
4
+ <body>
5
+ <div
6
+ class="i_w"
7
+ style='max-width:680px; position: relative;'
8
+ >
9
+ <crowdin-card
10
+ id="card"
11
+ is-shadowed
12
+ >
13
+ <div id="form"></div>
14
+ <div id="form-loading">
15
+ <crowdin-progress-indicator />
16
+ </div>
17
+ </crowdin-card>
18
+ </div>
19
+ <crowdin-toasts></crowdin-toasts>
20
+ <script>
21
+ /*<!--*/
22
+ var formGetDataUrl = '{{formGetDataUrl}}';
23
+ var formPostDataUrl = '{{formPostDataUrl}}';
24
+ var formSchema = {{{formSchema}}};
25
+ var formUiSchema = {{{formUiSchema}}};
26
+ /*-->*/
27
+ </script>
28
+ <script src="/assets/js/form.js"></script>
29
+ </body>
30
+ </html>
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ {{> head}}
4
+
5
+ <body>
6
+ <div class="i_w center">
7
+ <div>
8
+ <h1>Looks like {{ name }} is not installed yet!</h1>
9
+ <p>Contact your organization administrator to install it. More info on <a
10
+ href='https://support.crowdin.com'>Link
11
+ to how to install</a></p>
12
+ </div>
13
+ </div>
14
+ </body>
15
+
16
+ </html>