UNPKG

24.7 kBJavaScriptView Raw
1// Types
2import { getClosestPropertyValue, maxLinesProperty, textOverflowProperty } from './text-base-common';
3// Requires
4import { Font } from '../styling/font';
5import { backgroundColorProperty } from '../styling/style-properties';
6import { TextBaseCommon, formattedTextProperty, textAlignmentProperty, textDecorationProperty, textProperty, textTransformProperty, textShadowProperty, textStrokeProperty, letterSpacingProperty, whiteSpaceProperty, lineHeightProperty, isBold, resetSymbol } from './text-base-common';
7import { Color } from '../../color';
8import { colorProperty, fontSizeProperty, fontInternalProperty, paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, Length } from '../styling/style-properties';
9import { Span } from './span';
10import { CoreTypes } from '../../core-types';
11import { layout } from '../../utils';
12import { SDK_VERSION } from '../../utils/constants';
13import { isString, isNullOrUndefined } from '../../utils/types';
14import { accessibilityIdentifierProperty } from '../../accessibility/accessibility-properties';
15import { testIDProperty } from '../../ui/core/view';
16export * from './text-base-common';
17let TextTransformation;
18function initializeTextTransformation() {
19 if (TextTransformation) {
20 return;
21 }
22 var TextTransformationImpl = /** @class */ (function (_super) {
23 __extends(TextTransformationImpl, _super);
24 function TextTransformationImpl(textBase) {
25 var _this = _super.call(this) || this;
26 _this.textBase = textBase;
27 return global.__native(_this);
28 }
29 TextTransformationImpl.prototype.getTransformation = function (charSeq, view) {
30 // NOTE: Do we need to transform the new text here?
31 var formattedText = this.textBase.formattedText;
32 if (formattedText) {
33 return this.textBase.createFormattedTextNative(formattedText);
34 }
35 else {
36 var text = this.textBase.text;
37 var stringValue = isNullOrUndefined(text) ? '' : text.toString();
38 return getTransformedText(stringValue, this.textBase.textTransform);
39 }
40 };
41 TextTransformationImpl.prototype.onFocusChanged = function (view, sourceText, focused, direction, previouslyFocusedRect) {
42 // Do nothing for now.
43 };
44 var _a;
45 TextTransformationImpl = __decorate([
46 Interfaces([android.text.method.TransformationMethod]),
47 __metadata("design:paramtypes", [typeof (_a = typeof TextBase !== "undefined" && TextBase) === "function" ? _a : Object])
48 ], TextTransformationImpl);
49 return TextTransformationImpl;
50}(java.lang.Object));
51 TextTransformation = TextTransformationImpl;
52}
53let ClickableSpan;
54function initializeClickableSpan() {
55 if (ClickableSpan) {
56 return;
57 }
58 var ClickableSpanImpl = /** @class */ (function (_super) {
59 __extends(ClickableSpanImpl, _super);
60 function ClickableSpanImpl(owner) {
61 var _this = _super.call(this) || this;
62 _this.owner = new WeakRef(owner);
63 return global.__native(_this);
64 }
65 ClickableSpanImpl.prototype.onClick = function (view) {
66 var _a;
67 var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get();
68 if (owner) {
69 owner._emit(Span.linkTapEvent);
70 }
71 view.clearFocus();
72 view.invalidate();
73 };
74 ClickableSpanImpl.prototype.updateDrawState = function (tp) {
75 // don't style as link
76 };
77 return ClickableSpanImpl;
78}(android.text.style.ClickableSpan));
79 ClickableSpan = ClickableSpanImpl;
80}
81let BaselineAdjustedSpan;
82function initializeBaselineAdjustedSpan() {
83 if (BaselineAdjustedSpan) {
84 return;
85 }
86 var BaselineAdjustedSpanImpl = /** @class */ (function (_super) {
87 __extends(BaselineAdjustedSpanImpl, _super);
88 function BaselineAdjustedSpanImpl(fontSize, align) {
89 var _this = _super.call(this) || this;
90 _this.align = 'baseline';
91 _this.align = align;
92 _this.fontSize = fontSize;
93 return _this;
94 }
95 BaselineAdjustedSpanImpl.prototype.updateDrawState = function (paint) {
96 this.updateState(paint);
97 };
98 BaselineAdjustedSpanImpl.prototype.updateMeasureState = function (paint) {
99 this.updateState(paint);
100 };
101 BaselineAdjustedSpanImpl.prototype.updateState = function (paint) {
102 var metrics = paint.getFontMetrics();
103 if (!this.align || ['baseline', 'stretch'].includes(this.align)) {
104 return;
105 }
106 if (this.align === 'top') {
107 return (paint.baselineShift = -this.fontSize - metrics.bottom - metrics.top);
108 }
109 if (this.align === 'bottom') {
110 return (paint.baselineShift = metrics.bottom);
111 }
112 if (this.align === 'text-top') {
113 return (paint.baselineShift = -this.fontSize - metrics.descent - metrics.ascent);
114 }
115 if (this.align === 'text-bottom') {
116 return (paint.baselineShift = metrics.bottom - metrics.descent);
117 }
118 if (this.align === 'middle') {
119 return (paint.baselineShift = (metrics.descent - metrics.ascent) / 2 - metrics.descent);
120 }
121 if (this.align === 'sup') {
122 return (paint.baselineShift = -this.fontSize * 0.4);
123 }
124 if (this.align === 'sub') {
125 return (paint.baselineShift = (metrics.descent - metrics.ascent) * 0.4);
126 }
127 };
128 return BaselineAdjustedSpanImpl;
129}(android.text.style.MetricAffectingSpan));
130 BaselineAdjustedSpan = BaselineAdjustedSpanImpl;
131}
132export class TextBase extends TextBaseCommon {
133 constructor() {
134 super(...arguments);
135 this._tappable = false;
136 }
137 initNativeView() {
138 super.initNativeView();
139 initializeTextTransformation();
140 const nativeView = this.nativeTextViewProtected;
141 this._defaultTransformationMethod = nativeView.getTransformationMethod();
142 this._defaultMovementMethod = nativeView.getMovementMethod();
143 this._minHeight = nativeView.getMinHeight();
144 this._maxHeight = nativeView.getMaxHeight();
145 this._minLines = nativeView.getMinLines();
146 this._maxLines = nativeView.getMaxLines();
147 }
148 resetNativeView() {
149 super.resetNativeView();
150 const nativeView = this.nativeTextViewProtected;
151 // We reset it here too because this could be changed by multiple properties - whiteSpace, secure, textTransform
152 nativeView.setSingleLine(this._isSingleLine);
153 nativeView.setTransformationMethod(this._defaultTransformationMethod);
154 this._defaultTransformationMethod = null;
155 if (this._paintFlags !== undefined) {
156 nativeView.setPaintFlags(this._paintFlags);
157 this._paintFlags = undefined;
158 }
159 if (this._minLines !== -1) {
160 nativeView.setMinLines(this._minLines);
161 }
162 else {
163 nativeView.setMinHeight(this._minHeight);
164 }
165 this._minHeight = this._minLines = undefined;
166 if (this._maxLines !== -1) {
167 nativeView.setMaxLines(this._maxLines);
168 }
169 else {
170 nativeView.setMaxHeight(this._maxHeight);
171 }
172 this._maxHeight = this._maxLines = undefined;
173 }
174 [textProperty.getDefault]() {
175 return resetSymbol;
176 }
177 [textProperty.setNative](value) {
178 const reset = value === resetSymbol;
179 if (!reset && this.formattedText) {
180 return;
181 }
182 this._setTappableState(false);
183 this._setNativeText(reset);
184 }
185 [textStrokeProperty.setNative](value) {
186 this._setNativeText();
187 }
188 createFormattedTextNative(value) {
189 return createSpannableStringBuilder(value, this.style.fontSize);
190 }
191 [formattedTextProperty.setNative](value) {
192 const nativeView = this.nativeTextViewProtected;
193 if (!value) {
194 if (nativeView instanceof android.widget.Button && nativeView.getTransformationMethod() instanceof TextTransformation) {
195 nativeView.setTransformationMethod(this._defaultTransformationMethod);
196 }
197 }
198 // Don't change the transformation method if this is secure TextField or we'll lose the hiding characters.
199 if (this.secure) {
200 return;
201 }
202 const spannableStringBuilder = this.createFormattedTextNative(value);
203 nativeView.setText(spannableStringBuilder);
204 this._setTappableState(isStringTappable(value));
205 textProperty.nativeValueChange(this, value === null || value === undefined ? '' : value.toString());
206 if (spannableStringBuilder && nativeView instanceof android.widget.Button && !(nativeView.getTransformationMethod() instanceof TextTransformation)) {
207 // Replace Android Button's default transformation (in case the developer has not already specified a text-transform) method
208 // with our transformation method which can handle formatted text.
209 // Otherwise, the default tranformation method of the Android Button will overwrite and ignore our spannableStringBuilder.
210 nativeView.setTransformationMethod(new TextTransformation(this));
211 }
212 }
213 [textTransformProperty.setNative](value) {
214 if (value === 'initial') {
215 this.nativeTextViewProtected.setTransformationMethod(this._defaultTransformationMethod);
216 return;
217 }
218 // Don't change the transformation method if this is secure TextField or we'll lose the hiding characters.
219 if (this.secure) {
220 return;
221 }
222 this.nativeTextViewProtected.setTransformationMethod(new TextTransformation(this));
223 }
224 [textAlignmentProperty.getDefault]() {
225 return 'initial';
226 }
227 [textAlignmentProperty.setNative](value) {
228 const verticalGravity = this.nativeTextViewProtected.getGravity() & android.view.Gravity.VERTICAL_GRAVITY_MASK;
229 switch (value) {
230 case 'center':
231 this.nativeTextViewProtected.setGravity(android.view.Gravity.CENTER_HORIZONTAL | verticalGravity);
232 break;
233 case 'right':
234 this.nativeTextViewProtected.setGravity(android.view.Gravity.END | verticalGravity);
235 break;
236 default:
237 // initial | left | justify
238 this.nativeTextViewProtected.setGravity(android.view.Gravity.START | verticalGravity);
239 break;
240 }
241 if (SDK_VERSION >= 26) {
242 if (value === 'justify') {
243 this.nativeTextViewProtected.setJustificationMode(android.text.Layout.JUSTIFICATION_MODE_INTER_WORD);
244 }
245 else {
246 this.nativeTextViewProtected.setJustificationMode(android.text.Layout.JUSTIFICATION_MODE_NONE);
247 }
248 }
249 }
250 // Overridden in TextField because setSingleLine(false) will remove methodTransformation.
251 // and we don't want to allow TextField to be multiline
252 [whiteSpaceProperty.setNative](value) {
253 this.adjustLineBreak();
254 }
255 [textOverflowProperty.setNative](value) {
256 this.adjustLineBreak();
257 }
258 adjustLineBreak() {
259 const whiteSpace = this.whiteSpace;
260 const textOverflow = this.textOverflow;
261 const nativeView = this.nativeTextViewProtected;
262 switch (whiteSpace) {
263 case 'initial':
264 case 'normal':
265 nativeView.setSingleLine(false);
266 nativeView.setEllipsize(null);
267 break;
268 case 'nowrap':
269 switch (textOverflow) {
270 case 'initial':
271 case 'ellipsis':
272 nativeView.setSingleLine(true);
273 nativeView.setEllipsize(android.text.TextUtils.TruncateAt.END);
274 break;
275 default:
276 nativeView.setSingleLine(false);
277 nativeView.setEllipsize(android.text.TextUtils.TruncateAt.END);
278 break;
279 }
280 break;
281 }
282 }
283 [colorProperty.getDefault]() {
284 return this.nativeTextViewProtected.getTextColors();
285 }
286 [colorProperty.setNative](value) {
287 if (!this.formattedText || !(value instanceof Color)) {
288 if (value instanceof Color) {
289 this.nativeTextViewProtected.setTextColor(value.android);
290 }
291 else {
292 this.nativeTextViewProtected.setTextColor(value);
293 }
294 }
295 }
296 [fontSizeProperty.getDefault]() {
297 return { nativeSize: this.nativeTextViewProtected.getTextSize() };
298 }
299 [fontSizeProperty.setNative](value) {
300 if (!this.formattedText || typeof value !== 'number') {
301 if (typeof value === 'number') {
302 this.nativeTextViewProtected.setTextSize(value);
303 }
304 else {
305 this.nativeTextViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize);
306 }
307 }
308 }
309 [lineHeightProperty.getDefault]() {
310 return this.nativeTextViewProtected.getLineSpacingExtra() / layout.getDisplayDensity();
311 }
312 [lineHeightProperty.setNative](value) {
313 this.nativeTextViewProtected.setLineSpacing(value * layout.getDisplayDensity(), 1);
314 }
315 [fontInternalProperty.getDefault]() {
316 return this.nativeTextViewProtected.getTypeface();
317 }
318 [fontInternalProperty.setNative](value) {
319 if (!this.formattedText || !(value instanceof Font)) {
320 this.nativeTextViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value);
321 }
322 }
323 [textDecorationProperty.getDefault]() {
324 return (this._paintFlags = this.nativeTextViewProtected.getPaintFlags());
325 }
326 [textDecorationProperty.setNative](value) {
327 switch (value) {
328 case 'none':
329 this.nativeTextViewProtected.setPaintFlags(0);
330 break;
331 case 'underline':
332 this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG);
333 break;
334 case 'line-through':
335 this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.STRIKE_THRU_TEXT_FLAG);
336 break;
337 case 'underline line-through':
338 this.nativeTextViewProtected.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG | android.graphics.Paint.STRIKE_THRU_TEXT_FLAG);
339 break;
340 default:
341 this.nativeTextViewProtected.setPaintFlags(value);
342 break;
343 }
344 }
345 [textShadowProperty.getDefault]() {
346 return {
347 radius: this.nativeTextViewProtected.getShadowRadius(),
348 offsetX: this.nativeTextViewProtected.getShadowDx(),
349 offsetY: this.nativeTextViewProtected.getShadowDy(),
350 color: this.nativeTextViewProtected.getShadowColor(),
351 };
352 }
353 [textShadowProperty.setNative](value) {
354 // prettier-ignore
355 this.nativeTextViewProtected.setShadowLayer(Length.toDevicePixels(value.blurRadius, java.lang.Float.MIN_VALUE), Length.toDevicePixels(value.offsetX, 0), Length.toDevicePixels(value.offsetY, 0), value.color.android);
356 }
357 [letterSpacingProperty.getDefault]() {
358 return org.nativescript.widgets.ViewHelper.getLetterspacing(this.nativeTextViewProtected);
359 }
360 [letterSpacingProperty.setNative](value) {
361 org.nativescript.widgets.ViewHelper.setLetterspacing(this.nativeTextViewProtected, value);
362 }
363 [paddingTopProperty.getDefault]() {
364 return { value: this._defaultPaddingTop, unit: 'px' };
365 }
366 [paddingTopProperty.setNative](value) {
367 org.nativescript.widgets.ViewHelper.setPaddingTop(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0));
368 }
369 [paddingRightProperty.getDefault]() {
370 return { value: this._defaultPaddingRight, unit: 'px' };
371 }
372 [paddingRightProperty.setNative](value) {
373 org.nativescript.widgets.ViewHelper.setPaddingRight(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0));
374 }
375 [paddingBottomProperty.getDefault]() {
376 return { value: this._defaultPaddingBottom, unit: 'px' };
377 }
378 [paddingBottomProperty.setNative](value) {
379 org.nativescript.widgets.ViewHelper.setPaddingBottom(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0));
380 }
381 [paddingLeftProperty.getDefault]() {
382 return { value: this._defaultPaddingLeft, unit: 'px' };
383 }
384 [paddingLeftProperty.setNative](value) {
385 org.nativescript.widgets.ViewHelper.setPaddingLeft(this.nativeTextViewProtected, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0));
386 }
387 [testIDProperty.setNative](value) {
388 this.setAccessibilityIdentifier(this.nativeTextViewProtected, value);
389 }
390 [accessibilityIdentifierProperty.setNative](value) {
391 this.setAccessibilityIdentifier(this.nativeTextViewProtected, value);
392 }
393 [maxLinesProperty.setNative](value) {
394 const nativeTextViewProtected = this.nativeTextViewProtected;
395 if (value <= 0) {
396 nativeTextViewProtected.setMaxLines(Number.MAX_SAFE_INTEGER);
397 }
398 else {
399 nativeTextViewProtected.setMaxLines(typeof value === 'string' ? parseInt(value, 10) : value);
400 nativeTextViewProtected.setEllipsize(android.text.TextUtils.TruncateAt.END);
401 }
402 }
403 _setNativeText(reset = false) {
404 if (reset) {
405 this.nativeTextViewProtected.setText(null);
406 return;
407 }
408 let transformedText;
409 if (this.formattedText) {
410 transformedText = this.createFormattedTextNative(this.formattedText);
411 }
412 else {
413 const text = this.text;
414 const stringValue = text === null || text === undefined ? '' : text.toString();
415 transformedText = getTransformedText(stringValue, this.textTransform);
416 }
417 if (this.style?.textStroke) {
418 this.nativeViewProtected.setTextStroke(Length.toDevicePixels(this.style.textStroke.width), this.style.textStroke.color.android, this.style.color.android);
419 }
420 else if (this.nativeViewProtected.setTextStroke) {
421 // reset
422 this.nativeViewProtected.setTextStroke(0, 0, 0);
423 }
424 this.nativeTextViewProtected.setText(transformedText);
425 }
426 _setTappableState(tappable) {
427 if (this._tappable !== tappable) {
428 this._tappable = tappable;
429 if (this._tappable) {
430 // Setting singleLine to true results in conflicts with LinkMovementMethod
431 // See https://stackoverflow.com/a/34407901
432 this.nativeTextViewProtected.setSingleLine(false);
433 this.nativeTextViewProtected.setMovementMethod(android.text.method.LinkMovementMethod.getInstance());
434 this.nativeTextViewProtected.setHighlightColor(null);
435 }
436 else {
437 this.nativeTextViewProtected.setMovementMethod(this._defaultMovementMethod);
438 }
439 }
440 }
441}
442function getCapitalizedString(str) {
443 let newString = str.toLowerCase();
444 newString = newString.replace(/(?:^|\s'*|[-"([{])+\S/g, (c) => c.toUpperCase());
445 return newString;
446}
447export function getTransformedText(text, textTransform) {
448 if (!text || !isString(text)) {
449 return '';
450 }
451 switch (textTransform) {
452 case 'uppercase':
453 return text.toUpperCase();
454 case 'lowercase':
455 return text.toLowerCase();
456 case 'capitalize':
457 return getCapitalizedString(text);
458 case 'none':
459 default:
460 return text;
461 }
462}
463function isStringTappable(formattedString) {
464 if (!formattedString) {
465 return false;
466 }
467 for (let i = 0, length = formattedString.spans.length; i < length; i++) {
468 const span = formattedString.spans.getItem(i);
469 if (span.tappable) {
470 return true;
471 }
472 }
473 return false;
474}
475function createSpannableStringBuilder(formattedString, defaultFontSize) {
476 if (!formattedString || !formattedString.parent) {
477 return null;
478 }
479 const ssb = new android.text.SpannableStringBuilder();
480 for (let i = 0, spanStart = 0, spanLength = 0, length = formattedString.spans.length; i < length; i++) {
481 const span = formattedString.spans.getItem(i);
482 const text = span.text;
483 const textTransform = formattedString.parent.textTransform;
484 let spanText = text === null || text === undefined ? '' : text.toString();
485 if (textTransform && textTransform !== 'none') {
486 spanText = getTransformedText(spanText, textTransform);
487 }
488 spanLength = spanText.length;
489 if (spanLength > 0) {
490 ssb.insert(spanStart, spanText);
491 setSpanModifiers(ssb, span, spanStart, spanStart + spanLength, defaultFontSize);
492 spanStart += spanLength;
493 }
494 }
495 return ssb;
496}
497function setSpanModifiers(ssb, span, start, end, defaultFontSize) {
498 const spanStyle = span.style;
499 const bold = isBold(spanStyle.fontWeight);
500 const italic = spanStyle.fontStyle === 'italic';
501 const align = spanStyle.verticalAlignment;
502 if (bold && italic) {
503 ssb.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD_ITALIC), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
504 }
505 else if (bold) {
506 ssb.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
507 }
508 else if (italic) {
509 ssb.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.ITALIC), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
510 }
511 const fontFamily = span.fontFamily;
512 if (fontFamily) {
513 const font = new Font(fontFamily, 0, italic ? 'italic' : 'normal', bold ? 'bold' : 'normal', spanStyle.fontScaleInternal, spanStyle.fontVariationSettings);
514 const typeface = font.getAndroidTypeface() || android.graphics.Typeface.create(fontFamily, 0);
515 const typefaceSpan = new org.nativescript.widgets.CustomTypefaceSpan(fontFamily, typeface);
516 ssb.setSpan(typefaceSpan, start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
517 }
518 const realFontSize = span.fontSize;
519 if (realFontSize) {
520 ssb.setSpan(new android.text.style.AbsoluteSizeSpan(realFontSize * layout.getDisplayDensity()), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
521 }
522 const color = span.color;
523 if (color) {
524 ssb.setSpan(new android.text.style.ForegroundColorSpan(color.android), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
525 }
526 const backgroundColor = getClosestPropertyValue(backgroundColorProperty, span);
527 if (backgroundColor) {
528 ssb.setSpan(new android.text.style.BackgroundColorSpan(backgroundColor.android), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
529 }
530 const textDecoration = getClosestPropertyValue(textDecorationProperty, span);
531 if (textDecoration) {
532 const underline = textDecoration.indexOf('underline') !== -1;
533 if (underline) {
534 ssb.setSpan(new android.text.style.UnderlineSpan(), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
535 }
536 const strikethrough = textDecoration.indexOf('line-through') !== -1;
537 if (strikethrough) {
538 ssb.setSpan(new android.text.style.StrikethroughSpan(), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
539 }
540 }
541 if (align) {
542 initializeBaselineAdjustedSpan();
543 ssb.setSpan(new BaselineAdjustedSpan(defaultFontSize * layout.getDisplayDensity(), align), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
544 }
545 const tappable = span.tappable;
546 if (tappable) {
547 initializeClickableSpan();
548 ssb.setSpan(new ClickableSpan(span), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
549 }
550 // TODO: Implement letterSpacing for Span here.
551 // const letterSpacing = formattedString.parent.style.letterSpacing;
552 // if (letterSpacing > 0) {
553 // ssb.setSpan(new android.text.style.ScaleXSpan((letterSpacing + 1) / 10), start, end, android.text.Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
554 // }
555}
556//# sourceMappingURL=index.android.js.map
\No newline at end of file