Initial commit

This commit is contained in:
janisslsm committed 2026-07-27 16:20:00 +03:00
commit af3b49f756
16065 files changed
+2938410

No files matched your search

+523
View File
@@ -0,0 +1,523 @@
/* Metro module 4862; source: lib/MessageQueue.tsx; dependencies: [29, 6, 7, 15, 17, 102, 18, 4649, 1226, 4401, 661, 4503, 672, 3, 507, 4863, 4872, 4873, 1909, 44, 4648, 4651, 4655, 5258, 2] */
function _fun42457(global, require, importDefault, importAll, module, exports, dependencyMap) { // fn#42457, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:6, offset: 0x01139e28, size: 591 bytes, params: 8, frame: 25
var object2;
const env0_0 = require;
const closure = isMessageDataSend;
const closure2 = isMessageDataEdit;
const env0_3 = ['channelId', 'analyticsLocation'];
const env0_4 = ['channelId', 'analyticsLocation'];
const Object = global.Object;
Object.defineProperty(exports, '__esModule', {value: true});
const env0_5 = importDefault(29) /* metro dependency 29 */;
const env0_6 = importDefault(6) /* metro dependency 6 */;
const env0_7 = importDefault(7) /* metro dependency 7 */;
const env0_8 = importDefault(15) /* metro dependency 15 */;
const env0_9 = importDefault(17) /* metro dependency 17 */;
const env0_10 = importDefault(102) /* metro dependency 102 */;
const env0_11 = importDefault(18) /* metro dependency 18 */;
const devSettingsStore = importDefault(4649) /* metro dependency 4649: DevSettingsStore */;
const authenticationStore = importDefault(1226) /* metro dependency 1226: AuthenticationStore */;
const networkStore = importDefault(4401) /* metro dependency 4401: NetworkStore */;
let value = require(661) /* metro dependency 661: Constants */;
const env0_15 = value.AbortCodes;
const env0_16 = value.Endpoints;
const env0_17 = value.AnalyticEvents;
const env0_18 = (require(4503) /* metro dependency 4503: MessageConstants */).MESSAGE_HTTP_TIMEOUT_RETRY_OPTIONS;
object2 = {SEND: 0};
object2[0] = 'SEND';
object2.EDIT = 1;
object2[1] = 'EDIT';
object2.COMMAND = 2;
object2[2] = 'COMMAND';
object2.SEND_ANNOUNCEMENT = 3;
object2[3] = 'SEND_ANNOUNCEMENT';
let Millis = (importDefault(672) /* metro dependency 672: Durations */).Millis;
let MINUTE = Millis.MINUTE;
const items2 = [1 * MINUTE];
Millis = (importDefault(672) /* metro dependency 672: Durations */).Millis;
MINUTE = Millis.MINUTE;
items2[1] = 5 * MINUTE;
value = importDefault(5258) /* metro dependency 5258: Queue */;
value = _fun42463(value);
value = new value();
(require(2) /* metro dependency 2 */).fileFinishedImporting('lib/MessageQueue.tsx');
exports.default = value;
exports.MessageDataType = object2;
exports.isMessageDataSend = closure;
exports.isMessageDataEdit = closure2;
exports.isMessageDataCommand = isMessageDataCommand;
exports.getFailedMessageId = getFailedMessageId;
}
function _isNativeReflectConstruct_42458() { // fn#42458, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:382, offset: 0x0113a077, size: 94 bytes, params: 1, frame: 18
var Boolean;
var prototype;
var valueOf;
var call;
var Reflect;
var construct;
var closure;
var value;
var error;
try {
Boolean = global.Boolean;
prototype = Boolean.prototype;
valueOf = prototype.valueOf;
call = valueOf.call;
Reflect = global.Reflect;
construct = Reflect.construct;
Boolean = global.Boolean;
closure = function() {
};
value = Reflect.apply(construct, Reflect, [Boolean, [], closure]);
value = Reflect.apply(call, valueOf, [value]);
var result = !value;
} catch (error) {
}
return (_isNativeReflectConstruct_42458_isNativeReflectConstruct = function() {
return !!result;
})();
}
function isMessageDataSend(a0) { // fn#42461, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:715, offset: 0x0113a0d5, size: 49 bytes, params: 2, frame: 4
const type = a0.type;
const SEND = env0_19.SEND;
return type === SEND || a0.type === env0_19.SEND_ANNOUNCEMENT;
}
function isMessageDataEdit({type}) { // fn#42462, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:798, offset: 0x0113a106, size: 27 bytes, params: 2, frame: 2
const EDIT = env0_19.EDIT;
return type === EDIT;
}
function _fun42463(a0) { // fn#42463, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:915, offset: 0x0113a121, size: 306 bytes, params: 2, frame: 16
const closure = MessageQueue_42464;
env0_11(closure, a0);
return env0_7(closure, [{key: 'isFull', value: function() {
return this.queue.length >= this.maxSize;
}}, {key: 'drain', value: value_42468}, {key: 'cancelRequest', value: function(a0) {
this.logger.log('Cancel message send: ', a0);
var value = this.requests.get(a0);
if (value != null) {
value.abort();
}
this.requests.delete(a0);
this.cancelQueueMetricTimers(a0);
}}, {key: 'cancelPendingSendRequests', value: value_42470}, {key: 'clear', value: value_42471},
{key: 'startQueueMetricTimers', value: value_42476}, {key: 'cancelQueueMetricTimers', value: function(a0) {
var value = this.analyticsTimeouts.get(a0);
if (value != null) {
value.forEach(global.clearTimeout);
}
this.analyticsTimeouts.delete(a0);
}}, {key: 'createResponseHandler', value: function(a0, a1) {
var env0_0 = this;
var env0_1 = a0;
var env0_2 = a1;
return _fun42481;
}}, {key: 'handleSend', value: value_42482}, {key: 'handleSendAnnouncement', value: value_42484},
{key: 'handleCommand', value: value_42486}]);
}
function isMessageDataCommand({type}) { // fn#42490, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:6135, offset: 0x0113afab, size: 27 bytes, params: 2, frame: 2
const COMMAND = env0_19.COMMAND;
return type === COMMAND;
}
function getFailedMessageId(a0) { // fn#42491, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:6217, offset: 0x0113afc6, size: 69 bytes, params: 2, frame: 12
var r0;
var message;
var isMessageDataEdit2;
if (isMessageDataSend(a0)) {
r0 = a0.message.nonce;
} else {
isMessageDataEdit2 = isMessageDataEdit(a0);
message = a0.message;
r0 = isMessageDataEdit2 ? message.messageId : message.data.id;
}
return r0;
}
function MessageQueue_42464() { // fn#42464, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:927, offset: 0x0113a253, size: 261 bytes, params: 1, frame: 21
var environment;
let value = a0;
const r2 = value !== undefined ? value : 5;
value = environment.__proto__;
env1_6(this, MessageQueue_42464);
const defaultImport = importDefault(3) /* metro dependency 3: Logger */;
const value3 = Object.create(defaultImport.prototype, {constructor: {value: defaultImport}});
const defaultImport2 = new defaultImport('MessageQueue');
const items2 = [defaultImport2 instanceof Object ? defaultImport2 : value3];
const value6 = env1_9(MessageQueue_42464);
value = env1_8(this, _isNativeReflectConstruct_42458() ? global.Reflect.construct(value6, items2,
env1_9(this).constructor) : value6.apply(this, items2));
value.maxSize = r2;
let Map = global.Map;
const value7 = Object.create(Map.prototype, {constructor: {value: Map}});
let map = new Map();
value.requests = map instanceof Object ? map : value7;
Map = global.Map;
const value9 = Object.create(Map.prototype, {constructor: {value: Map}});
map = new Map();
value.analyticsTimeouts = map instanceof Object ? map : value9;
value.handleEdit = handleEdit_42465;
return value;
}
function value_42468(a0, a1) { // fn#42468, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:1692, offset: 0x0113a482, size: 184 bytes, params: 3, frame: 16
const logger = this.logger;
const log = logger.log;
let type = a0.type;
Reflect.apply(log, logger, ['Draining Message Queue with: ', type]);
type = a0.type;
const SEND = env1_19.SEND;
if (SEND === type) {
this.handleSend(a0.message, a1);
} else if (env1_19.SEND_ANNOUNCEMENT === type) {
this.handleSendAnnouncement(a0.message, a1);
} else if (env1_19.EDIT === type) {
this.handleEdit(a0.message, a1);
} else if (env1_19.COMMAND === type) {
this.handleCommand(a0.message, a1);
}
}
function value_42470(a0) { // fn#42470, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:2220, offset: 0x0113a597, size: 201 bytes, params: 2, frame: 20
var r9;
var shift;
var value2;
var message;
var type;
var SEND;
var message2;
var channelId;
var push;
const items4 = [];
const items2 = [];
let queue = this.queue;
let length = queue.length;
if (length > 0) {
reducibleLoop1: while (true) {
queue = this.queue;
shift = queue.shift;
value2 = Reflect.apply(shift, queue, []);
message = value2.message;
type = message.type;
SEND = env1_19.SEND;
reducibleJoin5: while (true) {
reducibleJoin3: while (true) {
if (type !== SEND) {
break reducibleJoin3;
}
message2 = message.message;
channelId = message2.channelId;
if (channelId === a0) {
push = items4.push;
message = message.message;
Reflect.apply(push, items4, [message]);
break reducibleJoin5;
}
break reducibleJoin3;
}
push = items2.push;
Reflect.apply(push, items2, [value2]);
break reducibleJoin5;
}
queue = this.queue;
length = queue.length;
if (length > 0) {
continue reducibleLoop1;
}
r9 = type;
break reducibleLoop1;
}
}
queue = this.queue;
push = queue.push;
const items3 = [];
arraySpread(items3, items2, 0, r9);
apply(push, items3, queue, r9);
const logger = this.logger;
logger.log('Cancel pending send requests', items4.length);
return items4;
}
function value_42471() { // fn#42471, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:2487, offset: 0x0113a660, size: 108 bytes, params: 1, frame: 17
this.requests.forEach(function(a0) {
return a0.abort();
});
this.requests.clear();
this.analyticsTimeouts.forEach(_fun42473);
value_42471_superPropGet(MessageQueue_42464, 'clear', this, 3)([]);
}
function value_42476(a0) { // fn#42476, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:2837, offset: 0x0113a756, size: 51 bytes, params: 2, frame: 13
var environment;
const value = environment.__proto__;
this.analyticsTimeouts.set(a0, env1_20.map(function(a0) {
var env0_0 = a0;
return global.setTimeout(_fun42478, a0);
}));
}
function value_42480(a0, a1) { // fn#42480, offset: 0x0113a82c, size: 30 bytes, params: 3, frame: 2
const env0_1 = a0;
const env0_2 = a1;
return _fun42481;
}
function value_42482(a0, a1) { // fn#42482, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:3593, offset: 0x0113a96d, size: 460 bytes, params: 3, frame: 25
const env0_1 = a0;
const channelId = a0.channelId;
const analyticsLocation = a0.analyticsLocation;
const binding = env1_5;
const value2 = undefined;
const value3 = binding(a0, env1_3);
const r7 = (importDefault(4872) /* metro dependency 4872: getOverlayMessageAnaylticsLocationNative */)() ?? analyticsLocation;
const r10 = r7 != null ? {location: r7} : value2;
const signalStrength = (require(4873) /* metro dependency 4873: NetStatsAndroid */).getSignalStrength();
const object2 = {};
object2.mobile_network_type = NetworkStore.getType();
copyDataProperties(object2, value3, channelId);
copyDataProperties(object2, signalStrength != null && ({signal_strength: signalStrength}), channelId);
const get = DevSettingsStore.get;
if (Reflect.apply(get, DevSettingsStore, ['send_fail_100'])) {
this.logger.log('Skipping message send because send_fail_100 is enabled');
a1(null, {'ok': false, 'hasErr': false, 'status': 500, 'headers': null, 'body': '{}',
'text': 'Simulated failure',
headers: {}});
} else {
var responseHandler = this.createResponseHandler(a0.nonce, a1);
var AbortController = global.AbortController;
var abortController = new AbortController();
this.startQueueMetricTimers(a0.nonce);
var HTTP = (require(507) /* metro dependency 507: HTTPUtils */).HTTP;
var post = HTTP.post;
var object4 = {};
object4.url = Endpoints.MESSAGES(channelId);
object4.body = object2;
object4.context = r10;
object4.oldFormErrors = true;
copyDataProperties(object4, MESSAGE_HTTP_TIMEOUT_RETRY_OPTIONS, channelId);
object4['signal'] = abortController.signal;
object4['rejectWithError'] = true;
object4['onRequestCreated'] = value_42482OnRequestCreated;
Reflect.apply(post, HTTP, [object4, responseHandler]);
}
return value2;
}
function value_42484(a0, a1) { // fn#42484, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:4340, offset: 0x0113ab73, size: 460 bytes, params: 3, frame: 25
const env0_1 = a0;
const channelId = a0.channelId;
const analyticsLocation = a0.analyticsLocation;
const binding = env1_5;
const value2 = undefined;
const value3 = binding(a0, env1_4);
const r7 = (importDefault(4872) /* metro dependency 4872: getOverlayMessageAnaylticsLocationNative */)() ?? analyticsLocation;
const r10 = r7 != null ? {location: r7} : value2;
const signalStrength = (require(4873) /* metro dependency 4873: NetStatsAndroid */).getSignalStrength();
const object2 = {};
object2.mobile_network_type = NetworkStore.getType();
copyDataProperties(object2, value3, channelId);
copyDataProperties(object2, signalStrength != null && ({signal_strength: signalStrength}), channelId);
const get = DevSettingsStore.get;
if (Reflect.apply(get, DevSettingsStore, ['send_fail_100'])) {
this.logger.log('Skipping message send because send_fail_100 is enabled');
a1(null, {'ok': false, 'hasErr': false, 'status': 500, 'headers': null, 'body': '{}',
'text': 'Simulated failure',
headers: {}});
} else {
var responseHandler = this.createResponseHandler(a0.nonce, a1);
var AbortController = global.AbortController;
var abortController = new AbortController();
this.startQueueMetricTimers(a0.nonce);
var HTTP = (require(507) /* metro dependency 507: HTTPUtils */).HTTP;
var post = HTTP.post;
var object4 = {};
object4.url = Endpoints.MESSAGES_ANNOUNCEMENT(channelId);
object4.body = object2;
object4.context = r10;
object4.oldFormErrors = true;
copyDataProperties(object4, MESSAGE_HTTP_TIMEOUT_RETRY_OPTIONS, channelId);
object4['signal'] = abortController.signal;
object4['rejectWithError'] = true;
object4['onRequestCreated'] = value_42484OnRequestCreated;
Reflect.apply(post, HTTP, [object4, responseHandler]);
}
return value2;
}
function value_42486({applicationId, guildId, channelId, data, nonce, attachments, maxSizeCallback, analytics_location, sectionName, source}, a1) { // fn#42486, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:5091, offset: 0x0113ad3f, size: 346 bytes, params: 3, frame: 26
const object2 = {};
const InteractionTypes = (require(1909) /* metro dependency 1909: Server */).InteractionTypes;
const APPLICATION_COMMAND = InteractionTypes.APPLICATION_COMMAND;
object2.type = APPLICATION_COMMAND;
object2.application_id = applicationId;
object2.guild_id = guildId;
object2.channel_id = channelId;
object2.session_id = AuthenticationStore.getSessionId();
object2.data = data;
object2.nonce = nonce;
object2.analytics_location = analytics_location;
object2.section_name = sectionName;
object2.source = source;
if (attachments != null) {
object2.data.attachments = attachments.map(_fun42487);
}
const AbortController = global.AbortController;
const abortController = new AbortController();
const HTTP = (require(507) /* metro dependency 507: HTTPUtils */).HTTP;
const post = HTTP.post;
const INTERACTIONS = Endpoints.INTERACTIONS;
Reflect.apply(post, HTTP, [{url: INTERACTIONS, body: object2, signal: abortController.signal, rejectWithError: true,
onRequestCreated: onRequestCreated}, this.createResponseHandler(nonce, a1)]);
}
function MessageQueue_42464HandleEdit(a0, a1) { // fn#42465, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:1245, owner: MessageQueue_42464.handleEdit, offset: 0x0113a358, size: 233 bytes, params: 3, frame: 21
const channelId = a0.channelId;
const messageId = a0.messageId;
const env0_0 = messageId;
const isCrossposted = a0.isCrossposted;
let object2 = {'channelId': 0, 'messageId': 0, 'isCrossposted': 0};
silentSetPrototypeOf(object2, null, undefined);
const value = copyDataProperties({}, a0, object2, channelId);
const AbortController = global.AbortController;
const abortController = new AbortController();
const responseHandler = env0_0.createResponseHandler(messageId, a1);
object2 = {'url': null, 'body': null, 'retries': 1, 'oldFormErrors': true, 'signal': null, 'rejectWithError': true};
object2.url = Endpoints.MESSAGE(channelId, messageId);
object2.body = value;
object2.signal = abortController.signal;
object2.onRequestCreated = onRequestCreated;
if (isCrossposted) {
object2.failImmediatelyWhenRateLimited = true;
}
const HTTP = (require(507) /* metro dependency 507: HTTPUtils */).HTTP;
HTTP.patch(object2, responseHandler);
}
function _fun42473(a0, a1) { // fn#42473, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:2590, offset: 0x0113a6db, size: 23 bytes, params: 3, frame: 11
return env0_0.cancelQueueMetricTimers(a1);
}
function value_42471_superPropGet(a0, a1, a2, a3) { // fn#42474, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:2631, owner: value_42471._superPropGet, offset: 0x0113a6f2, size: 100 bytes, params: 5, frame: 18
let value = a0;
const env0_0 = a2;
const binding = env2_10;
value = env2_9(1 & 3 ? value.prototype : value);
value = binding(value, 'clear', a2);
return 2 & 3 ? typeof value !== 'function' ? value : _fun42475 : value;
}
function _fun42477(a0) { // fn#42477, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:2862, offset: 0x0113a789, size: 32 bytes, params: 2, frame: 13
const env0_0 = a0;
return global.setTimeout(_fun42478, a0);
}
function _fun42481(a0) { // fn#42481, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:3208, offset: 0x0113a84a, size: 291 bytes, params: 2, frame: 19
var binding;
var requests;
var binding2;
var code;
var value2;
var int;
var object2;
if (env0_1 != null) {
binding = env0_0;
requests = binding.requests;
binding2 = env0_1;
requests.delete(binding2);
binding.cancelQueueMetricTimers(binding2);
}
if (a0.hasErr) {
return require(null, a0);
}
if (a0.body == null) {
if (a0.status === 429) {
int = global.parseInt(a0.headers['retry-after']);
if (global.isNaN(int)) {
require(null, a0);
} else {
object2 = {};
value = environment.__proto__.__proto__;
object2.retryAfter = int * (importDefault(672) /* metro dependency 672: Durations */).Millis.SECOND;
require(object2);
}
} else {
require(null, a0);
}
} else {
code = a0.body.code;
value2 = environment.__proto__.__proto__;
if (code === AbortCodes.SLOWMODE_RATE_LIMITED) {
require(null, a0);
} else if (a0.body.code !== AbortCodes.CHANNEL_FOLLOWING_EDIT_RATE_LIMITED) {
if (a0.status === 429) {
int = global.parseInt(a0.headers['retry-after']);
if (global.isNaN(int)) {
require(null, a0);
} else {
object2 = {};
value = environment.__proto__.__proto__;
object2.retryAfter = int * (importDefault(672) /* metro dependency 672: Durations */).Millis.SECOND;
require(object2);
}
} else {
require(null, a0);
}
} else {
require(null, a0);
}
}
}
function value_42482OnRequestCreated() { // fn#42483, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:4248, owner: value_42482.onRequestCreated, offset: 0x0113ab39, size: 58 bytes, params: 1, frame: 13
var requests;
if (env0_1.nonce != null) {
requests = env0_0.requests;
requests.set(env0_1.nonce, env0_2);
}
}
function _fun42487(a0, a1) { // fn#42487, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:5459, offset: 0x0113ae99, size: 106 bytes, params: 3, frame: 16
const value = environment.__proto__.__proto__;
const defaultImport = importDefault(44) /* metro dependency 44 */;
const status = a0.status;
const CloudUploadStatus = (require(4648) /* metro dependency 4648: CloudUpload */).CloudUploadStatus;
const COMPLETED = CloudUploadStatus.COMPLETED;
defaultImport(status === COMPLETED, 'Uploads must be staged before trying to send a message');
return (require(4651) /* metro dependency 4651: UploadUtils */).getAttachmentPayload(a0, a1);
}
function value_42486OnRequestCreated(a0) { // fn#42488, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:5748, owner: value_42486.onRequestCreated, offset: 0x0113af03, size: 62 bytes, params: 2, frame: 14
const requests = env0_0.requests;
requests.set(nonce, env0_4);
a0.on('progress', _fun42489);
}
function handleEditOnRequestCreated() { // fn#42466, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:1463, owner: MessageQueue_42464.handleEdit.onRequestCreated, offset: 0x0113a441, size: 39 bytes, params: 1, frame: 13
const requests = env1_0.requests;
requests.set(messageId, env0_1);
}
function _fun42478() { // fn#42478, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:2877, offset: 0x0113a7a9, size: 65 bytes, params: 1, frame: 15
const appAnalyticsUtilsModule = require(4863) /* metro dependency 4863: AppAnalyticsUtils */;
const trackWithMetadata = appAnalyticsUtilsModule.trackWithMetadata;
const SEND_MESSAGE_QUEUED = AnalyticEvents.SEND_MESSAGE_QUEUED;
Reflect.apply(trackWithMetadata, appAnalyticsUtilsModule, [SEND_MESSAGE_QUEUED, {queued_duration_ms: env0_0}]);
}
function _fun42489({total}) { // fn#42489, source: /ci/build/discord/discord/discord_android_rn/android/app/src/main/assets/index.android.bundle:5040:5792, offset: 0x0113af41, size: 106 bytes, params: 2, frame: 15
var binding;
let value = environment.__proto__.__proto__.__proto__;
value = Reflect.apply((require(4655) /* metro dependency 4655: FileUtils */).maxFileSize, value, [guildId]);
if (total != null && total > value) {
binding = env1_0;
binding.cancelRequest(nonce);
if (maxSizeCallback != null) {
maxSizeCallback(value);
}
}
}