@atlaskit/embedded-document 0.7.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +978 -0
- package/LICENSE +13 -0
- package/build/tsconfig.json +17 -0
- package/dist/cjs/components/document.js +157 -0
- package/dist/cjs/components/toolbar.js +89 -0
- package/dist/cjs/consumers/consumer.js +102 -0
- package/dist/cjs/consumers/document-body.js +95 -0
- package/dist/cjs/consumers/with-document-actions.js +139 -0
- package/dist/cjs/context/context.js +71 -0
- package/dist/cjs/context/embedded-document.js +396 -0
- package/dist/cjs/index.js +47 -0
- package/dist/cjs/model/index.js +5 -0
- package/dist/cjs/provider/index.js +35 -0
- package/dist/cjs/provider/provider.js +5 -0
- package/dist/cjs/provider/service-provider.js +240 -0
- package/dist/cjs/version.json +5 -0
- package/dist/es2019/components/document.js +107 -0
- package/dist/es2019/components/toolbar.js +45 -0
- package/dist/es2019/consumers/consumer.js +62 -0
- package/dist/es2019/consumers/document-body.js +49 -0
- package/dist/es2019/consumers/with-document-actions.js +35 -0
- package/dist/es2019/context/context.js +19 -0
- package/dist/es2019/context/embedded-document.js +216 -0
- package/dist/es2019/index.js +5 -0
- package/dist/es2019/model/index.js +1 -0
- package/dist/es2019/provider/index.js +18 -0
- package/dist/es2019/provider/provider.js +1 -0
- package/dist/es2019/provider/service-provider.js +101 -0
- package/dist/es2019/version.json +5 -0
- package/dist/esm/components/document.js +136 -0
- package/dist/esm/components/toolbar.js +70 -0
- package/dist/esm/consumers/consumer.js +84 -0
- package/dist/esm/consumers/document-body.js +77 -0
- package/dist/esm/consumers/with-document-actions.js +119 -0
- package/dist/esm/context/context.js +59 -0
- package/dist/esm/context/embedded-document.js +375 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/model/index.js +1 -0
- package/dist/esm/provider/index.js +18 -0
- package/dist/esm/provider/provider.js +1 -0
- package/dist/esm/provider/service-provider.js +229 -0
- package/dist/esm/version.json +5 -0
- package/dist/types/components/document.d.ts +20 -0
- package/dist/types/components/toolbar.d.ts +6 -0
- package/dist/types/consumers/consumer.d.ts +23 -0
- package/dist/types/consumers/document-body.d.ts +13 -0
- package/dist/types/consumers/with-document-actions.d.ts +16 -0
- package/dist/types/context/context.d.ts +22 -0
- package/dist/types/context/embedded-document.d.ts +41 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/model/index.d.ts +19 -0
- package/dist/types/provider/index.d.ts +9 -0
- package/dist/types/provider/provider.d.ts +7 -0
- package/dist/types/provider/service-provider.d.ts +13 -0
- package/package.json +44 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports, "EmbeddedDocument", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function get() {
|
|
11
|
+
return _embeddedDocument.default;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, "DocumentBody", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function get() {
|
|
17
|
+
return _documentBody.default;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "WithDocumentActions", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function get() {
|
|
23
|
+
return _withDocumentActions.default;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(exports, "ServiceProvider", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function get() {
|
|
29
|
+
return _serviceProvider.default;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports, "Toolbar", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function get() {
|
|
35
|
+
return _toolbar.default;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
var _embeddedDocument = _interopRequireDefault(require("./context/embedded-document"));
|
|
40
|
+
|
|
41
|
+
var _documentBody = _interopRequireDefault(require("./consumers/document-body"));
|
|
42
|
+
|
|
43
|
+
var _withDocumentActions = _interopRequireDefault(require("./consumers/with-document-actions"));
|
|
44
|
+
|
|
45
|
+
var _serviceProvider = _interopRequireDefault(require("./provider/service-provider"));
|
|
46
|
+
|
|
47
|
+
var _toolbar = _interopRequireDefault(require("./components/toolbar"));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports, "ServiceProvider", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function get() {
|
|
11
|
+
return _serviceProvider.default;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
exports.getProvider = void 0;
|
|
15
|
+
|
|
16
|
+
var _serviceProvider = _interopRequireDefault(require("./service-provider"));
|
|
17
|
+
|
|
18
|
+
var getProvider = function getProvider(_ref) {
|
|
19
|
+
var provider = _ref.provider,
|
|
20
|
+
url = _ref.url;
|
|
21
|
+
|
|
22
|
+
if (provider) {
|
|
23
|
+
return provider;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (url) {
|
|
27
|
+
return new _serviceProvider.default({
|
|
28
|
+
url: url
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
throw new Error('Missing provider');
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
exports.getProvider = getProvider;
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
|
|
12
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
13
|
+
|
|
14
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
15
|
+
|
|
16
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
17
|
+
|
|
18
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
19
|
+
|
|
20
|
+
var _utilServiceSupport = require("@atlaskit/util-service-support");
|
|
21
|
+
|
|
22
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
23
|
+
|
|
24
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
25
|
+
|
|
26
|
+
function queryBuilder(data) {
|
|
27
|
+
return Object.keys(data).map(function (key) {
|
|
28
|
+
return [key, data[key]].map(encodeURIComponent).join('=');
|
|
29
|
+
}).join('&');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var ServiceProvider = /*#__PURE__*/function () {
|
|
33
|
+
function ServiceProvider(config) {
|
|
34
|
+
(0, _classCallCheck2.default)(this, ServiceProvider);
|
|
35
|
+
this.config = config;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
(0, _createClass2.default)(ServiceProvider, [{
|
|
39
|
+
key: "getDocument",
|
|
40
|
+
value: function () {
|
|
41
|
+
var _getDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(documentId, language) {
|
|
42
|
+
var document;
|
|
43
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
44
|
+
while (1) {
|
|
45
|
+
switch (_context.prev = _context.next) {
|
|
46
|
+
case 0:
|
|
47
|
+
_context.prev = 0;
|
|
48
|
+
_context.next = 3;
|
|
49
|
+
return _utilServiceSupport.utils.requestService(this.config, {
|
|
50
|
+
path: "document/".concat(documentId, "/").concat(language || '')
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
case 3:
|
|
54
|
+
document = _context.sent;
|
|
55
|
+
return _context.abrupt("return", document);
|
|
56
|
+
|
|
57
|
+
case 7:
|
|
58
|
+
_context.prev = 7;
|
|
59
|
+
_context.t0 = _context["catch"](0);
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.warn("Failed to get document: ".concat(JSON.stringify(_context.t0)));
|
|
62
|
+
return _context.abrupt("return", null);
|
|
63
|
+
|
|
64
|
+
case 11:
|
|
65
|
+
case "end":
|
|
66
|
+
return _context.stop();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}, _callee, this, [[0, 7]]);
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
function getDocument(_x, _x2) {
|
|
73
|
+
return _getDocument.apply(this, arguments);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return getDocument;
|
|
77
|
+
}()
|
|
78
|
+
}, {
|
|
79
|
+
key: "getDocumentByObjectId",
|
|
80
|
+
value: function () {
|
|
81
|
+
var _getDocumentByObjectId = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(objectId, language) {
|
|
82
|
+
var queryString, documents;
|
|
83
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
84
|
+
while (1) {
|
|
85
|
+
switch (_context2.prev = _context2.next) {
|
|
86
|
+
case 0:
|
|
87
|
+
_context2.prev = 0;
|
|
88
|
+
queryString = queryBuilder(_objectSpread({
|
|
89
|
+
objectId: objectId
|
|
90
|
+
}, language ? {
|
|
91
|
+
language: language
|
|
92
|
+
} : {}));
|
|
93
|
+
_context2.next = 4;
|
|
94
|
+
return _utilServiceSupport.utils.requestService(this.config, {
|
|
95
|
+
path: "document?".concat(queryString)
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
case 4:
|
|
99
|
+
documents = _context2.sent;
|
|
100
|
+
|
|
101
|
+
if (!(documents && documents.length)) {
|
|
102
|
+
_context2.next = 7;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return _context2.abrupt("return", documents[0].language[language || 'default'].versions[0]);
|
|
107
|
+
|
|
108
|
+
case 7:
|
|
109
|
+
return _context2.abrupt("return", null);
|
|
110
|
+
|
|
111
|
+
case 10:
|
|
112
|
+
_context2.prev = 10;
|
|
113
|
+
_context2.t0 = _context2["catch"](0);
|
|
114
|
+
// eslint-disable-next-line no-console
|
|
115
|
+
console.warn("Failed to get document: ".concat(JSON.stringify(_context2.t0)));
|
|
116
|
+
return _context2.abrupt("return", null);
|
|
117
|
+
|
|
118
|
+
case 14:
|
|
119
|
+
case "end":
|
|
120
|
+
return _context2.stop();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}, _callee2, this, [[0, 10]]);
|
|
124
|
+
}));
|
|
125
|
+
|
|
126
|
+
function getDocumentByObjectId(_x3, _x4) {
|
|
127
|
+
return _getDocumentByObjectId.apply(this, arguments);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return getDocumentByObjectId;
|
|
131
|
+
}()
|
|
132
|
+
}, {
|
|
133
|
+
key: "updateDocument",
|
|
134
|
+
value: function () {
|
|
135
|
+
var _updateDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(documentId, body, objectId, title, language) {
|
|
136
|
+
var document;
|
|
137
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
138
|
+
while (1) {
|
|
139
|
+
switch (_context3.prev = _context3.next) {
|
|
140
|
+
case 0:
|
|
141
|
+
_context3.prev = 0;
|
|
142
|
+
_context3.next = 3;
|
|
143
|
+
return _utilServiceSupport.utils.requestService(this.config, {
|
|
144
|
+
path: "document/".concat(documentId),
|
|
145
|
+
requestInit: {
|
|
146
|
+
headers: {
|
|
147
|
+
'Content-Type': 'application/json'
|
|
148
|
+
},
|
|
149
|
+
method: 'PUT',
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
body: body,
|
|
152
|
+
objectId: objectId,
|
|
153
|
+
title: title,
|
|
154
|
+
language: language
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
case 3:
|
|
160
|
+
document = _context3.sent;
|
|
161
|
+
return _context3.abrupt("return", document);
|
|
162
|
+
|
|
163
|
+
case 7:
|
|
164
|
+
_context3.prev = 7;
|
|
165
|
+
_context3.t0 = _context3["catch"](0);
|
|
166
|
+
// eslint-disable-next-line no-console
|
|
167
|
+
console.warn("Failed to update document: ".concat(JSON.stringify(_context3.t0)));
|
|
168
|
+
return _context3.abrupt("return", null);
|
|
169
|
+
|
|
170
|
+
case 11:
|
|
171
|
+
case "end":
|
|
172
|
+
return _context3.stop();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}, _callee3, this, [[0, 7]]);
|
|
176
|
+
}));
|
|
177
|
+
|
|
178
|
+
function updateDocument(_x5, _x6, _x7, _x8, _x9) {
|
|
179
|
+
return _updateDocument.apply(this, arguments);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return updateDocument;
|
|
183
|
+
}()
|
|
184
|
+
}, {
|
|
185
|
+
key: "createDocument",
|
|
186
|
+
value: function () {
|
|
187
|
+
var _createDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(body, objectId, title, language) {
|
|
188
|
+
var document;
|
|
189
|
+
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
190
|
+
while (1) {
|
|
191
|
+
switch (_context4.prev = _context4.next) {
|
|
192
|
+
case 0:
|
|
193
|
+
_context4.prev = 0;
|
|
194
|
+
_context4.next = 3;
|
|
195
|
+
return _utilServiceSupport.utils.requestService(this.config, {
|
|
196
|
+
path: "document",
|
|
197
|
+
requestInit: {
|
|
198
|
+
headers: {
|
|
199
|
+
'Content-Type': 'application/json'
|
|
200
|
+
},
|
|
201
|
+
method: 'POST',
|
|
202
|
+
body: JSON.stringify({
|
|
203
|
+
body: body,
|
|
204
|
+
objectId: objectId,
|
|
205
|
+
title: title,
|
|
206
|
+
language: language
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
case 3:
|
|
212
|
+
document = _context4.sent;
|
|
213
|
+
return _context4.abrupt("return", document);
|
|
214
|
+
|
|
215
|
+
case 7:
|
|
216
|
+
_context4.prev = 7;
|
|
217
|
+
_context4.t0 = _context4["catch"](0);
|
|
218
|
+
// eslint-disable-next-line no-console
|
|
219
|
+
console.warn("Failed to update document: ".concat(JSON.stringify(_context4.t0)));
|
|
220
|
+
return _context4.abrupt("return", null);
|
|
221
|
+
|
|
222
|
+
case 11:
|
|
223
|
+
case "end":
|
|
224
|
+
return _context4.stop();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}, _callee4, this, [[0, 7]]);
|
|
228
|
+
}));
|
|
229
|
+
|
|
230
|
+
function createDocument(_x10, _x11, _x12, _x13) {
|
|
231
|
+
return _createDocument.apply(this, arguments);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return createDocument;
|
|
235
|
+
}()
|
|
236
|
+
}]);
|
|
237
|
+
return ServiceProvider;
|
|
238
|
+
}();
|
|
239
|
+
|
|
240
|
+
exports.default = ServiceProvider;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Component } from 'react';
|
|
4
|
+
import { Editor, EditorContext, WithEditorActions } from '@atlaskit/editor-core';
|
|
5
|
+
import { ReactRenderer } from '@atlaskit/renderer';
|
|
6
|
+
import { ProviderFactory } from '@atlaskit/editor-common';
|
|
7
|
+
const emptyDoc = '{ "type": "doc", "version": 1, "content": [] }';
|
|
8
|
+
export default class Document extends Component {
|
|
9
|
+
renderToolbar() {
|
|
10
|
+
const {
|
|
11
|
+
mode,
|
|
12
|
+
renderToolbar
|
|
13
|
+
} = this.props;
|
|
14
|
+
|
|
15
|
+
if (renderToolbar) {
|
|
16
|
+
return /*#__PURE__*/React.createElement(WithEditorActions, {
|
|
17
|
+
render: actions => renderToolbar(mode, actions)
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
renderTitle() {
|
|
25
|
+
const {
|
|
26
|
+
renderTitle,
|
|
27
|
+
mode,
|
|
28
|
+
doc
|
|
29
|
+
} = this.props;
|
|
30
|
+
|
|
31
|
+
if (renderTitle) {
|
|
32
|
+
return renderTitle(mode, doc);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
renderEditor() {
|
|
39
|
+
const {
|
|
40
|
+
doc,
|
|
41
|
+
editorProps
|
|
42
|
+
} = this.props;
|
|
43
|
+
const {
|
|
44
|
+
body = emptyDoc
|
|
45
|
+
} = doc || {};
|
|
46
|
+
return /*#__PURE__*/React.createElement(EditorContext, null, /*#__PURE__*/React.createElement(Editor, _extends({
|
|
47
|
+
appearance: "full-page",
|
|
48
|
+
placeholder: "Write something...",
|
|
49
|
+
defaultValue: body,
|
|
50
|
+
primaryToolbarComponents: this.renderToolbar(),
|
|
51
|
+
contentComponents: this.renderTitle()
|
|
52
|
+
}, editorProps)));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
render() {
|
|
56
|
+
const {
|
|
57
|
+
doc,
|
|
58
|
+
isLoading,
|
|
59
|
+
hasError,
|
|
60
|
+
mode,
|
|
61
|
+
editorProps,
|
|
62
|
+
rendererProps
|
|
63
|
+
} = this.props;
|
|
64
|
+
|
|
65
|
+
if (hasError) {
|
|
66
|
+
return /*#__PURE__*/React.createElement("div", null, "Something went wrong \uD83D\uDE14");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (isLoading) {
|
|
70
|
+
return /*#__PURE__*/React.createElement("div", null, "Loading document... \uD83D\uDC28");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
switch (mode) {
|
|
74
|
+
case 'create':
|
|
75
|
+
case 'edit':
|
|
76
|
+
return this.renderEditor();
|
|
77
|
+
|
|
78
|
+
default:
|
|
79
|
+
const {
|
|
80
|
+
body = emptyDoc
|
|
81
|
+
} = doc || {};
|
|
82
|
+
let dataProviders;
|
|
83
|
+
|
|
84
|
+
if (editorProps) {
|
|
85
|
+
const {
|
|
86
|
+
mentionProvider,
|
|
87
|
+
emojiProvider,
|
|
88
|
+
media
|
|
89
|
+
} = editorProps;
|
|
90
|
+
dataProviders = ProviderFactory.create({
|
|
91
|
+
mentionProvider: mentionProvider,
|
|
92
|
+
emojiProvider: emojiProvider
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (media && media.provider) {
|
|
96
|
+
dataProviders.setProvider('mediaProvider', media.provider);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return /*#__PURE__*/React.createElement(ReactRenderer, _extends({
|
|
101
|
+
dataProviders: dataProviders,
|
|
102
|
+
document: JSON.parse(body)
|
|
103
|
+
}, rendererProps));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
}
|