(MIT license)\n * @api private\n */\nconst re = /^(?:(?![^:@]+:[^:@\\/]*@)(http|https|ws|wss):\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/;\nconst parts = [\n 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'\n];\nexport function parse(str) {\n const src = str, b = str.indexOf('['), e = str.indexOf(']');\n if (b != -1 && e != -1) {\n str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);\n }\n let m = re.exec(str || ''), uri = {}, i = 14;\n while (i--) {\n uri[parts[i]] = m[i] || '';\n }\n if (b != -1 && e != -1) {\n uri.source = src;\n uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');\n uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');\n uri.ipv6uri = true;\n }\n uri.pathNames = pathNames(uri, uri['path']);\n uri.queryKey = queryKey(uri, uri['query']);\n return uri;\n}\nfunction pathNames(obj, path) {\n const regx = /\\/{2,9}/g, names = path.replace(regx, \"/\").split(\"/\");\n if (path.substr(0, 1) == '/' || path.length === 0) {\n names.splice(0, 1);\n }\n if (path.substr(path.length - 1, 1) == '/') {\n names.splice(names.length - 1, 1);\n }\n return names;\n}\nfunction queryKey(uri, query) {\n const data = {};\n query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {\n if ($1) {\n data[$1] = $2;\n }\n });\n return data;\n}\n","import { Socket as Engine, installTimerFunctions, } from \"engine.io-client\";\nimport { Socket } from \"./socket.js\";\nimport * as parser from \"socket.io-parser\";\nimport { on } from \"./on.js\";\nimport { Backoff } from \"./contrib/backo2.js\";\nimport { Emitter, } from \"@socket.io/component-emitter\";\nexport class Manager extends Emitter {\n constructor(uri, opts) {\n var _a;\n super();\n this.nsps = {};\n this.subs = [];\n if (uri && \"object\" === typeof uri) {\n opts = uri;\n uri = undefined;\n }\n opts = opts || {};\n opts.path = opts.path || \"/socket.io\";\n this.opts = opts;\n installTimerFunctions(this, opts);\n this.reconnection(opts.reconnection !== false);\n this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n this.reconnectionDelay(opts.reconnectionDelay || 1000);\n this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5);\n this.backoff = new Backoff({\n min: this.reconnectionDelay(),\n max: this.reconnectionDelayMax(),\n jitter: this.randomizationFactor(),\n });\n this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n this._readyState = \"closed\";\n this.uri = uri;\n const _parser = opts.parser || parser;\n this.encoder = new _parser.Encoder();\n this.decoder = new _parser.Decoder();\n this._autoConnect = opts.autoConnect !== false;\n if (this._autoConnect)\n this.open();\n }\n reconnection(v) {\n if (!arguments.length)\n return this._reconnection;\n this._reconnection = !!v;\n return this;\n }\n reconnectionAttempts(v) {\n if (v === undefined)\n return this._reconnectionAttempts;\n this._reconnectionAttempts = v;\n return this;\n }\n reconnectionDelay(v) {\n var _a;\n if (v === undefined)\n return this._reconnectionDelay;\n this._reconnectionDelay = v;\n (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v);\n return this;\n }\n randomizationFactor(v) {\n var _a;\n if (v === undefined)\n return this._randomizationFactor;\n this._randomizationFactor = v;\n (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v);\n return this;\n }\n reconnectionDelayMax(v) {\n var _a;\n if (v === undefined)\n return this._reconnectionDelayMax;\n this._reconnectionDelayMax = v;\n (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v);\n return this;\n }\n timeout(v) {\n if (!arguments.length)\n return this._timeout;\n this._timeout = v;\n return this;\n }\n /**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @private\n */\n maybeReconnectOnOpen() {\n // Only try to reconnect if it's the first time we're connecting\n if (!this._reconnecting &&\n this._reconnection &&\n this.backoff.attempts === 0) {\n // keeps reconnection from firing twice for the same reconnection loop\n this.reconnect();\n }\n }\n /**\n * Sets the current transport `socket`.\n *\n * @param {Function} fn - optional, callback\n * @return self\n * @public\n */\n open(fn) {\n if (~this._readyState.indexOf(\"open\"))\n return this;\n this.engine = new Engine(this.uri, this.opts);\n const socket = this.engine;\n const self = this;\n this._readyState = \"opening\";\n this.skipReconnect = false;\n // emit `open`\n const openSubDestroy = on(socket, \"open\", function () {\n self.onopen();\n fn && fn();\n });\n // emit `error`\n const errorSub = on(socket, \"error\", (err) => {\n self.cleanup();\n self._readyState = \"closed\";\n this.emitReserved(\"error\", err);\n if (fn) {\n fn(err);\n }\n else {\n // Only do this if there is no fn to handle the error\n self.maybeReconnectOnOpen();\n }\n });\n if (false !== this._timeout) {\n const timeout = this._timeout;\n if (timeout === 0) {\n openSubDestroy(); // prevents a race condition with the 'open' event\n }\n // set timer\n const timer = this.setTimeoutFn(() => {\n openSubDestroy();\n socket.close();\n // @ts-ignore\n socket.emit(\"error\", new Error(\"timeout\"));\n }, timeout);\n if (this.opts.autoUnref) {\n timer.unref();\n }\n this.subs.push(function subDestroy() {\n clearTimeout(timer);\n });\n }\n this.subs.push(openSubDestroy);\n this.subs.push(errorSub);\n return this;\n }\n /**\n * Alias for open()\n *\n * @return self\n * @public\n */\n connect(fn) {\n return this.open(fn);\n }\n /**\n * Called upon transport open.\n *\n * @private\n */\n onopen() {\n // clear old subs\n this.cleanup();\n // mark as open\n this._readyState = \"open\";\n this.emitReserved(\"open\");\n // add new subs\n const socket = this.engine;\n this.subs.push(on(socket, \"ping\", this.onping.bind(this)), on(socket, \"data\", this.ondata.bind(this)), on(socket, \"error\", this.onerror.bind(this)), on(socket, \"close\", this.onclose.bind(this)), on(this.decoder, \"decoded\", this.ondecoded.bind(this)));\n }\n /**\n * Called upon a ping.\n *\n * @private\n */\n onping() {\n this.emitReserved(\"ping\");\n }\n /**\n * Called with data.\n *\n * @private\n */\n ondata(data) {\n this.decoder.add(data);\n }\n /**\n * Called when parser fully decodes a packet.\n *\n * @private\n */\n ondecoded(packet) {\n this.emitReserved(\"packet\", packet);\n }\n /**\n * Called upon socket error.\n *\n * @private\n */\n onerror(err) {\n this.emitReserved(\"error\", err);\n }\n /**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @public\n */\n socket(nsp, opts) {\n let socket = this.nsps[nsp];\n if (!socket) {\n socket = new Socket(this, nsp, opts);\n this.nsps[nsp] = socket;\n }\n return socket;\n }\n /**\n * Called upon a socket close.\n *\n * @param socket\n * @private\n */\n _destroy(socket) {\n const nsps = Object.keys(this.nsps);\n for (const nsp of nsps) {\n const socket = this.nsps[nsp];\n if (socket.active) {\n return;\n }\n }\n this._close();\n }\n /**\n * Writes a packet.\n *\n * @param packet\n * @private\n */\n _packet(packet) {\n const encodedPackets = this.encoder.encode(packet);\n for (let i = 0; i < encodedPackets.length; i++) {\n this.engine.write(encodedPackets[i], packet.options);\n }\n }\n /**\n * Clean up transport subscriptions and packet buffer.\n *\n * @private\n */\n cleanup() {\n this.subs.forEach((subDestroy) => subDestroy());\n this.subs.length = 0;\n this.decoder.destroy();\n }\n /**\n * Close the current socket.\n *\n * @private\n */\n _close() {\n this.skipReconnect = true;\n this._reconnecting = false;\n this.onclose(\"forced close\");\n if (this.engine)\n this.engine.close();\n }\n /**\n * Alias for close()\n *\n * @private\n */\n disconnect() {\n return this._close();\n }\n /**\n * Called upon engine close.\n *\n * @private\n */\n onclose(reason, description) {\n this.cleanup();\n this.backoff.reset();\n this._readyState = \"closed\";\n this.emitReserved(\"close\", reason, description);\n if (this._reconnection && !this.skipReconnect) {\n this.reconnect();\n }\n }\n /**\n * Attempt a reconnection.\n *\n * @private\n */\n reconnect() {\n if (this._reconnecting || this.skipReconnect)\n return this;\n const self = this;\n if (this.backoff.attempts >= this._reconnectionAttempts) {\n this.backoff.reset();\n this.emitReserved(\"reconnect_failed\");\n this._reconnecting = false;\n }\n else {\n const delay = this.backoff.duration();\n this._reconnecting = true;\n const timer = this.setTimeoutFn(() => {\n if (self.skipReconnect)\n return;\n this.emitReserved(\"reconnect_attempt\", self.backoff.attempts);\n // check again for the case socket closed in above events\n if (self.skipReconnect)\n return;\n self.open((err) => {\n if (err) {\n self._reconnecting = false;\n self.reconnect();\n this.emitReserved(\"reconnect_error\", err);\n }\n else {\n self.onreconnect();\n }\n });\n }, delay);\n if (this.opts.autoUnref) {\n timer.unref();\n }\n this.subs.push(function subDestroy() {\n clearTimeout(timer);\n });\n }\n }\n /**\n * Called upon successful reconnect.\n *\n * @private\n */\n onreconnect() {\n const attempt = this.backoff.attempts;\n this._reconnecting = false;\n this.backoff.reset();\n this.emitReserved(\"reconnect\", attempt);\n }\n}\n","import { PacketType } from \"socket.io-parser\";\nimport { on } from \"./on.js\";\nimport { Emitter, } from \"@socket.io/component-emitter\";\n/**\n * Internal events.\n * These events can't be emitted by the user.\n */\nconst RESERVED_EVENTS = Object.freeze({\n connect: 1,\n connect_error: 1,\n disconnect: 1,\n disconnecting: 1,\n // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener\n newListener: 1,\n removeListener: 1,\n});\nexport class Socket extends Emitter {\n /**\n * `Socket` constructor.\n *\n * @public\n */\n constructor(io, nsp, opts) {\n super();\n this.connected = false;\n this.receiveBuffer = [];\n this.sendBuffer = [];\n this.ids = 0;\n this.acks = {};\n this.flags = {};\n this.io = io;\n this.nsp = nsp;\n if (opts && opts.auth) {\n this.auth = opts.auth;\n }\n if (this.io._autoConnect)\n this.open();\n }\n /**\n * Whether the socket is currently disconnected\n */\n get disconnected() {\n return !this.connected;\n }\n /**\n * Subscribe to open, close and packet events\n *\n * @private\n */\n subEvents() {\n if (this.subs)\n return;\n const io = this.io;\n this.subs = [\n on(io, \"open\", this.onopen.bind(this)),\n on(io, \"packet\", this.onpacket.bind(this)),\n on(io, \"error\", this.onerror.bind(this)),\n on(io, \"close\", this.onclose.bind(this)),\n ];\n }\n /**\n * Whether the Socket will try to reconnect when its Manager connects or reconnects\n */\n get active() {\n return !!this.subs;\n }\n /**\n * \"Opens\" the socket.\n *\n * @public\n */\n connect() {\n if (this.connected)\n return this;\n this.subEvents();\n if (!this.io[\"_reconnecting\"])\n this.io.open(); // ensure open\n if (\"open\" === this.io._readyState)\n this.onopen();\n return this;\n }\n /**\n * Alias for connect()\n */\n open() {\n return this.connect();\n }\n /**\n * Sends a `message` event.\n *\n * @return self\n * @public\n */\n send(...args) {\n args.unshift(\"message\");\n this.emit.apply(this, args);\n return this;\n }\n /**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @return self\n * @public\n */\n emit(ev, ...args) {\n if (RESERVED_EVENTS.hasOwnProperty(ev)) {\n throw new Error('\"' + ev + '\" is a reserved event name');\n }\n args.unshift(ev);\n const packet = {\n type: PacketType.EVENT,\n data: args,\n };\n packet.options = {};\n packet.options.compress = this.flags.compress !== false;\n // event ack callback\n if (\"function\" === typeof args[args.length - 1]) {\n const id = this.ids++;\n const ack = args.pop();\n this._registerAckCallback(id, ack);\n packet.id = id;\n }\n const isTransportWritable = this.io.engine &&\n this.io.engine.transport &&\n this.io.engine.transport.writable;\n const discardPacket = this.flags.volatile && (!isTransportWritable || !this.connected);\n if (discardPacket) {\n }\n else if (this.connected) {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n }\n else {\n this.sendBuffer.push(packet);\n }\n this.flags = {};\n return this;\n }\n /**\n * @private\n */\n _registerAckCallback(id, ack) {\n const timeout = this.flags.timeout;\n if (timeout === undefined) {\n this.acks[id] = ack;\n return;\n }\n // @ts-ignore\n const timer = this.io.setTimeoutFn(() => {\n delete this.acks[id];\n for (let i = 0; i < this.sendBuffer.length; i++) {\n if (this.sendBuffer[i].id === id) {\n this.sendBuffer.splice(i, 1);\n }\n }\n ack.call(this, new Error(\"operation has timed out\"));\n }, timeout);\n this.acks[id] = (...args) => {\n // @ts-ignore\n this.io.clearTimeoutFn(timer);\n ack.apply(this, [null, ...args]);\n };\n }\n /**\n * Sends a packet.\n *\n * @param packet\n * @private\n */\n packet(packet) {\n packet.nsp = this.nsp;\n this.io._packet(packet);\n }\n /**\n * Called upon engine `open`.\n *\n * @private\n */\n onopen() {\n if (typeof this.auth == \"function\") {\n this.auth((data) => {\n this.packet({ type: PacketType.CONNECT, data });\n });\n }\n else {\n this.packet({ type: PacketType.CONNECT, data: this.auth });\n }\n }\n /**\n * Called upon engine or manager `error`.\n *\n * @param err\n * @private\n */\n onerror(err) {\n if (!this.connected) {\n this.emitReserved(\"connect_error\", err);\n }\n }\n /**\n * Called upon engine `close`.\n *\n * @param reason\n * @param description\n * @private\n */\n onclose(reason, description) {\n this.connected = false;\n delete this.id;\n this.emitReserved(\"disconnect\", reason, description);\n }\n /**\n * Called with socket packet.\n *\n * @param packet\n * @private\n */\n onpacket(packet) {\n const sameNamespace = packet.nsp === this.nsp;\n if (!sameNamespace)\n return;\n switch (packet.type) {\n case PacketType.CONNECT:\n if (packet.data && packet.data.sid) {\n const id = packet.data.sid;\n this.onconnect(id);\n }\n else {\n this.emitReserved(\"connect_error\", new Error(\"It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)\"));\n }\n break;\n case PacketType.EVENT:\n case PacketType.BINARY_EVENT:\n this.onevent(packet);\n break;\n case PacketType.ACK:\n case PacketType.BINARY_ACK:\n this.onack(packet);\n break;\n case PacketType.DISCONNECT:\n this.ondisconnect();\n break;\n case PacketType.CONNECT_ERROR:\n this.destroy();\n const err = new Error(packet.data.message);\n // @ts-ignore\n err.data = packet.data.data;\n this.emitReserved(\"connect_error\", err);\n break;\n }\n }\n /**\n * Called upon a server event.\n *\n * @param packet\n * @private\n */\n onevent(packet) {\n const args = packet.data || [];\n if (null != packet.id) {\n args.push(this.ack(packet.id));\n }\n if (this.connected) {\n this.emitEvent(args);\n }\n else {\n this.receiveBuffer.push(Object.freeze(args));\n }\n }\n emitEvent(args) {\n if (this._anyListeners && this._anyListeners.length) {\n const listeners = this._anyListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, args);\n }\n }\n super.emit.apply(this, args);\n }\n /**\n * Produces an ack callback to emit with an event.\n *\n * @private\n */\n ack(id) {\n const self = this;\n let sent = false;\n return function (...args) {\n // prevent double callbacks\n if (sent)\n return;\n sent = true;\n self.packet({\n type: PacketType.ACK,\n id: id,\n data: args,\n });\n };\n }\n /**\n * Called upon a server acknowlegement.\n *\n * @param packet\n * @private\n */\n onack(packet) {\n const ack = this.acks[packet.id];\n if (\"function\" === typeof ack) {\n ack.apply(this, packet.data);\n delete this.acks[packet.id];\n }\n else {\n }\n }\n /**\n * Called upon server connect.\n *\n * @private\n */\n onconnect(id) {\n this.id = id;\n this.connected = true;\n this.emitBuffered();\n this.emitReserved(\"connect\");\n }\n /**\n * Emit buffered events (received and emitted).\n *\n * @private\n */\n emitBuffered() {\n this.receiveBuffer.forEach((args) => this.emitEvent(args));\n this.receiveBuffer = [];\n this.sendBuffer.forEach((packet) => {\n this.notifyOutgoingListeners(packet);\n this.packet(packet);\n });\n this.sendBuffer = [];\n }\n /**\n * Called upon server disconnect.\n *\n * @private\n */\n ondisconnect() {\n this.destroy();\n this.onclose(\"io server disconnect\");\n }\n /**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @private\n */\n destroy() {\n if (this.subs) {\n // clean subscriptions to avoid reconnections\n this.subs.forEach((subDestroy) => subDestroy());\n this.subs = undefined;\n }\n this.io[\"_destroy\"](this);\n }\n /**\n * Disconnects the socket manually.\n *\n * @return self\n * @public\n */\n disconnect() {\n if (this.connected) {\n this.packet({ type: PacketType.DISCONNECT });\n }\n // remove socket from pool\n this.destroy();\n if (this.connected) {\n // fire events\n this.onclose(\"io client disconnect\");\n }\n return this;\n }\n /**\n * Alias for disconnect()\n *\n * @return self\n * @public\n */\n close() {\n return this.disconnect();\n }\n /**\n * Sets the compress flag.\n *\n * @param compress - if `true`, compresses the sending data\n * @return self\n * @public\n */\n compress(compress) {\n this.flags.compress = compress;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not\n * ready to send messages.\n *\n * @returns self\n * @public\n */\n get volatile() {\n this.flags.volatile = true;\n return this;\n }\n /**\n * Sets a modifier for a subsequent event emission that the callback will be called with an error when the\n * given number of milliseconds have elapsed without an acknowledgement from the server:\n *\n * ```\n * socket.timeout(5000).emit(\"my-event\", (err) => {\n * if (err) {\n * // the server did not acknowledge the event in the given delay\n * }\n * });\n * ```\n *\n * @returns self\n * @public\n */\n timeout(timeout) {\n this.flags.timeout = timeout;\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * @param listener\n * @public\n */\n onAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * @param listener\n * @public\n */\n prependAny(listener) {\n this._anyListeners = this._anyListeners || [];\n this._anyListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @param listener\n * @public\n */\n offAny(listener) {\n if (!this._anyListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n *\n * @public\n */\n listenersAny() {\n return this._anyListeners || [];\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback.\n *\n * @param listener\n *\n * \n *\n * socket.onAnyOutgoing((event, ...args) => {\n * console.log(event);\n * });\n *\n *
\n *\n * @public\n */\n onAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.push(listener);\n return this;\n }\n /**\n * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the\n * callback. The listener is added to the beginning of the listeners array.\n *\n * @param listener\n *\n * \n *\n * socket.prependAnyOutgoing((event, ...args) => {\n * console.log(event);\n * });\n *\n *
\n *\n * @public\n */\n prependAnyOutgoing(listener) {\n this._anyOutgoingListeners = this._anyOutgoingListeners || [];\n this._anyOutgoingListeners.unshift(listener);\n return this;\n }\n /**\n * Removes the listener that will be fired when any event is emitted.\n *\n * @param listener\n *\n * \n *\n * const handler = (event, ...args) => {\n * console.log(event);\n * }\n *\n * socket.onAnyOutgoing(handler);\n *\n * // then later\n * socket.offAnyOutgoing(handler);\n *\n *
\n *\n * @public\n */\n offAnyOutgoing(listener) {\n if (!this._anyOutgoingListeners) {\n return this;\n }\n if (listener) {\n const listeners = this._anyOutgoingListeners;\n for (let i = 0; i < listeners.length; i++) {\n if (listener === listeners[i]) {\n listeners.splice(i, 1);\n return this;\n }\n }\n }\n else {\n this._anyOutgoingListeners = [];\n }\n return this;\n }\n /**\n * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,\n * e.g. to remove listeners.\n *\n * @public\n */\n listenersAnyOutgoing() {\n return this._anyOutgoingListeners || [];\n }\n /**\n * Notify the listeners for each packet sent\n *\n * @param packet\n *\n * @private\n */\n notifyOutgoingListeners(packet) {\n if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {\n const listeners = this._anyOutgoingListeners.slice();\n for (const listener of listeners) {\n listener.apply(this, packet.data);\n }\n }\n }\n}\n","import { Emitter } from \"@socket.io/component-emitter\";\nimport { deconstructPacket, reconstructPacket } from \"./binary.js\";\nimport { isBinary, hasBinary } from \"./is-binary.js\";\n/**\n * Protocol version.\n *\n * @public\n */\nexport const protocol = 5;\nexport var PacketType;\n(function (PacketType) {\n PacketType[PacketType[\"CONNECT\"] = 0] = \"CONNECT\";\n PacketType[PacketType[\"DISCONNECT\"] = 1] = \"DISCONNECT\";\n PacketType[PacketType[\"EVENT\"] = 2] = \"EVENT\";\n PacketType[PacketType[\"ACK\"] = 3] = \"ACK\";\n PacketType[PacketType[\"CONNECT_ERROR\"] = 4] = \"CONNECT_ERROR\";\n PacketType[PacketType[\"BINARY_EVENT\"] = 5] = \"BINARY_EVENT\";\n PacketType[PacketType[\"BINARY_ACK\"] = 6] = \"BINARY_ACK\";\n})(PacketType || (PacketType = {}));\n/**\n * A socket.io Encoder instance\n */\nexport class Encoder {\n /**\n * Encoder constructor\n *\n * @param {function} replacer - custom replacer to pass down to JSON.parse\n */\n constructor(replacer) {\n this.replacer = replacer;\n }\n /**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n */\n encode(obj) {\n if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) {\n if (hasBinary(obj)) {\n obj.type =\n obj.type === PacketType.EVENT\n ? PacketType.BINARY_EVENT\n : PacketType.BINARY_ACK;\n return this.encodeAsBinary(obj);\n }\n }\n return [this.encodeAsString(obj)];\n }\n /**\n * Encode packet as string.\n */\n encodeAsString(obj) {\n // first is type\n let str = \"\" + obj.type;\n // attachments if we have them\n if (obj.type === PacketType.BINARY_EVENT ||\n obj.type === PacketType.BINARY_ACK) {\n str += obj.attachments + \"-\";\n }\n // if we have a namespace other than `/`\n // we append it followed by a comma `,`\n if (obj.nsp && \"/\" !== obj.nsp) {\n str += obj.nsp + \",\";\n }\n // immediately followed by the id\n if (null != obj.id) {\n str += obj.id;\n }\n // json data\n if (null != obj.data) {\n str += JSON.stringify(obj.data, this.replacer);\n }\n return str;\n }\n /**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n */\n encodeAsBinary(obj) {\n const deconstruction = deconstructPacket(obj);\n const pack = this.encodeAsString(deconstruction.packet);\n const buffers = deconstruction.buffers;\n buffers.unshift(pack); // add packet info to beginning of data list\n return buffers; // write all the buffers\n }\n}\n/**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n */\nexport class Decoder extends Emitter {\n /**\n * Decoder constructor\n *\n * @param {function} reviver - custom reviver to pass down to JSON.stringify\n */\n constructor(reviver) {\n super();\n this.reviver = reviver;\n }\n /**\n * Decodes an encoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n */\n add(obj) {\n let packet;\n if (typeof obj === \"string\") {\n packet = this.decodeString(obj);\n if (packet.type === PacketType.BINARY_EVENT ||\n packet.type === PacketType.BINARY_ACK) {\n // binary packet's json\n this.reconstructor = new BinaryReconstructor(packet);\n // no attachments, labeled binary but no binary data to follow\n if (packet.attachments === 0) {\n super.emitReserved(\"decoded\", packet);\n }\n }\n else {\n // non-binary full packet\n super.emitReserved(\"decoded\", packet);\n }\n }\n else if (isBinary(obj) || obj.base64) {\n // raw binary data\n if (!this.reconstructor) {\n throw new Error(\"got binary data when not reconstructing a packet\");\n }\n else {\n packet = this.reconstructor.takeBinaryData(obj);\n if (packet) {\n // received final buffer\n this.reconstructor = null;\n super.emitReserved(\"decoded\", packet);\n }\n }\n }\n else {\n throw new Error(\"Unknown type: \" + obj);\n }\n }\n /**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n */\n decodeString(str) {\n let i = 0;\n // look up type\n const p = {\n type: Number(str.charAt(0)),\n };\n if (PacketType[p.type] === undefined) {\n throw new Error(\"unknown packet type \" + p.type);\n }\n // look up attachments if type binary\n if (p.type === PacketType.BINARY_EVENT ||\n p.type === PacketType.BINARY_ACK) {\n const start = i + 1;\n while (str.charAt(++i) !== \"-\" && i != str.length) { }\n const buf = str.substring(start, i);\n if (buf != Number(buf) || str.charAt(i) !== \"-\") {\n throw new Error(\"Illegal attachments\");\n }\n p.attachments = Number(buf);\n }\n // look up namespace (if any)\n if (\"/\" === str.charAt(i + 1)) {\n const start = i + 1;\n while (++i) {\n const c = str.charAt(i);\n if (\",\" === c)\n break;\n if (i === str.length)\n break;\n }\n p.nsp = str.substring(start, i);\n }\n else {\n p.nsp = \"/\";\n }\n // look up id\n const next = str.charAt(i + 1);\n if (\"\" !== next && Number(next) == next) {\n const start = i + 1;\n while (++i) {\n const c = str.charAt(i);\n if (null == c || Number(c) != c) {\n --i;\n break;\n }\n if (i === str.length)\n break;\n }\n p.id = Number(str.substring(start, i + 1));\n }\n // look up json data\n if (str.charAt(++i)) {\n const payload = this.tryParse(str.substr(i));\n if (Decoder.isPayloadValid(p.type, payload)) {\n p.data = payload;\n }\n else {\n throw new Error(\"invalid payload\");\n }\n }\n return p;\n }\n tryParse(str) {\n try {\n return JSON.parse(str, this.reviver);\n }\n catch (e) {\n return false;\n }\n }\n static isPayloadValid(type, payload) {\n switch (type) {\n case PacketType.CONNECT:\n return typeof payload === \"object\";\n case PacketType.DISCONNECT:\n return payload === undefined;\n case PacketType.CONNECT_ERROR:\n return typeof payload === \"string\" || typeof payload === \"object\";\n case PacketType.EVENT:\n case PacketType.BINARY_EVENT:\n return Array.isArray(payload) && payload.length > 0;\n case PacketType.ACK:\n case PacketType.BINARY_ACK:\n return Array.isArray(payload);\n }\n }\n /**\n * Deallocates a parser's resources\n */\n destroy() {\n if (this.reconstructor) {\n this.reconstructor.finishedReconstruction();\n }\n }\n}\n/**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n */\nclass BinaryReconstructor {\n constructor(packet) {\n this.packet = packet;\n this.buffers = [];\n this.reconPack = packet;\n }\n /**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n * a reconstructed packet object if all buffers have been received.\n */\n takeBinaryData(binData) {\n this.buffers.push(binData);\n if (this.buffers.length === this.reconPack.attachments) {\n // done with buffer list\n const packet = reconstructPacket(this.reconPack, this.buffers);\n this.finishedReconstruction();\n return packet;\n }\n return null;\n }\n /**\n * Cleans up binary packet reconstruction variables.\n */\n finishedReconstruction() {\n this.reconPack = null;\n this.buffers = [];\n }\n}\n","import { isBinary } from \"./is-binary.js\";\n/**\n * Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @public\n */\nexport function deconstructPacket(packet) {\n const buffers = [];\n const packetData = packet.data;\n const pack = packet;\n pack.data = _deconstructPacket(packetData, buffers);\n pack.attachments = buffers.length; // number of binary 'attachments'\n return { packet: pack, buffers: buffers };\n}\nfunction _deconstructPacket(data, buffers) {\n if (!data)\n return data;\n if (isBinary(data)) {\n const placeholder = { _placeholder: true, num: buffers.length };\n buffers.push(data);\n return placeholder;\n }\n else if (Array.isArray(data)) {\n const newData = new Array(data.length);\n for (let i = 0; i < data.length; i++) {\n newData[i] = _deconstructPacket(data[i], buffers);\n }\n return newData;\n }\n else if (typeof data === \"object\" && !(data instanceof Date)) {\n const newData = {};\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n newData[key] = _deconstructPacket(data[key], buffers);\n }\n }\n return newData;\n }\n return data;\n}\n/**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @public\n */\nexport function reconstructPacket(packet, buffers) {\n packet.data = _reconstructPacket(packet.data, buffers);\n packet.attachments = undefined; // no longer useful\n return packet;\n}\nfunction _reconstructPacket(data, buffers) {\n if (!data)\n return data;\n if (data && data._placeholder) {\n return buffers[data.num]; // appropriate buffer (should be natural order anyway)\n }\n else if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n data[i] = _reconstructPacket(data[i], buffers);\n }\n }\n else if (typeof data === \"object\") {\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n data[key] = _reconstructPacket(data[key], buffers);\n }\n }\n }\n return data;\n}\n","const withNativeArrayBuffer = typeof ArrayBuffer === \"function\";\nconst isView = (obj) => {\n return typeof ArrayBuffer.isView === \"function\"\n ? ArrayBuffer.isView(obj)\n : obj.buffer instanceof ArrayBuffer;\n};\nconst toString = Object.prototype.toString;\nconst withNativeBlob = typeof Blob === \"function\" ||\n (typeof Blob !== \"undefined\" &&\n toString.call(Blob) === \"[object BlobConstructor]\");\nconst withNativeFile = typeof File === \"function\" ||\n (typeof File !== \"undefined\" &&\n toString.call(File) === \"[object FileConstructor]\");\n/**\n * Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File.\n *\n * @private\n */\nexport function isBinary(obj) {\n return ((withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))) ||\n (withNativeBlob && obj instanceof Blob) ||\n (withNativeFile && obj instanceof File));\n}\nexport function hasBinary(obj, toJSON) {\n if (!obj || typeof obj !== \"object\") {\n return false;\n }\n if (Array.isArray(obj)) {\n for (let i = 0, l = obj.length; i < l; i++) {\n if (hasBinary(obj[i])) {\n return true;\n }\n }\n return false;\n }\n if (isBinary(obj)) {\n return true;\n }\n if (obj.toJSON &&\n typeof obj.toJSON === \"function\" &&\n arguments.length === 1) {\n return hasBinary(obj.toJSON(), true);\n }\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {\n return true;\n }\n }\n return false;\n}\n","export function on(obj, ev, fn) {\n obj.on(ev, fn);\n return function subDestroy() {\n obj.off(ev, fn);\n };\n}\n","/**\n * Initialize backoff timer with `opts`.\n *\n * - `min` initial timeout in milliseconds [100]\n * - `max` max timeout [10000]\n * - `jitter` [0]\n * - `factor` [2]\n *\n * @param {Object} opts\n * @api public\n */\nexport function Backoff(opts) {\n opts = opts || {};\n this.ms = opts.min || 100;\n this.max = opts.max || 10000;\n this.factor = opts.factor || 2;\n this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;\n this.attempts = 0;\n}\n/**\n * Return the backoff duration.\n *\n * @return {Number}\n * @api public\n */\nBackoff.prototype.duration = function () {\n var ms = this.ms * Math.pow(this.factor, this.attempts++);\n if (this.jitter) {\n var rand = Math.random();\n var deviation = Math.floor(rand * this.jitter * ms);\n ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;\n }\n return Math.min(ms, this.max) | 0;\n};\n/**\n * Reset the number of attempts.\n *\n * @api public\n */\nBackoff.prototype.reset = function () {\n this.attempts = 0;\n};\n/**\n * Set the minimum duration\n *\n * @api public\n */\nBackoff.prototype.setMin = function (min) {\n this.ms = min;\n};\n/**\n * Set the maximum duration\n *\n * @api public\n */\nBackoff.prototype.setMax = function (max) {\n this.max = max;\n};\n/**\n * Set the jitter\n *\n * @api public\n */\nBackoff.prototype.setJitter = function (jitter) {\n this.jitter = jitter;\n};\n","import { PureComponent } from 'react';\nimport {\n Badge,\n ButtonGroup,\n Card,\n ListGroup,\n ToggleButton\n} from 'react-bootstrap';\nimport { Select, Option } from 'idea-react';\n\nimport * as styles from './index.module.less';\nimport {\n DepthItem,\n DepthLevel,\n DepthType\n} from '../../../model/canister/Depth';\nimport { observer } from 'mobx-react';\nimport { SpotOrderType } from '../../../model/canister/Fusion';\nimport { formatNumber } from '../../../model/utils/helper';\nimport classnames from 'classnames';\nimport { LatestPrice, PriceTrend } from '../../../model/market';\nimport BigNumber from 'bignumber.js';\n\ninterface Props {\n askOrders?: Array;\n bidOrders?: Array;\n type?: DepthType;\n levels?: Array;\n level?: DepthLevel;\n count?: number;\n latestPrice?: LatestPrice;\n orderPricePrecision?: number;\n depthVolumePrecision?: number;\n baseTokenPrecision?: number;\n baseTokenSymbol?: string;\n quoteTokenSymbol?: string;\n onChangeDepthType?: (depthType: DepthType) => void;\n onChangeDepthLevel?: (level: DepthLevel) => void;\n onAskOrderClick?: (order: DepthItem) => void;\n onBidOrderClick?: (order: DepthItem) => void;\n}\n\n@observer\nexport class Depth extends PureComponent {\n radios = [DepthType.All, DepthType.Bid, DepthType.Ask].map(d =>\n DepthType[d].toString()\n );\n\n renderButtonGroup() {\n const { type = DepthType.All, onChangeDepthType = () => {} } = this.props;\n return (\n \n {this.radios.map((radio, idx) => (\n onChangeDepthType(DepthType[radio])}\n />\n ))}\n \n );\n }\n\n renderSelect() {\n const {\n level = DepthLevel.Two,\n levels = [],\n onChangeDepthLevel = () => {}\n } = this.props;\n\n return (\n \n onChangeDepthLevel(DepthLevel[v])}\n >\n {levels.map((item, idx) => (\n \n {item}\n \n ))}\n \n
\n );\n }\n\n renderTitle() {\n const { baseTokenSymbol = '', quoteTokenSymbol = '' } = this.props;\n return (\n \n \n Price {quoteTokenSymbol} \n \n \n Amount {baseTokenSymbol} \n \n \n Sum {baseTokenSymbol} \n \n \n );\n }\n\n renderPrice() {\n const {\n type = DepthType.All,\n latestPrice = { price: 0, trend: PriceTrend.Equal },\n orderPricePrecision = 2\n } = this.props;\n return (\n \n \n {formatNumber(latestPrice.price, orderPricePrecision)}\n \n ≈ {formatNumber(latestPrice.price, orderPricePrecision)} \n
\n );\n }\n\n renderOrderList(orders: DepthItem[], type: SpotOrderType) {\n const {\n onAskOrderClick = () => {},\n onBidOrderClick = () => {},\n levels = [],\n level = 1,\n baseTokenPrecision = 0\n } = this.props;\n const miniPrice = levels[level - 1];\n const depthPriceDecimals = new BigNumber(miniPrice).dp();\n let volumeSum = new BigNumber(0);\n let maxVolume = new BigNumber(0);\n\n orders.forEach(order => {\n maxVolume = BigNumber.max(maxVolume, order.volume);\n });\n\n let renderOrders: Array<{\n price: BigNumber;\n volume: BigNumber;\n sum: BigNumber;\n percent: BigNumber;\n }> = orders.map(order => {\n const { price, volume } = order;\n volumeSum = volumeSum.plus(volume);\n return {\n price: price,\n volume: volume,\n sum: volumeSum,\n percent: volume.div(maxVolume).times(100)\n };\n });\n\n if (type === SpotOrderType.Ask) renderOrders = renderOrders.reverse();\n\n return renderOrders.length > 0 ? (\n \n {renderOrders.map(({ price, volume, sum, percent }, idx) => (\n {\n type === SpotOrderType.Ask\n ? onAskOrderClick(renderOrders[idx])\n : onBidOrderClick(renderOrders[idx]);\n }}\n >\n \n {formatNumber(price, depthPriceDecimals)}\n \n \n {formatNumber(volume, baseTokenPrecision)}\n \n \n {formatNumber(sum, baseTokenPrecision)}\n \n \n ))}\n \n ) : (\n no data
\n );\n }\n\n render() {\n const { askOrders = [], bidOrders = [], type = DepthType.All } = this.props;\n return (\n \n \n {this.renderButtonGroup()}\n {this.renderSelect()}\n \n\n {this.renderTitle()}\n\n \n {type === DepthType.All || type === DepthType.Ask\n ? this.renderOrderList(askOrders, SpotOrderType.Ask)\n : null}\n\n {this.renderPrice()}\n\n {type === DepthType.All || type === DepthType.Bid\n ? this.renderOrderList(bidOrders, SpotOrderType.Bid)\n : null}\n \n \n );\n }\n}\n",".depth-wrap {\n border: none;\n border-radius: 0;\n height: 100%;\n width: 18.75rem;\n}\n\n.depth-header {\n display: flex;\n align-content: center;\n justify-content: space-between;\n height: 46px;\n padding: 10px 1rem;\n border: none;\n}\n\n.toggle-btn {\n width: 26px;\n height: 26px;\n outline: none;\n box-shadow: none !important;\n background-repeat: no-repeat;\n background-position: center;\n background-color: transparent;\n margin-right: 6px;\n border-radius: 0 !important;\n border: none;\n &:hover {\n background-color: rgba(9, 13, 26, 1);\n }\n &.all {\n background-image: url(./images/trade-icon-all.svg);\n }\n &.bid {\n background-image: url(./images/trade-icon-sell.svg);\n }\n &.ask {\n background-image: url(./images/trade-icon-buy.svg);\n }\n}\n.toggle-btn-group {\n :global {\n .btn-check:active + .btn-primary,\n .btn-check:checked + .btn-primary,\n .btn-primary.active,\n .btn-primary:active,\n .show > .btn-primary.dropdown-toggle {\n background-color: rgba(9, 13, 26, 1);\n }\n }\n}\n.depth-select {\n :global {\n .btn {\n height: 26px;\n border-color: transparent;\n box-shadow: none !important;\n }\n .dropdown-menu {\n width: 80px;\n min-width: 80px;\n }\n }\n}\n\n.trade-list-header {\n margin-bottom: 0;\n height: 32px;\n padding: 0 1rem;\n white-space: nowrap;\n font-size: 12px !important;\n & > .title-item {\n width: 33.33%;\n color: #5f7195;\n text-align: right;\n }\n & > .title-item:first-child {\n text-align: left;\n }\n .badge {\n background-color: rgba(33, 42, 69, 1) !important;\n font-weight: 400;\n }\n}\n.trade-list-sell,\n.trade-list-buy,\n.no-data {\n display: flex;\n flex-direction: column;\n margin-bottom: 0;\n color: #f4f9ff !important;\n min-height: 300px;\n font-family: Poppins-Regular, Poppins;\n}\n.no-data {\n align-items: center;\n justify-content: center;\n color: #5f7195 !important;\n}\n.trade-list-sell {\n margin-top: auto;\n}\n.depth-body {\n padding: 0 !important;\n display: flex;\n flex-direction: column;\n}\n.depth-all .trade-list-sell {\n margin-top: 0;\n}\n\n.trade-list-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n height: 30px;\n padding: 0 1rem;\n border: none;\n background-position: 100%;\n background-repeat: no-repeat;\n color: #fff;\n border-radius: 0 !important;\n &:hover {\n background-color: rgba(37, 42, 68, 0.5) !important;\n }\n & > span {\n width: 33.33%;\n text-align: right;\n }\n .trade-list-price {\n text-align: left;\n }\n}\n.trade-list-sell {\n justify-content: flex-end;\n .trade-list-price {\n color: #ec4953;\n }\n .trade-list-item {\n background-image: linear-gradient(\n rgba(236, 73, 83, 0.1),\n rgba(236, 73, 83, 0.1)\n );\n }\n}\n.trade-list-buy {\n .trade-list-price {\n color: #0fbeaf;\n }\n .trade-list-item {\n background-image: linear-gradient(\n rgba(18, 184, 134, 0.1),\n rgba(18, 184, 134, 0.1)\n );\n }\n}\n\n.price-wrap {\n height: 36px;\n line-height: 36px;\n padding-left: 10px;\n color: #5f7195;\n .price {\n font-size: 18px;\n font-weight: 500;\n &.green {\n color: #0fbeaf;\n }\n &.red {\n color: #ec4953;\n }\n &.white {\n color: #ffffff;\n }\n }\n}\n","import BigNumber from 'bignumber.js';\nimport { AuthBase } from '../AuthBase';\nimport {\n idlFactory as depthIDL,\n _SERVICE as DepthActor\n} from '@deland-labs/orderbook_depth_client';\nimport { CanisterError } from '../utils/exception';\nimport { parseToCommon, toBigNumber } from '../utils/helper';\nimport { MarketSetting } from './Market';\n\nexport enum DepthLevel {\n One = 1,\n Two = 2,\n Three = 3,\n Four = 4,\n Five = 5,\n Six = 6,\n Seven = 7\n}\n\nexport interface DepthItem {\n price: BigNumber;\n volume: BigNumber;\n}\n\nexport enum DepthType {\n All = 1,\n Bid = 2,\n Ask = 3\n}\n\nexport interface DepthData {\n bids: Array;\n asks: Array;\n}\n\nexport class Depth extends AuthBase {\n private baseTokenDecimals: number;\n private setting: MarketSetting;\n\n constructor(baseTokenDecimals: number, setting: MarketSetting) {\n super();\n this.baseTokenDecimals = baseTokenDecimals;\n this.setting = setting;\n }\n\n public getDepth = async (\n level: DepthLevel,\n count: number\n ): Promise => {\n const depth = await this.createDepthActor(this.setting.depthCanisterId);\n const res = await depth.get_depth(level, count);\n if ('Ok' in res) {\n return {\n bids: this.parseOriginDepth(res.Ok.bids),\n asks: this.parseOriginDepth(res.Ok.asks)\n };\n } else throw new CanisterError(res.Err);\n };\n\n /**\n * parse origin depth data to DepthItem\n * @param originData\n * @returns DepthItem[]\n */\n private parseOriginDepth = (\n originData: Array<[bigint, bigint]>\n ): Array => {\n const orders: Array = originData.map(item => {\n return {\n price: toBigNumber(item[0]).shiftedBy(-this.setting.priceDecimals),\n volume: toBigNumber(item[1]).shiftedBy(-this.baseTokenDecimals)\n };\n });\n return orders;\n };\n\n /**\n * create depth actor\n * @param depthCanisterId depth canister id\n * @param anonymous is anonymous access\n * @returns\n */\n private createDepthActor = (\n depthCanisterId: string,\n anonymous: boolean = true\n ) => {\n return this.createActor(depthCanisterId, depthIDL, anonymous);\n };\n}\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nexports.__esModule = true;\nexports.init = exports.idlFactory = void 0;\n__exportStar(require(\"./interface\"), exports);\nvar idl_1 = require(\"./idl\");\n__createBinding(exports, idl_1, \"idlFactory\");\n__createBinding(exports, idl_1, \"init\");\n","\"use strict\";\nexports.__esModule = true;\n","\"use strict\";\nexports.__esModule = true;\nexports.init = exports.idlFactory = void 0;\nvar idlFactory = function (_a) {\n var IDL = _a.IDL;\n var CanisterNames = IDL.Variant({\n 'OrderbookDepth': IDL.Null,\n 'AmountToken': IDL.Null,\n 'OrderbookKline': IDL.Null,\n 'SELF': IDL.Null,\n 'CanisterManagement': IDL.Null,\n 'BucketManager': IDL.Null,\n 'OrderbookTradeList': IDL.Null,\n 'VolumeToken': IDL.Null,\n 'EventStorage': IDL.Null,\n 'Fusion': IDL.Null,\n 'BalanceKeeper': IDL.Null\n });\n var InitArgs = IDL.Record({\n 'dev_named_canister_ids': IDL.Vec(IDL.Tuple(CanisterNames, IDL.Principal))\n });\n var StateExportData = IDL.Record({ 'state_data': IDL.Vec(IDL.Nat8) });\n var ErrorInfo = IDL.Record({ 'code': IDL.Nat32, 'message': IDL.Text });\n var StateExportResponse = IDL.Variant({\n 'Ok': StateExportData,\n 'Err': ErrorInfo\n });\n var OrderBookDepth = IDL.Record({\n 'asks': IDL.Vec(IDL.Tuple(IDL.Nat, IDL.Nat)),\n 'bids': IDL.Vec(IDL.Tuple(IDL.Nat, IDL.Nat))\n });\n var Result = IDL.Variant({ 'Ok': OrderBookDepth, 'Err': ErrorInfo });\n var BooleanActorResponse = IDL.Variant({\n 'Ok': IDL.Bool,\n 'Err': ErrorInfo\n });\n var GetVersionResponse = IDL.Variant({\n 'Ok': IDL.Nat64,\n 'Err': ErrorInfo\n });\n return IDL.Service({\n 'export_state': IDL.Func([], [StateExportResponse], []),\n 'get_depth': IDL.Func([IDL.Nat8, IDL.Nat16], [Result], ['query']),\n 'get_reverse_depth': IDL.Func([IDL.Nat8, IDL.Nat16], [Result], ['query']),\n 'get_wasm_info': IDL.Func([], [IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text))], ['query']),\n 'load_state': IDL.Func([StateExportData], [BooleanActorResponse], []),\n 'trigger_event_processing': IDL.Func([], [], ['oneway']),\n 'version': IDL.Func([], [GetVersionResponse], ['query'])\n });\n};\nexports.idlFactory = idlFactory;\nvar init = function (_a) {\n var IDL = _a.IDL;\n var CanisterNames = IDL.Variant({\n 'OrderbookDepth': IDL.Null,\n 'AmountToken': IDL.Null,\n 'OrderbookKline': IDL.Null,\n 'SELF': IDL.Null,\n 'CanisterManagement': IDL.Null,\n 'BucketManager': IDL.Null,\n 'OrderbookTradeList': IDL.Null,\n 'VolumeToken': IDL.Null,\n 'EventStorage': IDL.Null,\n 'Fusion': IDL.Null,\n 'BalanceKeeper': IDL.Null\n });\n var InitArgs = IDL.Record({\n 'dev_named_canister_ids': IDL.Vec(IDL.Tuple(CanisterNames, IDL.Principal))\n });\n return [IDL.Opt(InitArgs)];\n};\nexports.init = init;\n","import BigNumber from 'bignumber.js';\nimport { computed, IReactionDisposer, observable, reaction } from 'mobx';\nimport { DepthStore } from './Depth';\nimport { DFT, TokenInfo } from '../canister/DFT';\nimport { parseToCommon, toPrecision } from '../utils/helper';\nimport { IDisposable } from '../interface';\nimport { TradeHistoryStore } from './TradeHistory';\nimport { KLineStore } from './KLine';\nimport { Fusion, SpotOrder } from '../canister/Fusion';\nimport { Market, MarketSetting } from '../canister/Market';\nimport { TickSpaceIndex } from '../canister/KLine';\nimport { AuthBase } from '../AuthBase';\n\nexport interface TickOf24Hours {\n lastPrice: BigNumber;\n high: BigNumber;\n low: BigNumber;\n open: BigNumber;\n close: BigNumber;\n volume: BigNumber;\n change: string;\n}\n\nexport enum PriceTrend {\n Up = 'up',\n Down = 'down',\n Equal = 'equal'\n}\n\nexport interface LatestPrice {\n price: number;\n trend: PriceTrend;\n}\n\n/**\n * Orderbook market\n */\nexport class MarketStore extends AuthBase implements IDisposable {\n @observable\n marketId: string;\n\n @observable\n marketSetting: MarketSetting;\n\n @observable\n quoteToken: TokenInfo;\n\n @observable\n baseToken: TokenInfo;\n\n @observable\n tickOf24H: TickOf24Hours;\n\n @observable\n depth: DepthStore;\n\n @observable\n tradeHistory: TradeHistoryStore;\n\n @observable\n kline: KLineStore;\n\n @observable\n myOpenOrders: Array = [];\n\n private baseTokenId: string;\n private quoteTokenId: string;\n private priceDecimals: number = 32;\n private priceDecimalsShow: number = 2;\n private initialized = false;\n private marketTickTimer?: NodeJS.Timer = undefined;\n private marketTickTimeInterval: number = 1000 * 10;\n private fetchMyOpenOrderTimer?: NodeJS.Timer = undefined;\n private fetchMyOpenOrderInterval: number = 1000 * 10;\n private sessionSupervisorDisposer?: IReactionDisposer;\n private fusionActor: Fusion;\n private marketActor = new Market();\n private subNewPrice = 0;\n\n /**\n * constructor, please call initialize() before use\n * @param baseTokenId base token id\n * @param quotaTokenId quote token id\n */\n constructor(baseTokenId: string, quotaTokenId: string) {\n super();\n this.baseTokenId = baseTokenId;\n this.quoteTokenId = quotaTokenId;\n }\n\n @computed\n public get latestPrice() {\n let trend = PriceTrend.Equal;\n const latestPrice = this.tickOf24H?.lastPrice?.toNumber() || 0;\n if (this.subNewPrice > latestPrice) {\n trend = PriceTrend.Down;\n } else if (this.subNewPrice < latestPrice) {\n trend = PriceTrend.Up;\n }\n return { price: latestPrice, trend };\n }\n\n /**\n * initialize\n */\n public initialize = async () => {\n if (this.initialized) throw new Error('MarketStore has been initialized');\n this.baseToken = await new DFT(this.baseTokenId).getTokenInfo();\n this.quoteToken = await new DFT(this.quoteTokenId).getTokenInfo();\n this.marketSetting = await this.marketActor.getMarketSetting(\n this.baseTokenId,\n this.quoteTokenId\n );\n this.marketId = this.marketSetting.marketId;\n this.depth = new DepthStore(this);\n this.kline = new KLineStore(this);\n this.tradeHistory = new TradeHistoryStore(this);\n this.fusionActor = new Fusion(\n this.marketId,\n this.marketSetting.priceDecimals\n );\n if (this.marketTickTimer === undefined) {\n this.startMarketTickTimer();\n }\n console.info(`MarketStore.initialized: ${this.marketId}`);\n this.initialized = true;\n\n this.sessionSupervisorDisposer = reaction(\n () => this.initialized && this.session.isConnected,\n async connected => {\n if (connected) {\n await this.updateMyOpenOrders();\n this.startFetchMyOpenOrdersTimer();\n } else {\n this.stopFetchMyOpenOrdersTimer();\n this.myOpenOrders = [];\n }\n },\n { fireImmediately: true }\n );\n };\n\n /**\n * fetch all my open orders\n */\n public updateMyOpenOrders = async () => {\n this.checkInitialized();\n if (!this.session.isConnected) return;\n const orders = await this.fusionActor.fetchOpenOrders();\n console.info(`MarketStore.fetchOpenOrders: ${orders.length}`);\n this.myOpenOrders = orders;\n };\n\n /**\n * submit ask limit order\n * @param price price of order\n * @param volume volume of order\n * @returns\n */\n public submitAskLimitOrder = async (\n price: bigint,\n volume: bigint\n ): Promise => {\n this.checkInitialized();\n const res = await this.fusionActor.submitAskLimitOrder(price, volume);\n this.afterOrderOperation();\n return res;\n };\n\n /**\n * submit bid limit order\n * @param price price of order\n * @param volume volume of order\n * @returns\n */\n public submitBidLimitOrder = async (\n price: bigint,\n volume: bigint\n ): Promise => {\n this.checkInitialized();\n const res = await this.fusionActor.submitBidLimitOrder(price, volume);\n this.afterOrderOperation();\n return res;\n };\n\n /**\n * cancel order\n * @param orderId open order id\n * @returns {Promise}\n */\n public cancelOrder = async (orderId: bigint) => {\n this.checkInitialized();\n const res = await this.fusionActor.cancelOrder(orderId);\n this.afterOrderOperation();\n return res;\n };\n\n /**\n * cancel all orders\n * @returns {Promise}\n */\n public cancelAllOrders = async () => {\n this.checkInitialized();\n const res = await this.fusionActor.cancelAllOrders();\n this.afterOrderOperation();\n return res;\n };\n /**\n * fetch market's last 24H tick\n * @returns {Promise}\n */\n private fetchTick = async () => {\n const tick = await this.kline.fetchCurrentTick(TickSpaceIndex.OneDay);\n if (!(tick && tick.close)) {\n return;\n }\n const lastPrice = parseToCommon(\n tick.close,\n this.priceDecimals,\n this.priceDecimalsShow\n );\n console.debug(`Market.fetchLastPrice: lastPrice: ${lastPrice}`);\n const low = parseToCommon(\n tick.low,\n this.priceDecimals,\n this.priceDecimalsShow\n );\n const high = parseToCommon(\n tick.high,\n this.priceDecimals,\n this.priceDecimalsShow\n );\n const open = parseToCommon(\n tick.open,\n this.priceDecimals,\n this.priceDecimalsShow\n );\n const close = parseToCommon(\n tick.close,\n this.priceDecimals,\n this.priceDecimalsShow\n );\n const volume = parseToCommon(\n tick.volume,\n this.baseToken?.decimals,\n this.priceDecimalsShow\n );\n const change = toPrecision(\n lastPrice.minus(open).div(open).multipliedBy(100),\n 2\n ).toString();\n this.tickOf24H = { lastPrice, high, low, open, change, volume, close };\n };\n\n /**\n * order submitted/cancel hook\n */\n private afterOrderOperation = () => {\n this.stopFetchMyOpenOrdersTimer();\n this.startFetchMyOpenOrdersTimer();\n this.tradeHistory.updateUserTradeList();\n };\n\n private startMarketTickTimer = async () => {\n await this.fetchTick();\n this.fetchMyOpenOrderTimer = setInterval(() => {\n this.fetchTick();\n }, this.marketTickTimeInterval);\n };\n\n private stopMarketTickTimer = async () => {\n if (this.marketTickTimer) {\n clearInterval(this.marketTickTimer);\n this.marketTickTimer = undefined;\n }\n };\n\n private startFetchMyOpenOrdersTimer = () => {\n this.fetchMyOpenOrderTimer = setInterval(() => {\n if (!this.initialized) return;\n\n this.updateMyOpenOrders();\n }, this.fetchMyOpenOrderInterval);\n };\n\n private stopFetchMyOpenOrdersTimer = async () => {\n if (this.fetchMyOpenOrderTimer) {\n clearInterval(this.fetchMyOpenOrderTimer);\n this.fetchMyOpenOrderTimer = undefined;\n }\n };\n\n private checkInitialized = () => {\n if (!this.initialized)\n throw new Error('MarketStore has not been initialized');\n };\n\n /**\n * must be called before destroy, otherwise timer will not be cleared\n */\n dispose = (): void => {\n this.depth?.dispose();\n this.tradeHistory?.dispose();\n this.kline?.dispose();\n\n this.stopMarketTickTimer();\n this.stopFetchMyOpenOrdersTimer();\n\n if (this.sessionSupervisorDisposer) this.sessionSupervisorDisposer();\n\n this.initialized = false;\n };\n}\n","import { observable } from 'mobx';\nimport { MarketStore } from '.';\nimport { IDisposable } from '../interface';\nimport { Depth, DepthItem, DepthLevel, DepthType } from '../canister/Depth';\nimport { Fusion, SpotOrderType } from '../canister/Fusion';\nimport {\n DepthDirection,\n SwapDepth,\n SwapDepthItem\n} from '../utils/helper/converter/math';\nimport { toBigInt, toBigNumber, zero } from '../utils/helper';\nimport {\n SWAP_DEPTH_PRICE_FACTOR,\n SWAP_DEPTH_VOLUME_FACTOR\n} from '../utils/config';\nimport BigNumber from 'bignumber.js';\n\nexport class DepthStore implements IDisposable {\n @observable\n public type: DepthType = DepthType.All;\n\n @observable\n public level: DepthLevel = DepthLevel.One;\n\n @observable\n public count: number = 10;\n\n @observable\n public bidOrders: Array = [];\n\n @observable\n askOrders: Array = [];\n\n private timer?: NodeJS.Timer = undefined;\n private fetchTimeInterval: number = 1000 * 10;\n private marketStore: MarketStore;\n private depthActor: Depth;\n private fusionActor: Fusion;\n\n constructor(marketStore: MarketStore) {\n this.marketStore = marketStore;\n this.level = this.marketStore.marketSetting.defaultDepthLevel;\n this.depthActor = new Depth(\n this.marketStore.baseToken.decimals,\n this.marketStore.marketSetting\n );\n this.fusionActor = new Fusion(\n this.marketStore.marketSetting.marketId,\n this.marketStore.marketSetting.priceDecimals\n );\n this.fetchDepth();\n this.startFetchTimer();\n }\n\n /**\n * switch depth type\n * @param type\n */\n switchType = (type: DepthType) => {\n if (!type) return;\n this.type = type;\n switch (type) {\n case DepthType.Bid:\n this.count = 20;\n break;\n case DepthType.Ask:\n this.count = 20;\n break;\n case DepthType.All:\n this.count = 10;\n break;\n default:\n this.count = 10;\n break;\n }\n\n console.debug(\n `Depth.switchType: switch type to ${type.toString()} , \n depth count ${this.count}`\n );\n this.fetchDepth();\n this.restartFetchTimer();\n };\n\n /**\n * switch depth level\n * @param newLevel\n */\n switchLevel = (newLevel: DepthLevel) => {\n if (!newLevel) return;\n\n this.level = DepthLevel[newLevel.toString()];\n this.fetchDepth();\n this.restartFetchTimer();\n console.debug(`Depth.switchLevel: switch level to ${this.level} `);\n };\n\n private startFetchTimer = () => {\n this.timer = setInterval(this.fetchDepth, this.fetchTimeInterval);\n };\n\n private stopFetchTimer = () => {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n };\n\n private restartFetchTimer = () => {\n this.stopFetchTimer();\n this.startFetchTimer();\n };\n\n /**\n * fetch depth data\n */\n private fetchDepth = async () => {\n const { baseToken, quoteToken, marketSetting } = this.marketStore;\n const depthTask = this.depthActor.getDepth(this.level, this.count);\n const swapTask = this.fusionActor.fetchLiquidityInfo();\n\n const [depth, swap] = await Promise.all([depthTask, swapTask]);\n console.debug(`Depth.fetchDepth: swap liquidity ${JSON.stringify(swap)}`);\n const swapDepth = new SwapDepth({\n liquidity: toBigInt(swap.poolLP),\n volume: toBigInt(swap.poolVolume),\n amount: toBigInt(swap.poolAmount),\n decimals: {\n volume: baseToken.decimals,\n amount: quoteToken.decimals,\n price: marketSetting.priceDecimals\n },\n priceFixed: marketSetting.orderPricePrecision\n });\n\n const miniPrice = marketSetting.depthLevels[this.level - 1];\n const miniVolume = toBigNumber(1)\n .shiftedBy(-marketSetting.depthVolumePrecision)\n .times(SWAP_DEPTH_VOLUME_FACTOR);\n\n const bidOrderOption = {\n direction: DepthDirection.Bid,\n deltaP: toBigNumber(miniPrice).times(SWAP_DEPTH_PRICE_FACTOR),\n maxCount: this.count,\n minVolume: miniVolume,\n\n latestPrice: toBigNumber(this.marketStore?.latestPrice?.price || 0)\n };\n console.debug(\n `Depth.fetchDepth: bidOrderOption ${JSON.stringify(bidOrderOption)}`\n );\n const mapBidsOrders = swapDepth.getDepth(bidOrderOption).depthItems;\n console.debug(`Depth.fetchDepth: mapBidsOrders ${mapBidsOrders.length}`);\n const askOrderOption = {\n direction: DepthDirection.Ask,\n deltaP: toBigNumber(miniPrice).times(SWAP_DEPTH_PRICE_FACTOR),\n maxCount: this.count,\n minVolume: miniVolume,\n latestPrice: toBigNumber(this.marketStore?.latestPrice?.price || 0)\n };\n console.debug(\n `Depth.fetchDepth: askOrderOption ${JSON.stringify(askOrderOption)}`\n );\n const mapAsksOrders = swapDepth.getDepth(askOrderOption).depthItems;\n console.debug(`Depth.fetchDepth: mapAsksOrders ${mapAsksOrders.length}`);\n\n this.bidOrders = this.mergeOrders(\n depth.bids,\n mapBidsOrders,\n SpotOrderType.Bid\n );\n this.askOrders = this.mergeOrders(\n depth.asks,\n mapAsksOrders,\n SpotOrderType.Ask\n );\n\n console.debug(`Depth.fetchDepth: fetch depth success`);\n };\n\n private mergeOrders = (\n ordersA: Array,\n ordersB: Array,\n type: SpotOrderType\n ) => {\n const orders = ordersA.concat(ordersB);\n const map = new Map();\n orders.forEach(order => {\n const key = order.price.toString();\n if (map.has(key)) {\n const oldOrder = map.get(key);\n oldOrder.volume = oldOrder.volume.plus(order.volume);\n } else {\n map.set(key, order);\n }\n });\n const returnOrders = Array.from(map.values());\n const returnCount = Math.min(returnOrders.length, this.count);\n switch (type) {\n case SpotOrderType.Bid: {\n return returnOrders\n .sort((a, b) => b.price.comparedTo(a.price))\n .slice(0, returnCount);\n }\n case SpotOrderType.Ask:\n return returnOrders\n .sort((a, b) => a.price.comparedTo(b.price))\n .slice(0, returnCount);\n }\n };\n\n /**\n * must be called before destroy,\n * otherwise timer will not be cleared\n */\n dispose = () => this.stopFetchTimer;\n}\n","import BigNumber from 'bignumber.js';\nimport { parseToCommon, parseToOrigin, toBigNumber } from './unit';\n\nexport class Decimals {\n volume: number;\n amount: number;\n price: number;\n}\n\nexport enum DepthDirection {\n Bid = 'Bid',\n Ask = 'Ask'\n}\n\nexport class SwapDepthItem {\n public price: BigNumber;\n public volume: BigNumber;\n constructor(price: BigNumber, volume: BigNumber) {\n this.price = price;\n this.volume = volume;\n }\n}\nexport class SwapDepthCollection {\n direction: DepthDirection;\n private items: SwapDepthItem[];\n constructor(direction: DepthDirection, items: SwapDepthItem[]) {\n this.direction = direction;\n switch (direction) {\n case DepthDirection.Bid:\n this.items = items.sort((a, b) => b.price.comparedTo(a.price));\n break;\n case DepthDirection.Ask:\n this.items = items.sort((a, b) => a.price.comparedTo(b.price));\n break;\n }\n }\n public get depthItems(): SwapDepthItem[] {\n return this.items;\n }\n\n public get depthDict(): { [key: string]: SwapDepthItem } {\n const dict = {};\n this.items.forEach(item => {\n dict[item.price.toString()] = item;\n });\n return dict;\n }\n\n public toString(): string {\n let result = `direction: ${this.direction}`;\n this.items.forEach(item => {\n result += `\\nprice: ${item.price} volume: ${item.volume}`;\n });\n return result;\n }\n}\n\nexport class SwapDepth {\n k: BigNumber;\n volume: BigNumber;\n amount: BigNumber;\n decimals: Decimals;\n p0: BigNumber;\n constructor(options: {\n liquidity: bigint;\n volume: bigint;\n amount: bigint;\n decimals: Decimals;\n priceFixed: number;\n }) {\n this.k = toBigNumber(options.liquidity)\n .pow(2)\n .shiftedBy(-(options.decimals.amount + options.decimals.volume));\n this.volume = toBigNumber(options.volume).shiftedBy(\n -options.decimals.volume\n );\n this.amount = toBigNumber(options.amount).shiftedBy(\n -options.decimals.amount\n );\n const a = toBigNumber(options.amount);\n const b = toBigNumber(options.volume);\n this.p0 = new BigNumber(a.div(b).decimalPlaces(options.priceFixed));\n //console.log(this.p0)\n this.decimals = options.decimals;\n //console.log(this)\n }\n\n public getDepth(options: {\n direction: DepthDirection;\n deltaP: BigNumber;\n maxCount: number;\n minVolume?: BigNumber;\n latestPrice?: BigNumber;\n }): SwapDepthCollection {\n const { direction, deltaP, maxCount, minVolume, latestPrice } = options;\n let items = [];\n let pLast = latestPrice.gt(0) ? latestPrice : this.p0;\n console.debug(\n `pLast: ${pLast.toString()} , latestPrice ${latestPrice.toString()}`\n );\n let volumeLast = new BigNumber(1);\n let index = 0;\n while (index < maxCount && volumeLast.gt(0) && pLast.minus(deltaP).gt(0)) {\n index++;\n const getPriceNow = () => {\n if (direction === DepthDirection.Bid) {\n return pLast.minus(deltaP);\n } else {\n return pLast.plus(deltaP);\n }\n };\n const pNow = getPriceNow();\n const pMin = BigNumber.max(pNow, pLast);\n const pMax = BigNumber.min(pNow, pLast);\n pLast = pNow;\n\n const b = this.k.div(pMin).squareRoot();\n const a = this.k.div(pMax).squareRoot();\n const volumeNow = a.minus(b);\n if (volumeNow.lte(0)) {\n volumeLast = new BigNumber(0);\n } else {\n volumeLast = volumeNow;\n if (!minVolume || volumeNow.gt(minVolume)) {\n items.push(new SwapDepthItem(pNow, volumeNow));\n }\n }\n }\n return new SwapDepthCollection(direction, items);\n }\n}\n","import { IReactionDisposer, observable, reaction } from 'mobx';\nimport { MarketStore } from '.';\nimport { AuthBase } from '../AuthBase';\nimport { SpotTradeRecord, TradeHistory } from '../canister/TradeHistory';\nimport { IDisposable } from '../interface';\n\nexport class TradeHistoryStore extends AuthBase implements IDisposable {\n @observable\n tradeHistoryList: Array = [];\n private marketStore: MarketStore;\n private tradeHistoryActor: TradeHistory;\n private timer?: NodeJS.Timer = undefined;\n private fetchTimeInterval: number = 1000 * 10;\n private maxTradeHistoryCount = 100;\n private sessionSupervisorDisposer?: IReactionDisposer;\n\n constructor(marketStore: MarketStore) {\n super();\n this.marketStore = marketStore;\n const setting = marketStore.marketSetting;\n this.tradeHistoryActor = new TradeHistory(\n setting.tradeHistoryCanisterId,\n marketStore.baseToken.decimals,\n marketStore.quoteToken.decimals,\n setting.priceDecimals\n );\n this.sessionSupervisorDisposer = reaction(\n () => this.session.isConnected,\n async connected => {\n if (connected) {\n await this.updateUserTradeList();\n this.startFetchMyTradeHistoryTimer();\n } else {\n this.stopFetchMyTradeHistoryTimer();\n this.tradeHistoryList = [];\n }\n },\n { fireImmediately: true }\n );\n }\n\n public updateUserTradeList = async () => {\n this.tradeHistoryList = await this.tradeHistoryActor.fetchUserTradeList(\n 0,\n this.maxTradeHistoryCount\n );\n };\n\n private startFetchMyTradeHistoryTimer = () => {\n this.timer = setInterval(() => {\n if (!this.session.isConnected) return;\n this.updateUserTradeList();\n }, this.fetchTimeInterval);\n };\n\n private stopFetchMyTradeHistoryTimer = () => {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n };\n\n dispose = () => {\n this.stopFetchMyTradeHistoryTimer();\n if (this.sessionSupervisorDisposer) this.sessionSupervisorDisposer();\n };\n}\n","import { AuthBase } from '../AuthBase';\nimport {\n TradeRecord,\n idlFactory as tradeHistoryIDL,\n _SERVICE as TradeHistoryActor\n} from '@deland-labs/orderbook_trade_list_client';\nimport { executeWithLogging } from '../utils/errorLogger';\nimport { CanisterError } from '../utils/exception';\nimport { parseToCommon } from '../utils/helper';\nimport { SpotOrderType } from './Fusion';\n\nexport interface SpotTradeRecord {\n type: SpotOrderType;\n time: number;\n volume: number;\n price: number;\n}\n\nexport class TradeHistory extends AuthBase {\n private tradeHistoryCanisterId: string;\n private baseTokenDecimals: number;\n private quoteTokenDecimals: number;\n private priceDecimals: number;\n constructor(\n tradeHistoryCanisterId: string,\n baseTokenDecimals: number,\n quoteTokenDecimals: number,\n priceDecimals: number\n ) {\n super();\n this.tradeHistoryCanisterId = tradeHistoryCanisterId;\n this.baseTokenDecimals = baseTokenDecimals;\n this.quoteTokenDecimals = quoteTokenDecimals;\n this.priceDecimals = priceDecimals;\n }\n /**\n * fetch my trade history\n * @returns\n */\n public fetchUserTradeList = (\n offset: number,\n limit: number\n ): Promise> => {\n return executeWithLogging(async () => {\n const tradeHistoryActor = await this.createTradeHistoryActor(\n this.tradeHistoryCanisterId,\n false\n );\n const res = await tradeHistoryActor.get_user_trade_list(offset, limit);\n if ('Ok' in res) return res.Ok.map(this.parseTrade);\n else throw new CanisterError(res.Err);\n });\n };\n\n /**\n * parse origin trade to spot target trade\n * @param trade trade record\n * @returns\n */\n private parseTrade = (trade: TradeRecord): SpotTradeRecord => {\n return {\n type:\n 'Bid' in trade.order_direction ? SpotOrderType.Bid : SpotOrderType.Ask,\n time: parseToCommon(trade.time).toNumber(),\n volume: parseToCommon(trade.volume, this.baseTokenDecimals).toNumber(),\n price: parseToCommon(trade.price, this.priceDecimals).toNumber()\n };\n };\n\n /**\n * create trade history actor\n * @param tradeHistoryCanisterId trade history canister id\n * @param anonymous is anonymous access\n * @returns\n */\n private createTradeHistoryActor = (\n tradeHistoryCanisterId: string,\n anonymous: boolean = true\n ) => {\n return this.createActor(\n tradeHistoryCanisterId,\n tradeHistoryIDL,\n anonymous\n );\n };\n}\n","\"use strict\";\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nexports.__esModule = true;\nexports.init = exports.idlFactory = void 0;\n__exportStar(require(\"./interface\"), exports);\nvar idl_1 = require(\"./idl\");\n__createBinding(exports, idl_1, \"idlFactory\");\n__createBinding(exports, idl_1, \"init\");\n","\"use strict\";\nexports.__esModule = true;\n","\"use strict\";\nexports.__esModule = true;\nexports.init = exports.idlFactory = void 0;\nvar idlFactory = function (_a) {\n var IDL = _a.IDL;\n var CanisterNames = IDL.Variant({\n 'OrderbookDepth': IDL.Null,\n 'AmountToken': IDL.Null,\n 'OrderbookKline': IDL.Null,\n 'SELF': IDL.Null,\n 'CanisterManagement': IDL.Null,\n 'BucketManager': IDL.Null,\n 'OrderbookTradeList': IDL.Null,\n 'VolumeToken': IDL.Null,\n 'EventStorage': IDL.Null,\n 'Fusion': IDL.Null,\n 'BalanceKeeper': IDL.Null\n });\n var InitArgs = IDL.Record({\n 'dev_named_canister_ids': IDL.Vec(IDL.Tuple(CanisterNames, IDL.Principal))\n });\n var StateExportData = IDL.Record({ 'state_data': IDL.Vec(IDL.Nat8) });\n var ErrorInfo = IDL.Record({ 'code': IDL.Nat32, 'message': IDL.Text });\n var StateExportResponse = IDL.Variant({\n 'Ok': StateExportData,\n 'Err': ErrorInfo\n });\n var OrderDirection = IDL.Variant({ 'Ask': IDL.Null, 'Bid': IDL.Null });\n var TradeRecord = IDL.Record({\n 'order_direction': OrderDirection,\n 'time': IDL.Nat64,\n 'volume': IDL.Nat,\n 'price': IDL.Nat\n });\n var Result = IDL.Variant({\n 'Ok': IDL.Vec(TradeRecord),\n 'Err': ErrorInfo\n });\n var BooleanActorResponse = IDL.Variant({\n 'Ok': IDL.Bool,\n 'Err': ErrorInfo\n });\n var GetVersionResponse = IDL.Variant({\n 'Ok': IDL.Nat64,\n 'Err': ErrorInfo\n });\n return IDL.Service({\n 'export_state': IDL.Func([], [StateExportResponse], []),\n 'get_trade_list': IDL.Func([IDL.Nat32, IDL.Nat32], [Result], ['query']),\n 'get_user_trade_list': IDL.Func([IDL.Nat32, IDL.Nat32], [Result], ['query']),\n 'get_wasm_info': IDL.Func([], [IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text))], ['query']),\n 'load_state': IDL.Func([StateExportData], [BooleanActorResponse], []),\n 'trigger_event_processing': IDL.Func([], [], ['oneway']),\n 'version': IDL.Func([], [GetVersionResponse], ['query'])\n });\n};\nexports.idlFactory = idlFactory;\nvar init = function (_a) {\n var IDL = _a.IDL;\n var CanisterNames = IDL.Variant({\n 'OrderbookDepth': IDL.Null,\n 'AmountToken': IDL.Null,\n 'OrderbookKline': IDL.Null,\n 'SELF': IDL.Null,\n 'CanisterManagement': IDL.Null,\n 'BucketManager': IDL.Null,\n 'OrderbookTradeList': IDL.Null,\n 'VolumeToken': IDL.Null,\n 'EventStorage': IDL.Null,\n 'Fusion': IDL.Null,\n 'BalanceKeeper': IDL.Null\n });\n var InitArgs = IDL.Record({\n 'dev_named_canister_ids': IDL.Vec(IDL.Tuple(CanisterNames, IDL.Principal))\n });\n return [IDL.Opt(InitArgs)];\n};\nexports.init = init;\n","import { observable } from 'mobx';\nimport { MarketStore } from '.';\nimport { KLine, Tick, TickSpaceIndex } from '../canister/KLine';\nimport { IDisposable } from '../interface';\n\n/**\n * Market Kline\n */\nexport class KLineStore implements IDisposable {\n @observable\n ticks: Array = [];\n\n @observable\n tickSpaceIndex: TickSpaceIndex = TickSpaceIndex.FifteenMinutes;\n\n private marketStore: MarketStore;\n private klineActor: KLine;\n private timer?: NodeJS.Timer;\n private fetchTimeInterval: number = 10 * 1000;\n\n constructor(marketStore: MarketStore) {\n this.marketStore = marketStore;\n this.klineActor = new KLine(this.marketStore.marketSetting.klineCanisterId);\n this.tickSpaceIndex = TickSpaceIndex.FifteenMinutes;\n // this.fetchTicks();\n // this.startFetchTimer();\n }\n\n /**\n * switch the kline tick space\n * @param tickSpaceIndex\n */\n public switchTickSpace(tickSpaceIndex: TickSpaceIndex) {\n this.tickSpaceIndex = tickSpaceIndex;\n this.fetchTicks();\n this.restartFetchTimer();\n }\n\n private startFetchTimer() {\n this.timer = setInterval(this.updateTicks, this.fetchTimeInterval);\n }\n\n private stopFetchTimer = () => {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n };\n\n private restartFetchTimer = () => {\n this.stopFetchTimer();\n this.startFetchTimer();\n };\n\n /**\n * Update ticks, fetch new ticks if needed\n */\n private updateTicks = async () => {\n if (this.ticks.length === 0) {\n this.ticks = await this.fetchTicks();\n return;\n }\n\n const currentTick = await this.fetchCurrentTick(this.tickSpaceIndex);\n\n if (currentTick) {\n // if the lask tick is the current tick, replace it\n if (\n this.ticks[this.ticks.length - 1].tickIndex === currentTick.tickIndex\n ) {\n console.debug(`replace tick ${currentTick.tickIndex}`, currentTick);\n this.ticks[this.ticks.length - 1] = currentTick;\n }\n // if the current tick is the next tick, add it to the end\n else if (\n this.ticks[this.ticks.length - 1].tickIndex ===\n currentTick.tickIndex - 1\n ) {\n console.debug(\n 'KLine.updateTicks: current tick is the next tick ',\n currentTick\n );\n this.ticks.push(currentTick);\n }\n // maybe something wrong, reload the ticks\n else {\n console.warn(\n 'KLine.updateTicks:maybe something wrong, reload the ticks'\n );\n this.ticks = await this.fetchTicks();\n }\n }\n };\n\n /**\n * fetch ticks\n * @returns {Promise>}\n */\n private fetchTicks(): Promise> {\n const offset = 0;\n const limit = 1000;\n return this.klineActor.fetchTicks(this.tickSpaceIndex, offset, limit);\n }\n\n /**\n * get the current tick\n * @returns {Promise}\n */\n public fetchCurrentTick(\n tickSpace: TickSpaceIndex\n ): Promise {\n return this.klineActor.fetchCurrentTick(tickSpace);\n }\n /**\n * must be called before destroy\n */\n dispose = () => this.stopFetchTimer;\n}\n","import { FC } from 'react';\nimport { faStar } from '@fortawesome/free-solid-svg-icons';\n\nimport { IconButton } from '../../../component/IconButton';\nimport { IndexNumber } from '../../../component/IndexNumber';\nimport {\n formatNumber,\n priceFormatter\n} from '../../../model/utils/helper/formatter';\nimport classNames from 'classnames';\nimport BigNumber from 'bignumber.js';\nimport { zero } from '../../../model/utils/helper';\nimport * as styles from './index.module.less';\n\nexport interface AssetIndexProps {\n className?: string;\n baseTokenSymbol: string;\n baseTokenName: string;\n quoteTokenSymbol: string;\n fiatPrice: BigNumber;\n fiatCurrency: string;\n lastPrice: BigNumber;\n open: BigNumber;\n high: BigNumber;\n low: BigNumber;\n close: BigNumber;\n volume: BigNumber;\n}\n\nconst bnSafe = (bn?: BigNumber): BigNumber => {\n return !bn || bn.isNaN() ? zero : bn;\n};\nexport const AssetIndex: FC = props => {\n const {\n className,\n baseTokenSymbol = '',\n baseTokenName = '',\n quoteTokenSymbol = '',\n fiatPrice = zero,\n fiatCurrency = 'USD'\n } = props;\n const lastPrice = bnSafe(props?.lastPrice);\n const open = bnSafe(props?.open);\n const high = bnSafe(props?.high);\n const low = bnSafe(props?.low);\n const close = bnSafe(props?.close);\n const volume = bnSafe(props?.volume);\n const changed = open.eq(zero)\n ? zero\n : close.minus(open).div(open).multipliedBy(100);\n return (\n \n \n \n {baseTokenSymbol}/{quoteTokenSymbol}\n \n \n {baseTokenName} \n \n \n \n \n \n Fiat Price\n \n {priceFormatter.format(fiatPrice.toNumber())} {fiatCurrency}\n
\n \n \n Change\n \n (\n )\n
\n \n \n 24H High\n \n {priceFormatter.format(high.toNumber())}\n
\n \n \n 24H Low\n \n {priceFormatter.format(low.toNumber())}\n
\n \n \n 24H Vol\n \n {formatNumber(volume.toNumber())} {baseTokenSymbol}\n
\n \n \n );\n};\n","import { FC } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faCaretDown,\n faCaretUp,\n faMinus\n} from '@fortawesome/free-solid-svg-icons';\n\nimport { priceFormatter } from '../model/utils/helper/formatter/numberFormatter';\n\nexport interface IndexNumberProps {\n showIcon?: boolean;\n value: number | string;\n}\n\nexport const IndexNumber: FC = ({ value, showIcon }) => {\n const num = typeof value === 'number' ? value : parseFloat(value);\n\n const isGrow = num > 0,\n isSame = !num;\n\n value = num + '' === value + '' ? priceFormatter.format(num) : value;\n\n return (\n \n {showIcon && (\n \n )}\n {value}\n \n );\n};\n",".asset-index-wrap{\n height: 46px;\n display: flex;\n align-items: center;\n list-style: none;\n padding: 0;\n margin: 0;\n border-bottom: 1px solid #262d40;\n & > li{\n padding: 0 12px;\n white-space: nowrap;\n display: flex;\n flex-direction: column;\n justify-content: center;\n height: 100%;\n border-right: 1px solid #262d40;\n &:first-child{\n padding: 0 1rem 0 1.25rem;\n .btn{padding: 0 !important;margin-left: 10px;}\n }\n &:last-child{\n border:none;\n }\n }\n .symbol{\n font-size: 14px;\n }\n}\n","import classNames from 'classnames';\nimport { IReactionDisposer, observable, reaction } from 'mobx';\nimport { observer } from 'mobx-react';\nimport { PureComponent } from 'react';\nimport {\n Badge,\n Button,\n ToggleButton,\n ButtonGroup,\n InputGroup,\n Form,\n Row,\n Tab,\n Tabs,\n Spinner\n} from 'react-bootstrap';\nimport BigNumber from 'bignumber.js';\n\nimport { toastStore } from '../../../component/Toast';\nimport { RangeInput } from '../../../component/RangeInput';\nimport { ChooseWallet } from '../../../component/ChooseWallet';\nimport * as style from './index.module.less';\nimport session from '../../../model/Session';\nimport {\n formatNumber,\n getPrecision,\n parseToCommon,\n parseToOrigin,\n toBigInt,\n toBigNumber,\n toPrecision,\n zero\n} from '../../../model/utils/helper';\nimport { DFT, TokenInfo } from '../../../model/canister/DFT';\nimport { DepthItem } from '../../../model/canister/Depth';\nimport { SpotOrderType } from '../../../model/canister/Fusion';\nimport { DEFAULT_APPROVE_AMOUNT } from '../../../model/utils/config';\nimport { CanisterError } from '../../../model/utils/exception';\n\nexport interface TradeFormProps {\n className?: string;\n marketId: string;\n priceDecimals?: number;\n bidOrderDepthClickItem?: DepthItem;\n askOrderDepthClickItem?: DepthItem;\n orderVolumePrecision?: number;\n orderPricePrecision?: number;\n maxAskPriceLimit?: number;\n maxBidPriceLimit?: number;\n baseToken?: TokenInfo;\n quoteToken?: TokenInfo;\n baseTokenPrecision?: number;\n quoteTokenPrecision?: number;\n latestPrice?: number;\n onAskOrderSubmitted?: (price: bigint, volume: bigint) => Promise;\n onBidOrderSubmitted?: (price: bigint, volume: bigint) => Promise;\n}\n\ninterface ActionState {\n approvedAmount: BigNumber;\n submitting: boolean;\n input: ActionInput;\n validation: ActionValidation;\n}\n\nconst defaultActionState: ActionState = {\n approvedAmount: zero,\n submitting: false,\n input: {\n price: zero,\n pricePrecision: 0,\n amount: zero,\n amountPrecision: 0,\n percent: 0,\n total: new BigNumber(0)\n },\n validation: {\n priceValid: true,\n priceInvalidMsg: '',\n amountValid: true,\n amountInvalidMsg: ''\n }\n};\ninterface ActionInput {\n price: BigNumber;\n pricePrecision: number;\n amount: BigNumber;\n amountPrecision: number;\n percent: number;\n total: BigNumber;\n}\n\ninterface ActionValidation {\n priceValid: boolean;\n priceInvalidMsg: string;\n amountValid: boolean;\n amountInvalidMsg: string;\n}\n\n@observer\nexport class TradeForm extends PureComponent {\n @observable\n baseTokenBalance = new BigNumber(0);\n\n @observable\n quoteTokenBalance = new BigNumber(0);\n\n @observable\n bidState = defaultActionState;\n\n @observable\n askState = defaultActionState;\n\n private updateBalanceTimer?: NodeJS.Timer;\n private baseTokenActor: DFT;\n private quoteTokenActor: DFT;\n private updateBalanceInterval = 10 * 1000;\n private activeIDisposers: IReactionDisposer[] = [];\n\n /**\n * trade form input price changed\n */\n onTradeFormPriceChanged = (price: BigNumber, type: SpotOrderType) => {\n if (this.checkPricePrecision(price))\n switch (type) {\n case SpotOrderType.Bid:\n return this.onBidPriceChanged(price);\n case SpotOrderType.Ask:\n return this.onAskPriceChanged(price);\n }\n };\n\n /**\n * trade form input amount changed\n */\n onTradeFormAmountChanged = (amount: BigNumber, type: SpotOrderType) => {\n if (this.checkAmountPrecision(amount))\n switch (type) {\n case SpotOrderType.Bid:\n return this.onBidAmountChanged(amount);\n case SpotOrderType.Ask:\n return this.onAskAmountChanged(amount);\n }\n };\n\n /**\n * trade form input percent changed\n *\n * @param percent the percent value of the slider\n */\n onTradeFormSliderPercentChanged = (percent: number, type: SpotOrderType) => {\n switch (type) {\n case SpotOrderType.Bid:\n return this.onBidSliderPercentChanged(percent);\n case SpotOrderType.Ask:\n return this.onAskSliderPercentChanged(percent);\n }\n };\n\n /**\n * submit trade action\n */\n onTradeFormSubmit = (type: SpotOrderType) => {\n switch (type) {\n case SpotOrderType.Bid:\n return this.onBidOrderSubmitted();\n case SpotOrderType.Ask:\n return this.onAskOrderSubmitted();\n }\n };\n\n /**\n * Regularly update user's balance\n */\n updateTokenBalances = async () => {\n const userAddress = session?.walletAuth?.principal,\n { baseToken, quoteToken } = this.props;\n\n const baseTokenDecimals = baseToken?.decimals || 0;\n const quoteTokenDecimals = quoteToken?.decimals || 0;\n\n if (!userAddress) return;\n\n const baseRes = await this.baseTokenActor.balanceOf(userAddress);\n\n this.baseTokenBalance = parseToCommon(baseRes.balance, baseTokenDecimals);\n\n const quoteRes = await this.quoteTokenActor.balanceOf(userAddress);\n\n this.quoteTokenBalance = parseToCommon(\n quoteRes.balance,\n quoteTokenDecimals\n );\n console.info(\n `baseTokenBalance: ${this.baseTokenBalance}, quoteTokenBalance: ${this.quoteTokenBalance}`\n );\n };\n\n /**\n * Regularly update user's allowances\n */\n updateTokenAllowances = async () => {\n const userAddress = session.walletAuth?.principal;\n const { marketId, baseToken, quoteToken } = this.props;\n\n if (!userAddress || !marketId) return;\n\n const baseAllowance = await this.baseTokenActor.getTokenAllowance(\n userAddress,\n marketId\n );\n this.askState.approvedAmount = toBigNumber(baseAllowance).shiftedBy(\n -baseToken.decimals\n );\n const quoteAllowance = await this.quoteTokenActor.getTokenAllowance(\n userAddress,\n marketId\n );\n this.bidState.approvedAmount = toBigNumber(quoteAllowance).shiftedBy(\n -quoteToken.decimals\n );\n\n console.info(\n `base token allowance: ${this.bidState.approvedAmount}, quote token balance: ${this.askState.approvedAmount}`\n );\n };\n\n /**\n * call updateTokenBalances & updateTokenAllowances\n */\n startTimer = () => {\n this.updateBalanceTimer = setInterval(() => {\n this.updateTokenBalances();\n this.updateTokenAllowances();\n }, this.updateBalanceInterval);\n };\n\n /**\n * should clear the timer when component unmount\n */\n stopTimer = () => {\n if (this.updateBalanceTimer) {\n clearInterval(this.updateBalanceTimer);\n this.updateBalanceTimer = undefined;\n }\n };\n\n /**\n * stop & start\n */\n restartTimer = () => {\n this.stopTimer();\n this.startTimer();\n };\n\n /**\n * 1. restart balances fetching timer when token info changed\n * 2. update trade form price when depth order clicked\n */\n async componentDidMount() {\n const updateBalancesReactionDisposer = reaction(\n () => (this.props.baseToken, this.props.quoteToken),\n async (baseToken, quoteToken) => {\n if (!baseToken || !quoteToken) return;\n this.baseTokenActor = new DFT(this.props.baseToken.id);\n this.quoteTokenActor = new DFT(this.props.quoteToken.id);\n await this.updateTokenBalances();\n await this.updateTokenAllowances();\n this.restartTimer();\n },\n { fireImmediately: true }\n );\n this.activeIDisposers.push(updateBalancesReactionDisposer);\n\n const bidOrderDepthClickItemDisposer = reaction(\n () => this.props.bidOrderDepthClickItem,\n item => {\n if (!item) return;\n const price = Number(item.price);\n const priceBN = new BigNumber(price);\n this.bidState.input.price = priceBN;\n this.askState.input.price = priceBN;\n this.bidState.input.pricePrecision = this.props.orderPricePrecision;\n this.askState.input.pricePrecision = this.props.orderPricePrecision;\n this.onTradeFormPriceChanged(priceBN, SpotOrderType.Bid);\n this.onTradeFormPriceChanged(priceBN, SpotOrderType.Ask);\n console.info('this.bidState.input.price', Number(item.price));\n }\n );\n this.activeIDisposers.push(bidOrderDepthClickItemDisposer);\n\n const askOrderDepthClickItemDisposer = reaction(\n () => this.props.askOrderDepthClickItem,\n item => {\n if (!item) return;\n const price = Number(item.price);\n const priceBN = new BigNumber(price);\n this.bidState.input.price = priceBN;\n this.askState.input.price = priceBN;\n this.bidState.input.pricePrecision = this.props.orderPricePrecision;\n this.askState.input.pricePrecision = this.props.orderPricePrecision;\n this.onTradeFormPriceChanged(priceBN, SpotOrderType.Bid);\n this.onTradeFormPriceChanged(priceBN, SpotOrderType.Ask);\n console.info('this.sellState.input.price', Number(item.price));\n }\n );\n this.activeIDisposers.push(askOrderDepthClickItemDisposer);\n }\n\n /**\n * clear all disposers and stop timer (which can not auto-GC when component unmount)\n */\n componentWillUnmount() {\n this.stopTimer();\n\n for (const disposer of this.activeIDisposers) disposer();\n }\n\n /**\n * on bid order form price change\n */\n onBidPriceChanged = (price: BigNumber) => {\n console.debug(`onBidPriceChanged ${price}`);\n const { input } = this.bidState;\n const { orderVolumePrecision = 2 } = this.props;\n const { quoteTokenBalance = zero } = this;\n\n this.bidState.input.price = price;\n this.validateBidPrice(price);\n\n if (!input.amount || input.amount.isNaN()) return;\n\n if (price.isNaN()) {\n this.bidState.input.total = zero;\n this.bidState.input.percent = 0;\n return;\n }\n\n this.bidState.input.total = toPrecision(\n new BigNumber(input.amount).multipliedBy(price),\n orderVolumePrecision\n );\n const percent = this.bidState.input.total\n .div(quoteTokenBalance)\n .multipliedBy(100);\n this.bidState.input.percent = percent.isNaN()\n ? 0\n : Math.min(percent.toNumber(), 100);\n };\n\n /**\n * validate bid price\n *\n * @returns the price is valid or not\n */\n validateBidPrice = (price: BigNumber) => {\n const { maxBidPriceLimit = 1.5, latestPrice = 0 } = this.props;\n const bnLastPrice = new BigNumber(latestPrice);\n\n if (price.lte(0)) {\n this.bidState.validation.priceValid = false;\n this.bidState.validation.priceInvalidMsg = `Buy price cannot be 0`;\n console.debug('Buy price cannot be 0');\n return false;\n }\n\n if (\n !bnLastPrice.eq(0) &&\n maxBidPriceLimit &&\n bnLastPrice.multipliedBy(maxBidPriceLimit).lt(price)\n ) {\n this.bidState.validation.priceValid = false;\n\n const percent = new BigNumber(maxBidPriceLimit)\n .multipliedBy(100)\n .toFixed(2);\n this.bidState.validation.priceInvalidMsg = `Buy price cannot be more than ${percent}% of latest price`;\n\n console.debug(\n `Buy price cannot be more than ${percent} % of latest price( ${bnLastPrice})`\n );\n return false;\n }\n\n this.bidState.validation.priceValid = true;\n this.bidState.validation.priceInvalidMsg = '';\n return true;\n };\n\n /**\n * on ask order form price change\n */\n onAskPriceChanged = (price: BigNumber) => {\n console.debug('onAskPriceChanged', price);\n const { input } = this.askState;\n const { orderVolumePrecision = 2 } = this.props;\n\n this.askState.input.price = price;\n this.validateAskPrice(price);\n\n if (!input.amount || input.amount.isNaN()) return;\n\n if (price.isNaN()) {\n this.askState.input.total = zero;\n return;\n }\n\n this.askState.input.total = toPrecision(\n new BigNumber(input.amount).multipliedBy(price),\n orderVolumePrecision\n );\n };\n\n /**\n * validate ask price\n *\n * @returns the price is valid or not\n */\n validateAskPrice = (price: BigNumber) => {\n const { maxAskPriceLimit = 0.5, latestPrice = 0 } = this.props;\n const bnLastPrice = new BigNumber(latestPrice);\n\n if (price.lte(0)) {\n this.askState.validation.priceValid = false;\n this.askState.validation.priceInvalidMsg = `Ask price cannot be 0`;\n console.debug('Ask price cannot be 0');\n return false;\n }\n\n if (\n !bnLastPrice.eq(0) &&\n maxAskPriceLimit &&\n bnLastPrice.multipliedBy(maxAskPriceLimit).gt(price)\n ) {\n this.askState.validation.priceValid = false;\n\n const percent = new BigNumber(maxAskPriceLimit)\n .multipliedBy(100)\n .toFixed(2);\n this.askState.validation.priceInvalidMsg = `Ask price cannot be less than ${percent}% of latest price`;\n\n console.debug(\n `Ask price cannot be less than ${percent} % of latest price( ${bnLastPrice})`\n );\n return false;\n }\n\n this.askState.validation.priceValid = true;\n this.askState.validation.priceInvalidMsg = '';\n return true;\n };\n\n /**\n * The price precision cannot exceed the setting\n */\n checkPricePrecision = (price: BigNumber) => {\n const { orderPricePrecision = 2 } = this.props;\n const precision = price.dp();\n\n if (precision <= orderPricePrecision) return true;\n\n console.debug(`price precision exceed ${orderPricePrecision}`);\n return false;\n };\n\n /**\n * The amount precision cannot exceed the setting\n */\n checkAmountPrecision = (amount: BigNumber) => {\n const { orderVolumePrecision = 2 } = this.props;\n const precision = amount.dp();\n\n if (precision <= orderVolumePrecision) return true;\n\n console.debug(`amount precision exceed ${orderVolumePrecision}`);\n return false;\n };\n\n /**\n * on bid order form amount change\n */\n onBidAmountChanged = (amount: BigNumber) => {\n console.debug('onBidAmountChanged', amount);\n const { input } = this.bidState;\n const { orderVolumePrecision = 2 } = this.props;\n\n console.debug(`onBidAmountChanged ${amount.toString()}`);\n this.bidState.input.amount = amount;\n this.validateBidAmount(amount);\n\n if (!input.price || input.price.isNaN()) return;\n\n if (amount.isNaN()) {\n this.bidState.input.total = zero;\n this.bidState.input.percent = 0;\n return;\n }\n\n this.bidState.input.total = toPrecision(\n new BigNumber(input.price).multipliedBy(amount),\n orderVolumePrecision\n );\n const percent = this.bidState.input.total\n .div(this.quoteTokenBalance)\n .multipliedBy(100)\n .toNumber();\n this.bidState.input.percent = Math.min(percent, 100);\n };\n\n /**\n * validate bid amount\n */\n validateBidAmount = (amount: BigNumber) => {\n const { quoteTokenBalance = 0 } = this;\n const { orderVolumePrecision = 0 } = this.props;\n const bnPrice = new BigNumber(this.bidState.input.price);\n const quoteTokenBalanceBN = new BigNumber(quoteTokenBalance);\n\n if (amount.eq(0)) {\n this.bidState.validation.amountValid = false;\n this.bidState.validation.amountInvalidMsg = `Buy volume cannot be 0`;\n console.debug('Buy volume cannot be 0');\n return false;\n }\n\n if (bnPrice.gt(0) && quoteTokenBalance > 0) {\n const maxBidAmount = quoteTokenBalanceBN.div(bnPrice);\n\n if (amount.gt(maxBidAmount)) {\n const amountFmt = toPrecision(maxBidAmount, orderVolumePrecision);\n this.bidState.validation.amountValid = false;\n this.bidState.validation.amountInvalidMsg = `Bid amount cannot be more than ${amountFmt}`;\n console.debug(`Bid amount cannot be more than ${amountFmt}`);\n return false;\n }\n }\n this.bidState.validation.amountValid = true;\n this.bidState.validation.amountInvalidMsg = '';\n return true;\n };\n\n /**\n * on ask order form amount change\n */\n onAskAmountChanged = (amount: BigNumber) => {\n console.debug(`onAskAmountChanged ${amount}`);\n const { input } = this.askState;\n const { orderVolumePrecision = 2 } = this.props;\n\n this.askState.input.amount = amount;\n this.validateAskAmount(amount);\n\n if (amount.isNaN()) {\n this.askState.input.total = zero;\n this.askState.input.percent = 0;\n return;\n }\n if (this.baseTokenBalance.gt(0))\n this.askState.input.percent = new BigNumber(amount)\n .div(this.baseTokenBalance)\n .multipliedBy(100)\n .toNumber();\n else if (this.baseTokenBalance.eq(0) && amount.gt(0))\n this.askState.input.percent = 100;\n\n if (input.price.gt(0) && amount.gt(0))\n this.askState.input.total = toPrecision(\n new BigNumber(input.price).multipliedBy(amount),\n orderVolumePrecision\n );\n };\n\n /**\n * validate ask amount\n */\n validateAskAmount = (amount: BigNumber) => {\n const { baseTokenBalance = zero } = this;\n const { orderVolumePrecision = 0 } = this.props;\n\n if (amount.eq(0)) {\n this.askState.validation.amountValid = false;\n this.askState.validation.amountInvalidMsg = `Sell volume cannot be 0`;\n console.debug('Sell volume cannot be 0');\n return false;\n }\n\n if (baseTokenBalance.gt(0) && amount.gt(baseTokenBalance)) {\n const amountFmt = toPrecision(baseTokenBalance, orderVolumePrecision);\n this.askState.validation.amountValid = false;\n this.askState.validation.amountInvalidMsg = `Sell amount cannot be more than ${amountFmt}`;\n console.debug(`Sell amount cannot be more than ${amountFmt}`);\n return false;\n }\n\n this.askState.validation.amountValid = true;\n this.askState.validation.amountInvalidMsg = '';\n return true;\n };\n\n /**\n * on bid order form percent change\n */\n onBidSliderPercentChanged = (percent: number) => {\n const { input } = this.bidState;\n const { orderVolumePrecision = 2 } = this.props;\n\n this.bidState.input.percent = percent;\n\n if (this.quoteTokenBalance.eq(0) || !input.price) return;\n\n this.bidState.input.total = this.quoteTokenBalance\n .multipliedBy(percent)\n .div(100);\n\n this.bidState.input.amount = toPrecision(\n this.bidState.input.total.div(input.price),\n orderVolumePrecision\n );\n this.bidState.input.amountPrecision = orderVolumePrecision;\n };\n\n /**\n * on ask order form percent change\n */\n onAskSliderPercentChanged = (percent: number) => {\n const { input } = this.askState;\n const { orderVolumePrecision = 2 } = this.props;\n\n this.askState.input.percent = percent;\n this.askState.input.amount = this.baseTokenBalance\n .multipliedBy(percent)\n .div(100);\n\n if (this.baseTokenBalance.eq(0) || !input.price) return;\n\n this.askState.input.total = toPrecision(\n new BigNumber(this.askState.input.amount).multipliedBy(input.price),\n orderVolumePrecision\n );\n\n this.askState.input.amountPrecision = orderVolumePrecision;\n };\n\n /**\n * submit bid order\n */\n onBidOrderSubmitted = async () => {\n const { input } = this.bidState;\n const {\n marketId,\n baseToken,\n quoteToken,\n priceDecimals,\n onBidOrderSubmitted\n } = this.props;\n\n if (!this.validateBidPrice(input.price)) return;\n if (!this.validateBidAmount(input.amount)) return;\n\n const transferFee = DFT.calcTransferFee(input.amount, quoteToken);\n\n this.bidState.submitting = true;\n // approve first\n if (this.bidState.approvedAmount < input.amount.plus(transferFee))\n try {\n await this.quoteTokenActor.approveToken(\n marketId,\n toBigNumber(DEFAULT_APPROVE_AMOUNT),\n baseToken.decimals\n );\n console.debug('Approve quote token success');\n } catch (e) {\n console.warn('Approve quote token fail', e);\n if (e instanceof CanisterError) {\n toastStore.error(`code ${e.code}, ${e.message}`, 'Swap error');\n } else {\n toastStore.error(`Unknown error: ${e.message}`, 'Swap error');\n }\n return;\n } finally {\n this.bidState.submitting = false;\n }\n const priceBN = toBigInt(parseToOrigin(input.price, priceDecimals));\n const amountBN = toBigInt(parseToOrigin(input.amount, baseToken.decimals));\n\n if (!onBidOrderSubmitted) {\n console.debug('Bid order submit called');\n return;\n }\n\n try {\n const orderId = await onBidOrderSubmitted(priceBN, amountBN);\n\n toastStore.success(\n `price ${input.price}, volume ${input.amount}`,\n 'Submit bid order success'\n );\n console.info('Bid order success', orderId);\n } catch (e) {\n toastStore.error(`${e?.message || ''}`, 'Submit ask order fail');\n } finally {\n this.bidState.submitting = false;\n }\n };\n\n /**\n * submit ask order\n * @returns\n */\n onAskOrderSubmitted = async () => {\n const { input } = this.askState;\n\n if (\n !this.validateAskPrice(input.price) ||\n !this.validateAskAmount(input.amount)\n )\n return;\n\n const { marketId, baseToken, priceDecimals, onAskOrderSubmitted } =\n this.props;\n const transferFee = DFT.calcTransferFee(input.amount, baseToken);\n\n this.askState.submitting = true;\n // approve first\n if (this.askState.approvedAmount < input.amount.plus(transferFee))\n try {\n await this.baseTokenActor.approveToken(\n marketId,\n toBigNumber(DEFAULT_APPROVE_AMOUNT),\n baseToken.decimals\n );\n console.debug('Approve base token success');\n } catch (e) {\n console.warn('Approve base token fail', e);\n if (e instanceof CanisterError) {\n toastStore.error(`code ${e.code}, ${e.message}`, 'Swap error');\n } else {\n toastStore.error(`Unknown error: ${e.message}`, 'Swap error');\n }\n return;\n } finally {\n this.askState.submitting = false;\n }\n\n const priceBN = toBigInt(parseToOrigin(input.price, priceDecimals));\n const amountBN = toBigInt(parseToOrigin(input.amount, baseToken.decimals));\n\n if (!onAskOrderSubmitted) {\n console.debug('Ask order submit called');\n return;\n }\n console.debug(\n `Ask order submit called: price ${input.price} amount ${input.amount}`\n );\n try {\n const orderId = await onAskOrderSubmitted(priceBN, amountBN);\n\n toastStore.success(\n `price ${input.price}, volume ${input.amount}`,\n 'Submit ask order success'\n );\n console.info(`Ask order success ${orderId}`);\n } catch (e) {\n toastStore.error(`${e?.message || ''}`, 'Submit ask order fail');\n } finally {\n this.askState.submitting = false;\n }\n };\n\n renderForm(type: SpotOrderType) {\n const isBuy = type === SpotOrderType.Bid;\n const quoteTokenSymbol = this.props?.quoteToken?.symbol || '';\n const baseTokenSymbol = this.props?.baseToken?.symbol || '';\n const {\n baseTokenPrecision = 0,\n quoteTokenPrecision = 0,\n orderPricePrecision = 0,\n orderVolumePrecision = 0\n } = this.props;\n const actionState = isBuy ? this.bidState : this.askState;\n const {\n amount = zero,\n amountPrecision = 0,\n price = zero,\n pricePrecision = 0\n } = actionState.input;\n const validation = actionState.validation;\n const availableAmount = isBuy\n ? formatNumber(this.quoteTokenBalance.toNumber(), quoteTokenPrecision)\n : formatNumber(this.baseTokenBalance.toNumber(), baseTokenPrecision);\n\n return (\n \n );\n }\n\n renderTowards() {\n return (\n \n \n Withdraw\n \n \n Deposit\n \n \n );\n }\n\n render() {\n const { className } = this.props;\n\n return (\n \n
\n \n \n {this.renderForm(SpotOrderType.Bid)}\n {this.renderForm(SpotOrderType.Ask)}\n
\n \n \n \n Coming soon...\n
\n \n \n\n {/* TODO: hide it now. {this.renderTowards()} */}\n
\n );\n }\n}\n",".tabs {\n height: 37px;\n --bs-nav-link-font-size: 14px;\n --bs-nav-tabs-border-color: rgb(var(--ex3-secondary-rgb));\n :global {\n .nav-link {\n height: 36px;\n --bs-nav-link-color: rgb(var(--bs-secondary-rgb));\n --bs-link-hover-color: white;\n --bs-nav-link-hover-color: white;\n --bs-nav-tabs-link-active-color: white;\n --bs-nav-tabs-link-active-bg: rgb(var(--bs-black-rgb));\n --bs-nav-tabs-border-radius: 0;\n --bs-nav-tabs-link-hover-border-color: rgb(var(--ex3-secondary-rgb));\n --bs-nav-tabs-link-active-border-color: rgb(var(--ex3-secondary-rgb));\n border-color: rgb(var(--ex3-secondary-rgb)) !important;\n &,\n &:hover,\n &.active {\n border-bottom: none;\n border-left-color: transparent !important;\n border-top-color: transparent !important;\n outline: none;\n }\n }\n }\n & + :global.tab-content {\n flex: 1;\n .tab-pane {\n height: 100%;\n }\n }\n}\n\n.towards {\n position: absolute;\n top: 0.35rem;\n right: 0.35rem;\n}\n\n.btn{\n height: 40px;\n border-radius: 6px;\n box-shadow: none !important;\n border-style:solid;\n border-width: 1px;\n .spinner{\n margin-left: 10px;\n }\n &.connect-btn {\n background: #1a2239 !important;\n border-color: transparent !important;\n color: #0099e6;\n font-weight: 400;\n box-shadow: none !important;\n &:hover,\n &:active,\n &:focus {\n background: #212a45 !important;\n border-color: #212a45 !important;\n }\n }\n &.btn-buy{\n background: rgba(15, 190, 175, 0.1);\n border-color: rgba(15, 190, 175, 0.4);\n &:hover,\n &:active,\n &:focus{\n background: rgba(15, 190, 175, 0.3);\n }\n &:disabled{\n color: rgba(15, 190, 175, 0.4);\n }\n .spinner{\n color: rgba(15, 190, 175, 0.4) !important;\n }\n \n }\n &.btn-sell{\n background: rgba(236, 73, 83, 0.1);\n border-color: rgba(236, 73, 83, 0.4);\n &:hover,\n &:active,\n &:focus{\n background: rgba(236, 73, 83, 0.3);\n }\n &:disabled{\n color: rgba(236, 73, 83, 0.4);\n }\n }\n .spinner{\n color: rgba(236, 73, 83, 0.4) !important;\n }\n}\n\n\n.trading-form-wrap{\n padding-bottom: 20px;\n}\n.form-wrap{\n :global{\n .badge{\n background-color: #212A45 !important;\n font-weight: 400;\n }\n }\n}\n.header{\n height: 20px;\n margin: 20px 0 10px;\n}\n.footer{\n height: 20px;\n margin: 8px 0 12px;\n}\n.input-group{\n height: 36px;\n margin-bottom: 4px;\n :global{\n .form-control{\n box-shadow: none !important;\n }\n }\n}\n\n.RangeInput-wrap{\n height: 1rem;\n display: flex;\n align-items: center;\n}\n.RangeInput{\n background-color: #353E59;\n height: 2px;\n input[type=\"range\"]{\n transform: translateY(-14px);\n &::-webkit-slider-runnable-track {\n height: 2px;\n background: rgb(var(--bs-dark-rgb));\n }\n &::-webkit-slider-thumb {\n height: 12px;\n width: 12px;\n background: #5F7195;\n border-radius: 2px;\n }\n }\n}\n@-moz-document url-prefix(){\n input[type=\"range\"]{\n &::-moz-range-track{\n height: 3px;\n background: rgb(var(--bs-dark-rgb));\n }\n &::-moz-range-thumb {\n border:none;\n height: 12px;\n width: 12px;\n background: #5F7195;\n border-radius: 2px;\n transform: translateY(2px);\n }\n }\n}","import { Column, IdeaTable } from 'idea-react';\nimport {\n action,\n computed,\n IReactionDisposer,\n observable,\n reaction\n} from 'mobx';\nimport { observer } from 'mobx-react';\nimport { PureComponent } from 'react';\nimport { Tabs, Tab } from 'react-bootstrap';\nimport { SpotOrder, SpotOrderType } from '../../../model/canister/Fusion';\nimport { SpotTradeRecord } from '../../../model/canister/TradeHistory';\nimport { TableInlineButton } from './TableInlineButton';\nimport * as styles from './index.module.less';\nimport {\n formatDateTime,\n parseToCommon,\n toPrecision\n} from '../../../model/utils/helper';\nimport BigNumber from 'bignumber.js';\nimport session from '../../../model/Session';\nimport classnames from 'classnames';\nimport { toastStore } from '../../../component/Toast';\nimport { ChooseWallet } from '../../../component/ChooseWallet';\nimport { CanisterError } from '../../../model/utils/exception';\n\ninterface MyOrderDto {\n id: string;\n type: SpotOrderType;\n volume: BigNumber;\n createdAt: number;\n filled: BigNumber;\n price: number;\n}\n\ninterface TradeHistory extends SpotTradeRecord {\n id: number;\n}\n\ninterface Props {\n myOrderList?: SpotOrder[];\n tradeHistoryList?: SpotTradeRecord[];\n baseTokenSymbol: string;\n baseTokenDecimals: number;\n quoteTokenSymbol: string;\n quoteTokenDecimals: number;\n baseTokenPrecision?: number;\n quoteTokenPrecision?: number;\n orderPricePrecision?: number;\n onSwitchOnlyCurrencyMarket: (onlyCurrentMarket: boolean) => void;\n onOrderCancelled: (orderId: bigint) => Promise;\n onCancelAllClicked: () => Promise;\n}\n\n@observer\nexport class MyOrder extends PureComponent {\n @observable\n onlyCurrentMarket: boolean = false;\n @observable\n myOpenOrders: MyOrderDto[] = [];\n @observable\n tradeHistoryList: TradeHistory[] = [];\n\n private activeIDisposers: IReactionDisposer[] = [];\n\n componentDidMount() {\n const myOrderSupervisor = reaction(\n () => this.props.myOrderList,\n orders => {\n console.debug(\n `MyOrder.componentDidMount: myOrderList changed ${\n orders?.length || 0\n }`\n );\n const { baseTokenDecimals = 0 } = this.props;\n this.myOpenOrders = orders?.map(item => {\n return {\n ...item,\n volume: parseToCommon(item.volume, baseTokenDecimals),\n filled: parseToCommon(item.filled, baseTokenDecimals),\n id: item.id.toString()\n };\n });\n },\n { fireImmediately: true }\n );\n\n const tradeHistorySupervisor = reaction(\n () => this.props.tradeHistoryList,\n history => {\n console.debug(\n `MyOrder.componentDidMount: tradeHistoryList changed ${\n history?.length || 0\n }`\n );\n this.tradeHistoryList = history?.map((item, index) => {\n return { ...item, id: index };\n });\n },\n { fireImmediately: true }\n );\n this.activeIDisposers.push(myOrderSupervisor);\n this.activeIDisposers.push(tradeHistorySupervisor);\n }\n\n /**\n * clear all disposers (which can not auto-GC when component unmount)\n */\n async componentWillUnmount() {\n this.activeIDisposers.forEach(disposer => disposer());\n }\n\n /**\n * generate my open orders columns\n * @param p this.Props\n * @returns\n */\n @computed get myOpenOrdersColumns(): Column[] {\n const baseSymbol = (this.props?.baseTokenSymbol || '').toUpperCase();\n const quoteSymbol = (this.props?.quoteTokenSymbol || '').toUpperCase();\n const { baseTokenPrecision = 0, orderPricePrecision = 0 } = this.props;\n return [\n {\n key: 'createdAt',\n label: 'Time',\n render: item => {formatDateTime(item.createdAt)} \n },\n {\n key: 'pair',\n label: 'Pair',\n render: () => (\n \n {baseSymbol}/{quoteSymbol}\n \n )\n },\n {\n key: 'side',\n label: 'Side',\n render: item => (\n {item.type === SpotOrderType.Bid ? 'Buy' : 'Sell'} \n )\n },\n {\n key: 'price',\n label: `Price (${quoteSymbol})`,\n render: item => (\n {toPrecision(item.price, orderPricePrecision).toString()} \n )\n },\n {\n key: 'amount',\n label: `Amount (${baseSymbol})`,\n render: item => (\n {toPrecision(item.volume, baseTokenPrecision).toFormat()} \n )\n },\n {\n key: 'executed',\n label: 'Executed',\n render: item => (\n {toPrecision(item.filled, baseTokenPrecision).toFormat()} \n )\n },\n {\n key: 'unexecuted',\n label: 'unexecuted',\n render: item => (\n \n {toPrecision(\n new BigNumber(item.volume).minus(item.filled),\n baseTokenPrecision\n ).toFormat()}\n \n )\n },\n {\n key: 'action',\n label: 'Action',\n render: ({ id }) => (\n this.cancelOrder(BigInt(id))}\n />\n )\n }\n ];\n }\n\n @computed get tradeHistoryColumns(): Column[] {\n const baseSymbol = (this.props?.baseTokenSymbol || '').toUpperCase();\n const quoteSymbol = (this.props?.quoteTokenSymbol || '').toUpperCase();\n const {\n baseTokenPrecision = 0,\n quoteTokenPrecision = 0,\n orderPricePrecision = 0\n } = this.props;\n return [\n {\n key: 'time',\n label: 'Time',\n render: item => {formatDateTime(item.time)} \n },\n {\n key: 'pair',\n label: 'Pair',\n render: () => (\n \n {baseSymbol}/{quoteSymbol}\n \n )\n },\n {\n key: 'side',\n label: 'Side',\n render: item => (\n {item.type === SpotOrderType.Bid ? 'Buy' : 'Sell'} \n )\n },\n {\n key: 'price',\n label: `Price (${quoteSymbol})`,\n render: item => (\n {toPrecision(item.price, orderPricePrecision).toString()} \n )\n },\n {\n key: 'filled',\n label: `Filled (${baseSymbol})`,\n render: item => (\n {toPrecision(item.volume, baseTokenPrecision).toFormat()} \n )\n },\n {\n key: 'fee',\n label: 'Fee',\n render: item => (\n \n 0 {item.type === SpotOrderType.Bid ? baseSymbol : quoteSymbol}\n \n )\n },\n {\n key: 'total',\n label: `Total (${quoteSymbol})`,\n render: item => (\n \n {toPrecision(\n new BigNumber(item.price).multipliedBy(item.volume),\n quoteTokenPrecision\n ).toFormat()}\n \n )\n }\n ];\n }\n\n @action\n cancelOrder = (orderId: bigint | string): Promise => {\n return this.props\n ?.onOrderCancelled(BigInt(orderId))\n .then(() => {\n this.myOpenOrders = this.myOpenOrders.filter(\n item => item.id !== orderId.toString()\n );\n toastStore.success(\n `OrderId ${orderId} has been cancelled successfully`,\n 'Cancel order success'\n );\n console.info('Cancel order success', orderId);\n })\n .catch(e => {\n if (e instanceof CanisterError) {\n toastStore.error(`${e.message}`, 'Cancel order fail');\n } else {\n toastStore.error(`${e?.message || ''}`, 'Cancel order fail');\n }\n });\n };\n\n @action\n cancelAll = (): Promise => {\n return this.props\n .onCancelAllClicked()\n .then(() => {\n this.myOpenOrders = [];\n toastStore.success(\n `All order has been cancelled successfully`,\n 'Cancel order success'\n );\n console.info('Cancel all order success');\n })\n .catch(e => {\n if (e instanceof CanisterError) {\n toastStore.error(`${e.message}`, 'Cancel order fail');\n } else {\n toastStore.error(`${e?.message || ''}`, 'Cancel order fail');\n }\n });\n };\n\n toggleSwitch = () => {\n this.onlyCurrentMarket = !this.onlyCurrentMarket;\n };\n renderOperator() {\n const { onlyCurrentMarket } = this;\n return (\n \n
\n \n Only Current Market\n \n \n \n \n \n
\n
\n );\n }\n\n renderNoData() {\n return session.isConnected ? (\n no data
\n ) : (\n \n \n Connect Wallet \n \n
\n );\n }\n\n renderMyOpenOrders(columns: Column[], data: MyOrderDto[]) {\n return (\n \n \n
\n );\n }\n\n renderTradeHistory(columns: Column[], data: TradeHistory[]) {\n return (\n \n \n
\n );\n }\n\n render() {\n const {\n myOpenOrdersColumns = [],\n tradeHistoryColumns = [],\n myOpenOrders,\n tradeHistoryList\n } = this;\n return (\n \n {this.renderOperator()}\n \n \n {this.renderMyOpenOrders(myOpenOrdersColumns, myOpenOrders)}\n \n \n {this.renderTradeHistory(tradeHistoryColumns, tradeHistoryList)}\n \n \n
\n );\n }\n}\n","import classNames from 'classnames';\nimport { observable } from 'mobx';\nimport { observer } from 'mobx-react';\nimport { PureComponent } from 'react';\nimport { Spinner } from 'react-bootstrap';\n\nimport * as styles from './index.module.less';\n\nexport interface TableInlineButtonProps {\n id: string;\n className?: string;\n kind?: 'cancel';\n text: string;\n onClick?: () => Promise;\n}\n\n@observer\nexport class TableInlineButton extends PureComponent {\n @observable\n submitting = false;\n\n handleClick = () => {\n this.submitting = true;\n this.props.onClick().finally(() => (this.submitting = false));\n };\n\n render() {\n const { className, kind } = this.props;\n\n return (\n \n {this.props.text}\n {this.submitting && (\n \n )}\n \n );\n }\n}\n",".my-order-wrap {\n --color-primary: #0099e6;\n --color-gray: #5f7195;\n --border-color: #262d40;\n --bar-height:40px;\n}\n\n.my-order-wrap {\n margin: 0 0 2.5rem;\n position: relative;\n :global {\n .nav-tabs {\n padding-left: 1px;\n height: var(--bar-height);\n border-bottom: 1px solid var(--border-color);\n .nav-link {\n height: 100%;\n border-radius: 0;\n border-width: 0 1px 0 0;\n border-color: var(--border-color);\n border-style: solid;\n background: transparent;\n color: var(--color-gray);\n font-weight: 400;\n transition: all 0.3s;\n &:hover,\n &.active {\n background: #090d1a;\n color: var(--color-primary);\n }\n }\n }\n .tab-content {\n padding-top: var(--bar-height);\n }\n }\n .order-operator {\n padding: 0 1rem;\n display: flex;\n align-items: center;\n justify-content: space-between;\n height:var(--bar-height);\n position: absolute;\n width: 100%;\n top: var(--bar-height);\n border-bottom: 1px solid var(--border-color);\n }\n}\n\n.check-switch {\n display: flex;\n align-items: center;\n .check-switch-title {\n color: var(--color-gray);\n padding-right: 5px;\n }\n .toggle {\n cursor: pointer;\n border: none;\n background: #090d1a;\n border-radius: 1rem;\n color: #fff;\n display: block;\n position: relative;\n transition: background 120ms;\n width: 2rem;\n height: 0.875rem;\n margin: 0 1rem 0 0.5rem;\n padding: 0;\n &:before {\n content: '';\n display: block;\n text-align: right;\n }\n &.active {\n background: var(--color-primary);\n &:before {\n text-align: left;\n }\n }\n .handle {\n background: #212a45;\n border-radius: 50%;\n display: block;\n height: 1rem;\n width: 1rem;\n left: -10%;\n margin-top: -0.5rem;\n position: absolute;\n top: 50%;\n transition: all 120ms;\n }\n &.active .handle {\n left: 70%;\n background: #ffffff;\n }\n }\n}\n\n.btn-connect {\n background: none;\n border: none;\n color: var(--color-primary);\n transition: all 0.3s;\n border-bottom: 1px solid rgba(0, 153, 230, 0.5);\n padding: 0;\n &:hover {\n color: #ffffff;\n border-bottom: 1px solid #ffffff;\n }\n}\n\n.btn-cancel {\n background: #1a2239;\n border-radius: 0.5rem;\n font-weight: 400;\n color: var(--color-gray);\n border: none;\n min-width: 4rem;\n height: 1.5rem;\n padding: 0 8px;\n transition: all 0.3s;\n &:hover {\n color: var(--color-primary);\n background: #212a45;\n }\n &:disabled {\n color: var(--color-gray);\n background: #212a45;\n }\n :global {\n .spinner-border {\n width: 0.75rem;\n height: 0.75rem;\n margin-left: 5px;\n color: var(--color-primary) !important;\n }\n }\n}\n\n.order-table {\n border-bottom: none;\n th,\n td {\n text-align: left;\n border-color: var(--border-color);\n font-weight: 400;\n color: var(--color-gray);\n white-space: nowrap;\n &:last-child {\n text-align: right;\n width: 6.25rem;\n }\n }\n thead th {\n vertical-align: middle;\n }\n tbody tr {\n &:hover td {\n color: var(--color-gray);\n }\n &:last-child td {\n border: none;\n }\n }\n}\n\n@media screen and (min-width: 768px) {\n .btn-cancel:hover {\n color: #fff;\n }\n .my-order-wrap {\n .order-operator {\n width: auto;\n padding: 0;\n right: 0;\n top: 0;\n justify-content: flex-end;\n :global{\n .btn-cancel {\n border-width: 0 0 0 1px;\n border-color: var(--border-color);\n border-style: solid;\n background: transparent;\n height: 100%;\n color: var(--color-gray);\n font-weight: 400;\n transition: all 0.3s;\n border-radius: 0;\n padding: 0 1rem;\n &:hover {\n background: #090d1a;\n color: #fff;\n }\n }\n }\n }\n :global {\n .tab-content {\n padding-top: 0;\n }\n .nav-tabs .nav-link {\n width: 9.375rem;\n &:hover,\n &.active {\n color: #ffffff;\n }\n }\n }\n }\n}","import { Constructor, parseURLData } from 'web-utility';\nimport { Location } from 'history';\nimport React, { Component, PureComponent } from 'react';\nimport { useLocation, useParams } from 'react-router-dom';\n\n// Types come from https://cdn.jsdelivr.net/npm/@types/react-router/index.d.ts\n\nexport interface StaticContext {\n statusCode?: number | undefined;\n}\n\nexport interface match<\n Params extends Partial> = {}\n> {\n url: string;\n path: string;\n params: Params;\n}\n\nexport interface RouteComponentProps<\n Params extends Partial> = {},\n Context extends StaticContext = StaticContext,\n Query extends Record = {}\n> {\n location: Location;\n match: match;\n query: Query;\n staticContext?: Context;\n}\n\n/**\n * @see https://v5.reactrouter.com/web/api/withRouter\n */\nexport function withRouter(\n Class: Constructor<\n Component | PureComponent\n >\n) {\n return () => {\n const location = useLocation(),\n params = useParams();\n\n const { pathname = '/', search = '', hash = '' } = location;\n\n const path = pathname + search + hash;\n\n const match = {\n url: globalThis.location.origin + path,\n path,\n params\n },\n query = parseURLData(search);\n\n return ;\n };\n}\n"],"names":["$1Yvdb","parcelRequire","$1391fff915f6f56f$export$81482c677a163d2a","$acw62","PureComponent","async","this","bqDisposer","$57kwV","reaction","props","match","params","p","console","log","b","q","$iI5ED","TOKEN_DBTC_ID","TOKEN_DICP_ID","baseTokenId","quoteTokenId","market","$iErjh","MarketStore","info","initialize","fireImmediately","dispose","debug","render","isDesktop","$fxvql","default","depth","baseToken","quoteToken","tickOf24H","marketSetting","$ayMG0","jsxs","$biXX6","Container","as","className","$parcel$interopDefault","$8g1PZ","isLaptop","fluid","jsx","$ltbZC","MainSearch","Fragment","$l09qH","AssetIndex","baseTokenSymbol","symbol","baseTokenName","name","quoteTokenSymbol","lastPrice","high","low","volume","open","close","fiatPrice","fiatCurrency","style","height","$7dhMp","TVChartContainer","klineCanisterId","priceDecimals","baseTokenDecimals","decimals","$g3T3g","TradeForm","marketId","baseTokenPrecision","quoteTokenPrecision","maxAskPriceLimit","maxBidPriceLimit","orderPricePrecision","orderVolumePrecision","latestPrice","price","bidOrderDepthClickItem","askOrderDepthClickItem","onAskOrderSubmitted","submitAskLimitOrder","onBidOrderSubmitted","submitBidLimitOrder","$2KrWB","Depth","levels","depthLevels","count","level","type","depthVolumePrecision","askOrders","bidOrders","onChangeDepthLevel","switchLevel","onChangeDepthType","switchType","onAskOrderClick","item","onBidOrderClick","$dQE7N","MyOrder","myOrderList","myOpenOrders","tradeHistoryList","tradeHistory","quoteTokenDecimals","onSwitchOnlyCurrencyMarket","onOrderCancelled","orderId","cancelOrder","onCancelAllClicked","cancelAllOrders","observable","prototype","$eOZ0o","observer","$1391fff915f6f56f$export$2e2bcd8739ae039","$3tzs6","withRouter","$e91db2e7ecb0b15a$var$filterHead","$e91db2e7ecb0b15a$var$tableHead","$e91db2e7ecb0b15a$export$e870e12a9fd6474c","data","ascend","sortFiled","filter","undefined","marketService","$1VuYG","Market","dataWithFilter","lowerFilter","toLowerCase","d","token","DEFAULT_DATA","fav","top","change","marketList","getMarketList","setting","priceUpdateTimer","setInterval","forEach","kline","$brav4","KLine","tick","fetchCurrentTick","TickSpaceIndex","OneDay","priceChanged","minus","div","shiftedBy","dp","toNumber","componentWillUnmount","clearInterval","searchCoin","event","preventDefault","stopPropagation","onFilterChanged","onSortFiledChanged","theFiled","$ec13Y","toCamelCase","diff","sort","a","toggleFav","map","redirectMarket","window","location","hash","renderList","index","onClick","$9UoUt","IconButton","icon","$4iLuP","faStar","color","$jEyqx","FontAwesomeIcon","faSortUp","faSortDown","toFixed","width","$iktDz","Form","onSubmit","$TdvKl","IconInput","faSearch","placeholder","required","ToggleButtonGroup","onChange","head","ToggleButton","id","variant","size","value","checked","Table","borderless","hover","table","header","minWidth","faSort","computed","$d581159a9530047a$export$6084c78a3d99fd2b","$d581159a9530047a$export$e37752190853367f","$d581159a9530047a$export$9852986a3ec5f6a0","$6db3d402f8edd168$var$timeButtons","text","resolution","$6db3d402f8edd168$export$f6958aa45248cbb5","interval","componentDidMount","symbolDisposer","tvWidget","TradingView","dataFeed","unsubscribeBars","$4rNti","EX3DataFeed","widgetOptions","datafeed","container_id","library_path","locale","charts_storage_url","charts_storage_api_version","client_id","user_id","autosize","theme","toolbar_bg","customFormatters","timeFormatter","format","date","formatDate","formatLocal","dateFormatter","overrides","disabled_features","widget","onChartReady","button","createButton","attr","addClass","parent","css","on","e","srcElement","getAttribute","indexOf","target","parentNode","querySelectorAll","element","children","classList","remove","setAttribute","add","chart","setResolution","$asqJN","$8c68bd71eec0ac6e$export$22c5d51923debbed","constructor","historyProvider","$7snXe","EX3HistoryProvider","streamProvider","$892Al","EX3StreamProvider","searchSymbols","userInput","exchange","symbolType","onResult","resolveSymbol","symbolName","onResolve","onError","split_data","split","symbol_stub","description","session","timezone","ticker","minmov","pricescale","has_intraday","intraday_multipliers","supported_resolutions","supportedResolutions","volume_precision","data_status","full_name","listed_exchange","setTimeout","getBars","symbolInfo","rangeStartDate","rangeEndDate","isFirstCall","then","bars","length","noData","catch","err","subscribeBars","onTick","listenerGuid","onResetCacheNeededCallback","subscribeDepth","callback","Error","unsubscribeDepth","subscriberUID","onReady","$c95f9a86722d8e07$export$4078bfa3d9f911fe","$fb29e7f9cdf46804$export$cff61a0a6477707b","firstDataRequest","$3jtud","parseResolutionToTickSpaceIndex","historyData","fetchTicks","time","reverse","error","$a63f41910960ad0c$export$8fc2ba451c947191","OneMinute","FiveMinutes","FifteenMinutes","ThirtyMinutes","OneHour","FourHours","Week","Month","$8396a28a802c9b9c$export$97245c780040f109","onRealtimeCallback","fetchLatestTickTimer","klineActor","crtTick","newBar","Second","$70091907e8246b5a$export$ec9a71745c2761ee","from","toTs","first","limit","fsym","tsym","url","qs","aggregate","body","Response","Message","Data","$iDCui","tvClient","post","buildURLData","volumefrom","rest","history","lastBar","$840998644807d193$var$socket","$73MNt","$840998644807d193$var$_subs","$840998644807d193$var$xResolution","$840998644807d193$var$symbolInfoname","$840998644807d193$var$newSub","$840998644807d193$export$8776f53f689efee","subIndex","findIndex","uid","sub","emit","subs","channelString","splice","channel","to","$840998644807d193$var$createChannelString","listener","push","$840998644807d193$var$updateBar","includes","_lastBar","coeff","rounded","Math","floor","e1","_data","$ipYHn","ExampleHistoryProvider","to_sym","from_sym","newdata","subX","find","_lastBarX","sub_type","parseInt","trade_id","parseFloat","channelString1","$kATNo","$523eaa49d3f99bf8$var$cache","$523eaa49d3f99bf8$export$841407ceb083bd74","uri","opts","parsed","path","source","sameNamespace","io","forceNew","multiplex","$fL4YY","Manager","query","queryKey","socket","Object","assign","$lGX0c","Socket","connect","$l7wSz","$efe27346e00da8a8$export$128fa18b7194ef","loc","obj","protocol","host","charAt","test","parse","port","href","$al9N3","$gEtm1","$787375aed2c43820$export$4798917dbf149b79","$687to","Emitter","super","hostname","secure","$5vwdc","installTimerFunctions","transports","readyState","writeBuffer","prevBufferLen","agent","withCredentials","upgrade","timestampParam","rememberUpgrade","rejectUnauthorized","perMessageDeflate","threshold","transportOptions","closeOnBeforeunload","replace","$2buxl","decode","upgrades","pingInterval","pingTimeout","pingTimeoutTimer","addEventListener","transport","removeAllListeners","offlineEventListener","onClose","createTransport","EIO","$CnWUo","sid","priorWebsocketSuccess","setTimeoutFn","emitReserved","shift","setTransport","onDrain","bind","onPacket","reason","probe","failed","onTransportOpen","send","once","msg","upgrading","pause","cleanup","flush","freezeTransport","onerror","onTransportClose","onclose","onupgrade","removeListener","off","onOpen","i","l","packet","onHandshake","JSON","resetPingTimeout","sendPacket","code","filterUpgrades","maxPayload","clearTimeoutFn","autoUnref","unref","writable","packets","getWritablePackets","payloadSize","byteLength","slice","write","options","fn","compress","cleanupAndClose","waitForUpgrade","removeEventListener","filteredUpgrades","j","$7pvuz","$c1f726e793763466$export$46dec00755c1153b","websocket","WS","polling","Polling","$6opKi","$56534be56e5aa809$var$empty","$56534be56e5aa809$var$hasXHR2","$lB1J3","XHR","xdomain","responseType","$56534be56e5aa809$export$265ee5eefd4c309b","Transport","isSSL","xd","xs","forceBase64","supportsBinary","doOpen","poll","onPause","total","doPoll","onData","decodePayload","binaryType","doClose","encodePayload","doWrite","schema","timestampRequests","$e3yjg","yeast","b64","Number","encodedQuery","encode","request","$56534be56e5aa809$export$7fa6c5b6f8193917","req","method","xhrStatus","context","pollXhr","create","pick","xscheme","xhr","extraHeaders","setDisableHeaderCheck","hasOwnProperty","setRequestHeader","e2","requestTimeout","timeout","onreadystatechange","status","onLoad","document","requestsCount","requests","fromError","abort","responseText","attachEvent","$56534be56e5aa809$var$unloadHandler","terminationEvent","$3kfWP","globalThisShim","$ezyGD","$4a78f487f5bb98d8$var$TransportError","$4a78f487f5bb98d8$export$86495b081fef8e52","details","$bRHuL","$0736208648dc8bae$var$SEPARATOR","String","fromCharCode","$0736208648dc8bae$export$144d64fe58dad441","encodedPackets","Array","encodedPacket","join","$0736208648dc8bae$export$d10cc2e7f7566a2d","encodedPayload","decodedPacket","$0736208648dc8bae$export$a51d6b395ff4c65a","$fsDlh","$8a3662315a48cdbd$var$withNativeBlob","Blob","toString","call","$8a3662315a48cdbd$var$withNativeArrayBuffer","ArrayBuffer","$8a3662315a48cdbd$var$encodeBlobAsBase64","fileReader","FileReader","onload","content","result","readAsDataURL","$8a3662315a48cdbd$export$2e2bcd8739ae039","isView","buffer","PACKET_TYPES","$b417fd17fc84e4e3$export$c169aefb7330cccb","$b417fd17fc84e4e3$export$47791e8004edd485","keys","key","$b417fd17fc84e4e3$export$c718b5840781f8a7","$a9bf3da28855a34f$var$withNativeArrayBuffer","$a9bf3da28855a34f$var$decodeBase64Packet","decoded","$aVEkU","$a9bf3da28855a34f$var$mapBinary","base64","$a9bf3da28855a34f$export$2e2bcd8739ae039","substring","PACKET_TYPES_REVERSE","ERROR_PACKET","$7f4e842ae29bcbc5$var$chars","$7f4e842ae29bcbc5$var$lookup","Uint8Array","charCodeAt","$7f4e842ae29bcbc5$export$2f872c0f2117be69","i2","encoded1","encoded2","encoded3","encoded4","bufferLength","len","arraybuffer","bytes","$8ff0082eecb39b62$export$4293555f241ae35a","$8ff0082eecb39b62$var$mixin","_callbacks","apply","arguments","cb","callbacks","args","listeners","hasListeners","$4028d5a20a4526d1$export$357523c63a2253b9","reduce","acc","k","$4028d5a20a4526d1$var$NATIVE_SET_TIMEOUT","$4028d5a20a4526d1$var$NATIVE_CLEAR_TIMEOUT","clearTimeout","$4028d5a20a4526d1$export$2f67576668b97183","useNativeTimers","$4028d5a20a4526d1$export$a48f0734ac7c2329","str","c","$4028d5a20a4526d1$var$utf8Length","ceil","$26bf9c4279db2ef0$export$394f9358f6231289","self","Function","$a3bbf5b17719daf1$var$alphabet","$a3bbf5b17719daf1$var$map","$a3bbf5b17719daf1$var$prev","$a3bbf5b17719daf1$var$seed","$a3bbf5b17719daf1$var$i","$a3bbf5b17719daf1$export$c564cdbbe6da493","num","encoded","$a3bbf5b17719daf1$export$5bb64b92cb4135a","now","Date","$19744bce3c183d10$export$c564cdbbe6da493","encodeURIComponent","$19744bce3c183d10$export$2f872c0f2117be69","qry","pairs","pair","decodeURIComponent","$kxvpX","$fb8e645f3bad3d56$export$a2d42eb087c10497","XMLHttpRequest","hasCORS","concat","$ef3f42a25dd224af$var$value","$ef3f42a25dd224af$export$5235bbd4a1ef06e","$9ab7b46a38551fa4$var$isReactNative","navigator","product","$9ab7b46a38551fa4$export$911baa0677ac404c","check","protocols","headers","ws","$cFgwF","usingBrowserWebSocket","WebSocket","defaultBinaryType","addEventListeners","onopen","_socket","closeEvent","onmessage","ev","lastPacket","$9ab7b46a38551fa4$require$Buffer","nextTick","$93862213c34af1ff$export$bdd553fddd433dcb","Promise","resolve","$93862213c34af1ff$export$3909fb301d3dc8c9","MozWebSocket","$93862213c34af1ff$export$3407ba5dfb7a683d","$93862213c34af1ff$export$790dcbc41e2d75d5","$f603c1892ffe9e8b$var$re","$f603c1892ffe9e8b$var$parts","$f603c1892ffe9e8b$export$98e6a39c04603d36","src","m","exec","authority","ipv6uri","pathNames","regx","names","substr","$f603c1892ffe9e8b$var$pathNames","$0","$1","$2","$f603c1892ffe9e8b$var$queryKey","$b78f1c3cb524f77d$export$d0d38e7dec7a1a61","_a","nsps","reconnection","reconnectionAttempts","Infinity","reconnectionDelay","reconnectionDelayMax","randomizationFactor","backoff","$5pEXn","Backoff","min","max","jitter","_readyState","_parser","parser","$2BjQv","encoder","Encoder","decoder","Decoder","_autoConnect","autoConnect","v","_reconnection","_reconnectionAttempts","_reconnectionDelay","setMin","_randomizationFactor","setJitter","_reconnectionDelayMax","setMax","_timeout","maybeReconnectOnOpen","_reconnecting","attempts","reconnect","engine","skipReconnect","openSubDestroy","$vPX8d","errorSub","timer","onping","ondata","ondecoded","nsp","_destroy","active","_close","_packet","subDestroy","destroy","disconnect","reset","delay","duration","onreconnect","attempt","$fcab49da21a6222a$var$RESERVED_EVENTS","freeze","connect_error","disconnecting","newListener","$fcab49da21a6222a$export$4798917dbf149b79","connected","receiveBuffer","sendBuffer","ids","acks","flags","auth","disconnected","subEvents","onpacket","unshift","PacketType","EVENT","ack","pop","_registerAckCallback","isTransportWritable","volatile","notifyOutgoingListeners","CONNECT","onconnect","BINARY_EVENT","onevent","ACK","BINARY_ACK","onack","DISCONNECT","ondisconnect","CONNECT_ERROR","message","emitEvent","_anyListeners","sent","emitBuffered","onAny","prependAny","offAny","listenersAny","onAnyOutgoing","_anyOutgoingListeners","prependAnyOutgoing","offAnyOutgoing","listenersAnyOutgoing","$1e4e6e6cc3958162$export$a51d6b395ff4c65a","$1e4e6e6cc3958162$export$84d4095e16c6fc19","PacketType1","$1e4e6e6cc3958162$export$a50aceb0e02a00aa","replacer","$eGKCF","hasBinary","encodeAsString","encodeAsBinary","attachments","stringify","deconstruction","$8URBv","deconstructPacket","pack","buffers","$1e4e6e6cc3958162$export$f9de6ca0bc043724","reviver","decodeString","reconstructor","$1e4e6e6cc3958162$var$BinaryReconstructor","isBinary","takeBinaryData","start","buf","next","payload","tryParse","isPayloadValid","static","isArray","finishedReconstruction","reconPack","binData","reconstructPacket","$67dd224d5a131c9e$export$ac2edb9eb7af56f6","packetData","$67dd224d5a131c9e$var$_deconstructPacket","_placeholder","newData","$67dd224d5a131c9e$export$a00da3b1ec037a04","$67dd224d5a131c9e$var$_reconstructPacket","$ab192732c3780e48$var$withNativeArrayBuffer","$ab192732c3780e48$var$toString","$ab192732c3780e48$var$withNativeBlob","$ab192732c3780e48$var$withNativeFile","File","$ab192732c3780e48$export$37488ff1135b1696","$ab192732c3780e48$var$isView","$ab192732c3780e48$export$5234c529abdb5610","toJSON","$05fb321879039179$export$af631764ddc44097","$3f0f0eae169725b6$export$2d38012449449c89","ms","factor","pow","rand","random","deviation","$af87ae26bc22e0a3$export$950556173b6cbecb","radios","$3RHRn","DepthType","All","Bid","Ask","renderButtonGroup","ButtonGroup","$g4NtT","radio","idx","renderSelect","DepthLevel","Two","$fuNpx","Select","menuVariant","Option","renderTitle","Card","Title","Badge","badge","renderPrice","trend","PriceTrend","Equal","Up","green","Down","red","white","$j1eIZ","formatNumber","renderOrderList","orders","miniPrice","depthPriceDecimals","$5Kq8F","volumeSum","maxVolume","order","renderOrders","plus","sum","percent","times","$2sUhp","SpotOrderType","ListGroup","Item","backgroundSize","Header","Body","$bb4366fd148aaa09$export$81542e59773ce399","$bb4366fd148aaa09$export$d7f1bf221683375b","$bb4366fd148aaa09$export$61a6b4d3399863b6","$bb4366fd148aaa09$export$84bf76cd7afc7469","$bb4366fd148aaa09$export$a38bfcdc9e03eaa8","$bb4366fd148aaa09$export$1b4aee0b51c3def8","$bb4366fd148aaa09$export$fe0c27da941d48c6","$bb4366fd148aaa09$export$163338a71f1866be","$bb4366fd148aaa09$export$13bb94cc1bb431ac","$bb4366fd148aaa09$export$b1c2ad82f9995540","$bb4366fd148aaa09$export$4aebd143f31d0c0d","$bb4366fd148aaa09$export$5bec8eb0bdc7f0d9","$bb4366fd148aaa09$export$377817097f96120","$bb4366fd148aaa09$export$63c31deb8bd5d3d4","$bb4366fd148aaa09$export$4431f64c1e0164a8","$bb4366fd148aaa09$export$3b5f0228ff59d3b9","$bb4366fd148aaa09$export$1766dc9f9f2dd14","$bb4366fd148aaa09$export$c26b6b8d0c58f01b","$bb4366fd148aaa09$export$30b6dc633c1f7902","$bb4366fd148aaa09$export$321c0b1a406de31f","$bb4366fd148aaa09$export$955a2ebd2fb142ae","$bb4366fd148aaa09$export$a90204d1394caf30","$bb4366fd148aaa09$export$8fa4e5556fd77a60","$cdNtN","$ec10372c452549f6$export$983f3b759863328f","DepthLevel1","$ec10372c452549f6$export$ed4ee5d1e55474a5","DepthType1","$ec10372c452549f6$export$950556173b6cbecb","AuthBase","getDepth","createDepthActor","depthCanisterId","res","get_depth","bids","parseOriginDepth","Ok","asks","$eLiKN","CanisterError","Err","originData","toBigNumber","anonymous","createActor","$kiatt","idlFactory","$ec5d9d1588acab10$var$__createBinding","module","exports","__createBinding","o","k2","desc","getOwnPropertyDescriptor","__esModule","configurable","enumerable","get","defineProperty","$ec5d9d1588acab10$var$__exportStar","__exportStar","init","$h7GhG","$08b27c415293c825$export$1e511d4a378977f5","$c773e3dc4ea4d7ed$export$1e511d4a378977f5","$c773e3dc4ea4d7ed$export$2cd8252107eb640b","$c773e3dc4ea4d7ed$export$b2034e2ea8897403","IDL","CanisterNames","Variant","OrderbookDepth","Null","AmountToken","OrderbookKline","SELF","CanisterManagement","BucketManager","OrderbookTradeList","VolumeToken","EventStorage","Fusion","BalanceKeeper","StateExportData","Record","dev_named_canister_ids","Vec","Tuple","Principal","state_data","Nat8","ErrorInfo","Nat32","Text","StateExportResponse","OrderBookDepth","Nat","Result","BooleanActorResponse","Bool","GetVersionResponse","Nat64","Service","export_state","Func","Nat16","get_reverse_depth","get_wasm_info","load_state","trigger_event_processing","version","InitArgs","Opt","$4fec26593bde2dc8$export$71eca91c27092856","PriceTrend1","$4fec26593bde2dc8$export$28982c03c196c7e1","priceDecimalsShow","initialized","marketTickTimer","marketTickTimeInterval","fetchMyOpenOrderTimer","fetchMyOpenOrderInterval","marketActor","subNewPrice","quotaTokenId","$bCqTI","DFT","getTokenInfo","getMarketSetting","$9ylhw","DepthStore","$932bn","KLineStore","$4a11O","TradeHistoryStore","fusionActor","startMarketTickTimer","sessionSupervisorDisposer","isConnected","updateMyOpenOrders","startFetchMyOpenOrdersTimer","stopFetchMyOpenOrdersTimer","checkInitialized","fetchOpenOrders","afterOrderOperation","fetchTick","parseToCommon","toPrecision","multipliedBy","updateUserTradeList","stopMarketTickTimer","$3ca9619f1cac11c4$export$556c3a48a9e28265","fetchTimeInterval","marketStore","One","defaultDepthLevel","depthActor","fetchDepth","startFetchTimer","restartFetchTimer","newLevel","stopFetchTimer","depthTask","swapTask","fetchLiquidityInfo","swap","all","swapDepth","$cptKm","SwapDepth","liquidity","toBigInt","poolLP","poolVolume","amount","poolAmount","priceFixed","miniVolume","SWAP_DEPTH_VOLUME_FACTOR","bidOrderOption","direction","DepthDirection","deltaP","SWAP_DEPTH_PRICE_FACTOR","maxCount","minVolume","mapBidsOrders","depthItems","askOrderOption","mapAsksOrders","mergeOrders","ordersA","ordersB","Map","has","oldOrder","set","returnOrders","values","returnCount","comparedTo","$02cb38a44abae19d$export$8fef7050222c4109","DepthDirection1","$02cb38a44abae19d$export$8177e720482360ef","$02cb38a44abae19d$export$53901946b714f472","items","depthDict","dict","$02cb38a44abae19d$export$a66ecf07d0248ad1","$cj2h1","p0","decimalPlaces","pLast","gt","volumeLast","pNow","getPriceNow","pMin","pMax","squareRoot","volumeNow","lte","$21de1e09dfebd3af$export$1a9b8d76f4797280","maxTradeHistoryCount","tradeHistoryActor","$kjDQT","TradeHistory","tradeHistoryCanisterId","startFetchMyTradeHistoryTimer","stopFetchMyTradeHistoryTimer","fetchUserTradeList","$33e8a12c933a991b$export$dc397b0da942bb54","offset","$9YgT4","executeWithLogging","createTradeHistoryActor","get_user_trade_list","parseTrade","trade","order_direction","$ewW0L","$a9410daeddad89bb$var$__createBinding","$a9410daeddad89bb$var$__exportStar","$bKeP4","$91998ef657b038c8$export$1e511d4a378977f5","$88cf7d107048cc1b$export$1e511d4a378977f5","$88cf7d107048cc1b$export$2cd8252107eb640b","$88cf7d107048cc1b$export$b2034e2ea8897403","OrderDirection","TradeRecord","get_trade_list","$ddacabf4795646c4$export$fd70ae1e4f47c167","ticks","tickSpaceIndex","switchTickSpace","updateTicks","currentTick","tickIndex","warn","tickSpace","$e909be2c453ba951$var$bnSafe","bn","isNaN","zero","$e909be2c453ba951$export$32ec6abefa73480","changed","eq","$a66rf","btn","$fBpmM","IndexNumber","$g7sdx","priceFormatter","showIcon","$35b8fb94baf4d345$export$c83e6f467738e834","isGrow","isSame","$6oZza","faCaretUp","faMinus","faCaretDown","$759f757e68f48dd9$export$534219b709288da9","$759f757e68f48dd9$export$8f701197936bc2a6","$759f757e68f48dd9$export$9394863499631edf","$2fff68771c858513$var$defaultActionState","approvedAmount","submitting","input","pricePrecision","amountPrecision","validation","priceValid","priceInvalidMsg","amountValid","amountInvalidMsg","$2fff68771c858513$export$a63ebd99d34087f2","baseTokenBalance","quoteTokenBalance","bidState","askState","updateBalanceInterval","activeIDisposers","onTradeFormPriceChanged","checkPricePrecision","onBidPriceChanged","onAskPriceChanged","onTradeFormAmountChanged","checkAmountPrecision","onBidAmountChanged","onAskAmountChanged","onTradeFormSliderPercentChanged","onBidSliderPercentChanged","onAskSliderPercentChanged","onTradeFormSubmit","updateTokenBalances","userAddress","walletAuth","principal","baseRes","baseTokenActor","balanceOf","balance","quoteRes","quoteTokenActor","updateTokenAllowances","baseAllowance","getTokenAllowance","quoteAllowance","startTimer","updateBalanceTimer","stopTimer","restartTimer","updateBalancesReactionDisposer","bidOrderDepthClickItemDisposer","priceBN","askOrderDepthClickItemDisposer","disposer","validateBidPrice","bnLastPrice","lt","validateAskPrice","validateBidAmount","bnPrice","quoteTokenBalanceBN","maxBidAmount","amountFmt","validateAskAmount","transferFee","calcTransferFee","approveToken","DEFAULT_APPROVE_AMOUNT","$cOVdM","toastStore","parseToOrigin","amountBN","success","renderForm","isBuy","actionState","availableAmount","noValidate","$6nY0Q","bg","InputGroup","Control","getPrecision","isInvalid","Feedback","tooltip","$2xH21","RangeInput","colors","footer","$cBLmd","ChooseWallet","Button","disabled","Spinner","animation","spinner","renderTowards","towards","Tabs","tabs","Tab","eventKey","title","Row","$4a63714d05b69c52$export$39f5674517ec0000","$4a63714d05b69c52$export$dff840edf10f285e","$4a63714d05b69c52$export$534219b709288da9","$4a63714d05b69c52$export$641374ffb95bc399","$4a63714d05b69c52$export$7ef555c6aef20aec","$4a63714d05b69c52$export$c659e452bab99a57","$4a63714d05b69c52$export$bd4c6d3f752e8ef6","$4a63714d05b69c52$export$37957852aec08359","$4a63714d05b69c52$export$f85df913b3b63720","$4a63714d05b69c52$export$38e42c68cf43b5d4","$4a63714d05b69c52$export$adb608be33961c98","$4a63714d05b69c52$export$58006689be929417","$4a63714d05b69c52$export$a671e0480694f021","$4a63714d05b69c52$export$f5603a09670563b9","$ed02f7179293c681$export$f683d71531d28a01","onlyCurrentMarket","BigInt","cancelAll","myOrderSupervisor","filled","tradeHistorySupervisor","myOpenOrdersColumns","baseSymbol","toUpperCase","quoteSymbol","label","formatDateTime","createdAt","toFormat","$d0acp","TableInlineButton","kind","tradeHistoryColumns","toggleSwitch","renderOperator","$gcV9H","toggle","handle","renderNoData","renderMyOpenOrders","columns","IdeaTable","list","noneNode","renderTradeHistory","defaultActiveKey","action","$45bed6a52e64d7fe$export$5029fa4b808c2d8d","handleClick","finally","$bcca1a3417a37e95$export$6b49c933d8810e84","$bcca1a3417a37e95$export$7b2f6446b96abfef","$bcca1a3417a37e95$export$aeddb16902a8a28c","$bcca1a3417a37e95$export$f6e39d2fbf0452d3","$bcca1a3417a37e95$export$e03c1c3201ee8bb7","$bcca1a3417a37e95$export$89da14300d534261","$bcca1a3417a37e95$export$8f34ce051745d39e","$bcca1a3417a37e95$export$ba310d98d04c7900","$bcca1a3417a37e95$export$8bc5ee67b66bb4d3","$bcca1a3417a37e95$export$228f2bb1ec207cd5","$287f94a0f75add88$export$369b6b2b30582e8e","Class","$14Ta7","useLocation","useParams","pathname","search","globalThis","origin","parseURLData"],"version":3,"file":"Trading.8640e855.js.map"}