quiclog / qvis Goto Github PK
View Code? Open in Web Editor NEWQUIC and HTTP/3 visualization tools
Home Page: https://qvis.edm.uhasselt.be
License: MIT License
QUIC and HTTP/3 visualization tools
Home Page: https://qvis.edm.uhasselt.be
License: MIT License
I use https://qvis.edm.uhasselt.be/#/files to visualize qlogs. At times the qlogs are more than 100MB and it seems pretty slow to navigate through. Is there a way to have qvis tool installed on the machine. I also notice that QUICvis is deprecated. Any suggestions please?
Describe the bug
Even a decrypted file was loaded, the Error "ParserPCAP: no tls info known for the first QUIC initial, not supported! Are you sure the trace decrypted?" occurred.
To Reproduce
-pcapng file was converted using your guide under https://github.com/quiclog/pcap2qlog#options
-next the qlog-file was loaded via https://qvis.quictools.info/#/files / Option 2
-used for tracing was Wireshark 3.6.5-1 under Linux Ubuntu
-web-server is nginx
-client is Firefox 103.0a1 (nightly)
Expected behavior
expected was to see the visualization of the packet-flow of my trace
Screenshots
see attachments
Additional context
If you are having problems loading a file, please attach it to this issue or email it to us at [email protected]
Note that qvis is currently only tested and maintained for the latest stable versions of Google Chrome.
evidence_files.zip
see quicwg/qlog#40
packet_type is now in PacketHeader
packet_size is now renamed and no longer in PacketHeader, but in raw.length
on the individual events.
first pass probably: swap them to draft-01 places if they are already reversed (draft-02)
second pass: properly update the tools to look at the new places and then swap everything pre-draft02 to draft02
Hi, my problem is that GQUIC is supported?
It is still use gquic popularily, expecially q046 which is used mostly in latest chrome browser.
I'm debugging a potential RTT measurement problem, and these 2 features would be very helpful:
Good suggestion from Wouter Vanmontfort to also show byte-offsets in the multiplexed view as well to make it clear which parts are being sent first (this info is also visible per-stream on the bottom, but in a slightly different way, and I think this change makes a lot of sense):
Maybe @LPardue has some opinions on this as well?
At this moment. json means a pcap2json output from tshark. For qlog, it needs to have the .qlog extension, for netlog, it has to be .netlog.
Ideally, we'd just ingest a .json and heuristically try to determine what it is (before sending it to the right json parser even)
This kind of thing will be needed either way once we start with qlog's streaming format, so make it a more general approach overall.
Hi,
Is your feature request related to a problem? Please describe.
When I load a qlog which stream ids are all odd, I can't use the multiplexing feature. And I found out that the cause of this problem is that StreamGraphDataHelper.isDataStream() is called under MultiplexingGraphD3WaterfallRenderer.ts, ignoring stream ids that are not divisible by 4. But sometimes we need to analyze some stream from server, these streams are often odd ids.
Describe the solution you'd like and alternatives you've considered
Maybe we intercept these stream ids in another way, such as analyzing vantage_point, or displaying odd and even ids at the same time.
Describe the bug
Trying to load multiple files by URL results in an error.
Format 1 (?file=x.qlog
) works like a charm, but when using format 4 (?file1=x.qlog&file2=y.qlog&file3=z.qlog
) an error is thrown. The error also occurs when only trying to load a single file.
The error seems to be a bug.
Meanwhile, the inability to load multiple files seems to be a lacking feature. I quickly skimmed though the code, and it seems like only one file is attempted to be fetched, the others are ignored.
To Reproduce
?file1=http://localhost:5000/qlog/f49d5b63efe7abca.qlog
ERROR loading URL
Expected behaviour
When only supplying file1
: same behaviour as format 1, correctly loading the file.
When supplying multiple files (file1
, file2
, ...): correctly loading all supplied files.
Error message
ConnectionStore.ts:302 ConnectionStore:LoadFilesFromServer : ERROR : trace not added to qvis! : {
file1: "http://localhost:5000/qlog/f49d5b63efe7abca.qlog"
}
Response: {
url: "http://localhost:5000/qlog/f49d5b63efe7abca.qlog%20etc."
}
Note that the response has %20etc.
appended to the URL, which is absent in file1
.
Possible fix
The error can be fixed using the following patch, which works for a local build:
diff --git a/visualizations/src/store/ConnectionStore.ts b/visualizations/src/store/ConnectionStore.ts
index fbce71b..9d3606a 100644
--- a/visualizations/src/store/ConnectionStore.ts
+++ b/visualizations/src/store/ConnectionStore.ts
@@ -136,7 +136,7 @@ export default class ConnectionStore extends VuexModule {
urlToLoad = queryParameters.list;
}
else if ( queryParameters.file1 ){
- urlToLoad = queryParameters.file1 + " etc.";
+ urlToLoad = queryParameters.file1;
}
if ( urlToLoad === "" ){
The attached qlog files seem to display correctly, but not all of the events for sending are matched to receive events.
For instance, event 110 at the client is at packet_sent for "1RTT" packet "5". Event 116 at the server is reported as packet_received for "1rtt" packet 5. I originally thought this to be a bug in the log converter for picoquic, which produces lowercase names for 0RTT and 1RTT packets, but after fixing that the problem remains. The input record is:
[2446805, "transport", "packet_received", { "packet_type": "1RTT", "header": { "packet_size": 29, "packet_number": 5, "dcid": "46d3e6a2be3761fd", "quic_bit": 0 }, "frames": [{
"frame_type": "ping"}]}],
However, the UI consistently shows the down-cased version, and adds a "type" field:
Event nr: 116
[
2446805,
"transport",
"packet_received",
{
"packet_type": "1rtt",
"header": {
"packet_size": 29,
"packet_number": 5,
"dcid": "46d3e6a2be3761fd",
"quic_bit": 0
},
"frames": [
{
"frame_type": "ping"
}
],
"type": "1rtt"
}
]
The only other potential problem here is that picoquic uses numbers for packet numbers rather than decimal strings. Maybe a little tolerance is in order.
Note that you need to set the offset to about -1597611236589 as the two use a different epoch (is there a fixed epoch in the spec?) and #28 causes the default to be incorrect.
Add an option for users to indicate a specific packet number or timestamp they would like to visualize in the sequence diagram.
This should have a bit of a clamping/approximation factor so it shows the nearest value if the exact input isn't found.
Somewhat related to #36, UX should probably be considered at the same time.
(note: packet numbers should probably be only 1-RTT numbers)
Thanks to @marten-seemann for suggesting.
For those who want to run the tool locally instead of relying on a remote web server an ocean away.
If you first open a trace in one of the visualizations, then remove it using the FileManager overview, then go back to the visualization, the removed trace is still loaded.
For some reason, the data binding doesn't auto-update/re-render here, even though the dropdown no longer shows the removed trace.
I have no idea why this happens and don't think this will be a big problem for most users, so decided to open an issue for now instead of solving immediately (I expect this to be a deep rabbit hole).
Note: tied to other quality-of-life issues such as visualizations not auto-switching to last loaded trace when coming from filemanager.
Is your feature request related to a problem? Please describe.
I've loaded a qlog by url. I want to send a link to the qlog, but once it's loaded there's no place I can see to cut and paste the original loaded URL. (Yes, maybe it's still in my paste buffer, or I could go back to wherever I got it from, but....Qvis shows "loaded via URL" in many places, which is SO CLOSE, but these are all abbreviated e.g. "https://blah.net/qlog/...3636298364.qlog" not the actual correct URL
Describe the solution you'd like
Either show the entire URL so I can cut and paste, or make it a link with the full original URL.
Describe alternatives you've considered
It would also be nice if there was a way to send a colleague a qvis link that included the qlog URL to load. Even better still would be if packets in the sequence were anchors so the URL could reference a specific packet in a sequence for my colleague to look at.
Stream limits are indicated in number of streams of a given type, not the actual stream IDs those correspond to.
It would be useful if qvis could also show those stream IDs to make debugging easier.
Basic setup:
It would be useful if qvis, when loading a qlog file, would recommend additional fields or other qlog features for the generating application to implement, in order to improve the visualization or better support qvis features.
At this time, the backend does not use the Oboe JSON parser as a backup when parsing fails (e.g., a malformed qlog), while the frontend does.
This isn't typically a problem atm, as most qlog files are loaded individually, and the server simply sends them back as text for the browser to interpret. However, when loading multiple files at the same time, the JSON is parsed at the server to be combined into a single, aggregated qlog, which is where things fail.
Another question to ask though is whether we should aggregate qlogs on the server instead of just in the browser. Why not just fetch the files individually and then combine them on the browser end when they're all done? This makes the pipeline a bit less consistent, but at least keeps the somewhat complex fallback logic in one place...
Is your feature request related to a problem? Please describe.
Installing node.js based projects can sometime fail, and some are not very fluent with debugging the node.js toolchain.
Describe the solution you'd like
A Docker image that can run qvis, while still beeing able to consult server side logs for debugging traces maybe?
This could be built and pushed by Github actions for instance.
Describe alternatives you've considered
I am not sure there is a more convenient way to pack it than Docker.
Describe the bug
Error: could not process packet type: ENCRYPTION_ZERO_RTT
Error uploading the netlog file
To Reproduce
Screenshots
FileManagerContainer:uploadFile : Error: could not process packet type: ENCRYPTION_ZERO_RTT
at netlogtoqlog.ts:434
at Function.convert (netlogtoqlog.ts:425)
at FileReader.n.onload (FileManagerContainer.vue?15b5:281)
n.onload @ FileManagerContainer.vue?15b5:297
load (async)
uploadFile @ FileManagerContainer.vue?15b5:265
Additional context
If you are having problems loading a file, please attach it to this issue or email it to us at [email protected]
Note that qvis is currently only tested and maintained for the latest stable versions of Google Chrome.
Hi,
thanks for your work. This tool is so useful.
I am using it in my master thesis and I wish there was one more feature - ability to download sequence diagram as svg image.
This would allow you to attach such diagrams in papers or thesis as well as modifiy them e.g skip some events, add subtitles, etc.
One thing I was trying to do was to inspect diagram and save HTML svg element but it didn't work for me :/
I can try to make a PR but I would probably need some help
Describe the bug
The live site seems to be down, getting a 500 Proxy Error.
To Reproduce
Go to https://qvis.quictools.info/ it will show the following error page:
Expected behavior
The website should open
Screenshots
Additional context
I am using Google Chrome Beta 104.0.5112.29 on windows 11
One of the advantages of qlog/JSON is that it's human-readable while still being computer-processable.
However, qvis currently doesn't really expose that power dynamic well. Many people have turned to jq
for manually processing qlogs with custom queries, but that can be cumbersome in practice, and doesn't integrate with visualizations.
@mpiraux did a few simple tools that allow you to select individual fields for plotting in e.g., linecharts to kind of get the best of both worlds.
Others have suggested a full CLI interface that e.g., wraps jq
(or https://github.com/kantord/emuto) with some high-level, qlog specific queries would be interesting.
Ideally, we would have something akin to SQL for querying qlogs, and provide both a CLI-tool for this (that outputs partial qlog for example) and an integration into qvis for (basic) visualization/exploration.
This could then also help with filtering in the sequence diagram for example, see #36
Right now, if you load a long trace (say 100MB+) and you're for example only interested in changes in flow control, it can be challenging to impossible to find them.
A minimal version of this feature would allow filtering on 1 or more event + frame types. A more complex version would allow a more advanced grammar to for example select fields with a particular value within an event and complex combinations ( (event type x OR y) AND (time > 5000) etc.)
It would also be nice to (optionally) show the events right before and after the filtered events to get some context.
Technically implementing the filtering itself won't be difficult (we already filter on time-ranges atm to reduce rendering overhead for example). It's mainly making a user-friendly interface for something advanced that would be the problem here.
This is something the browser can do without issue. However, when downloading qlog from an external endpoint, we currently go through qvis-server to prevent CORS issues... and the qvis-server introspects the qlog etc. and not sure how the nodejs request library handles gzip/brotli.
Plan:
I use the congestion tab quite often for investigating QoS issues. It works great for Reno/CUBIC, but it's less useful after implementing BBR. The congestion window still exists, but BBR primarily limits the send rate via a pacer.
It would be nice if we could visualize the optional pacing_rate
in recovery:metrics_updated
. This is measured in bits/sec so it wouldn't fit with the other graphs. It would also be nice to add a new field called bandwidth_estimate
to that event, graphing it alongside the pacing_rate
.
It seems like the packetization diagram changes some internal state after drawing for the first time, mainly related to how we do the auto-generated FILLER frames.
To reproduce: load example files, go to packetization tab, load the "10 parallel files". In the middle in the bottom part for packet nr 4, you'll see that the QUIC frame header is almost entirely red with a little yellow. Now click any other tab, and come back to the packetization. Suddenly, packet nr 4 has a much larger yellow area up front. This also happens with some other traces such as SPIN_BIT.
I think this might be happening due to a double loop where we calculate things the second time around based on the output of the first due to an error (since we store the results of the first time in the qlog data directly).
Leaving this open for now since it doesn't really introduce any errors atm (frame sizes are guesstimated anyway) and we have to revise this code anyway when adding proper support for frame.raw.length and frame.raw.payload_length soon.
Previously, events packet_dropped
and packet_lost
and packet_buffered
had separate packet_number
and packet_type
fields. For draft02, these have been replaced to always using a header:PacketHeader field, so we need to update tools that look for those fields (mainly congestion graph).
Related to #8 and quicwg/qlog#40
it would be nice to be able to visualize how implementations make scheduling decisions between DATAGRAM and STREAM frames. This could be as simple as showing the sent DATAGRAM frame as a unique colour in amongst the STREAM frames.
Is your feature request related to a problem? Please describe.
I don't believe the issue I've encountered is a problem, but unsure. I had captured a 'chrome-net-export-log.json' from my work computer intended to upload it to 'https://qlog.edm.uhasselt.be/sigcomm/' for QUIC and Qlog analysis due diligence. However I could not read the qlog url from my work computer, so I uploaded it to my home computer. The attempted again to load it to the qlog tool site. The tool indicates it was uploaded but when I browse through the menu, the form is there but no data. When I upload a qlog capture on my home computer, it works fine.
QUESTION: Is it possible to load qlogs captured on one computer and then analyze on a different computer?
Describe the solution you'd like
Analyze Qlogs captured on one computer on a different computer.
Describe alternatives you've considered
Submitting a boundary change request, but that is like to be problematic.
Additional context
I'm not a web developer or programmer, so I may not be aware of the full scope of options. Thanks in advance
Qvis is not able to upload qlog files for visualization.
I uploaded the file using option: 2. I clicked on browse button to upload the file as well as tried to drag and drop using qlog but there is no visualization of the qlog and when I switch the menus to see the trace it still says "Please load a trace file to visualize it".
When I download the source code and try to run it locally on my machine the behavior is the same.
I have used qvis before and it was working fine.
Can You please help in this.
When loading 2 qlogs (using file1=..&file2=...) they are automatically combined by pcap2qlog into a single file. However, when that file is then loaded into qvis, it doesn't automatically select client and server vantage points correctly. Instead, it selects the client and then auto-generates a server viewpoint from that, even though the server viewpoint is right there in the trace.
Probably a bug in how we search for the server viewpoint in the same ConnectionGroup in qvis.
See also #16.
Currently if you only upload 1 trace, we auto-generate its opposite in the sequence diagram (e.g., you upload client, qvis generates server)
This is done by doing a full copy of the original trace and then manually swapping packet_sent
for packet_received
and vice versa.
This is however quite wasteful, especially for large traces, and swapping sent/received is a bit confusing for several users if they click on the squares to watch event details. Additionally, we default to showing the client-side event in the detail popup, causing the generated qlog to show up if you upload a server-side trace instead of the server-side qlog, which is even more confusing.
I did this approach initially to make it easier to re-use code across single-trace and multi-trace setups. However, adding a bit of special code for single-trace scenarios should work too.
I do have a faint recollection that this was tried initially but was too difficult for some reason, so best to do some proper analysis before starting this...
Describe the bug
Rendering a sequence diagram of the QLOG below causes an TypeError exception.
Note that the ACK-frame doesn't carry any additional information.
Example qlog:
{
"qlog_version": "draft-00",
"title": "Name of this particular qlog file (short)",
"description": "Description for this group of traces (long)",
"summary": {
},
"traces": [
{
"vantage_point": {
"name": "backend-67",
"type": "SERVER"
},
"title": "Name of this particular trace (short)",
"description": "Description for this trace (long)",
"event_fields": [
"relative_time",
"CATEGORY",
"EVENT_TYPE",
"DATA"
],
"common_fields": {
"protocol_type": "QUIC_HTTP3"
},
"events": [
[0, "TRANSPORT", "PACKET_SENT", { "packet_type": "initial", "header": { "packet_number": 0 }, "frames": [{ "frame_type": "crypto_hs"}, { "frame_type": "padding"}]}],
[5997, "TRANSPORT", "PACKET_RECEIVED", { "packet_type": "initial", "header": { "packet_number": 0 }, "frames": [{ "frame_type": "ack"}, { "frame_type": "crypto_hs"}]}]
]
}
]
}
Especially when just a single trace is loaded, this would make sense.
Should probably have a "deus ex machina" kind of setup (arrow starting halfway with dots) when loading both client and server side traces where the server doesn't contain these events
Describe the bug
"Manage files" tab -> Option 1 Load a file by URL
Enter a http URL, e.g. http://kwikqlogs.westeurope.azurecontainer.io/qlog/34d646b63de7f45e.qlog
Loading does not finish successfully.
In browser dev tools, i saw that loading failed, due to the fact that the page is loaded from a https URL and does not allow to load content from http URL
To Reproduce
Enter the given URL and hit "Fetch" ;-)
qvis often fixes/changes qlogs (e.g., remove duplicates, order timestamps, etc.).
It would be nice to allow people to download the "fixed" qlog afterwards.
Similarly, downloading qlogs with the tool parameters embedded is also needed if we want people to share the same viewpoints on files.
Maybe show a list of "currently loaded files" in the filemanager with a download button next to them?
cc @LPardue
Currently, we just print ACKed packet numbers and ranges in full in the sequence diagram.
However, in cases with many ACK gaps and/or large packet numbers, this can lead to a very cluttered result:
We could consider shortening the numbers by longest prefix to alleviate this a bit.
For example: range 12345 - 12359 could become 12345 - .59
This is complicated a bit if we want to do this across ack ranges/PNs (so 12345 - 12359, 12330 - 12340 would become 12345 - .59, .30 - .40), since we currently print highest first (in accordance with how the ACK frame is laid out), but certainly doable.
quant already does this type of thing (https://github.com/NTAP/quant/blob/main/lib/src/frame.c#L502-L512), but maybe we need to move to a string-based approach instead (longest-prefix finder with regex?) as we conceptually want to support 64-bit numbers encoded as strings.
Describe the bug
Uploading a file with the same file name as the previous file loaded (but different contents) does not load the new contents.
Describe the bug
It seems that QVIS does not properly handle two connections in the same trace.
A second connection seems to be mapped to the first connection and, e.g., initial frames are interpreted as retransmission (see attached screenshot). It also lacks all answers from the second connection.
To Reproduce
Expected behavior
Not mixing up two connections into one sequence. I suggest having a connection drop down menu that allows selecting a connection from a trace.
Describe the bug
It appears as though some implementations use a different epoch than 1970-01-01. This manifests in a very large skew in reported times in logs. There is code to make an adjustment, but where the adjustment needs to be negative, a positive value is used instead, which doubles the skew instead.
(To be clear, this is likely just neqo, which sets an epoch at the time the program starts, due to its choice to rely on Rust's monotonic clock rather than its absolute one.)
To Reproduce
View any of the interop test qlogs from https://interop.seemann.io where neqo is the client.
Expected behavior
A negative value for the large skew.
Other
I note that you can't enter 0 as a value for the offset. I find this odd in the extreme.
Currently, netlog support is only when uploading files, not linking them via URL.
For this, we need to update qvis-server support, as well as probably allow them to be loaded in the browser directly if CORS is enabled. For now, this flow is quite .qlog centric, so need to go through and make this more generalizable.
Concrete problem: when transforming pcaps using pcap2qlog, they will always be seen as a client-side trace. As such, if you have two pcaps, one from the client and one from the server, there's currently no real way in qvis to upload them and then have them correctly identified as client and server.
I tried a very naive fix for this (a68255f), but that doesn't work because the second trace still has perpendicular packet_sent
and packet_received
semantics and so the packets still don't match up.
Ideally, you'd be able to indicate/override the vantagepoint when uploading/linking the pcap, but then that would have to propagate all the way down to qvis-server and then into pcap2qlog, for which at the moment -no- plumbing is present. Dirty hacks such as "look for the string 'server' in the filename/extension" are possible, but suboptimal...
Another option is to transform the 2nd trace to be server-side automatically. We have code for that, but this is in the sequencediagram itself atm and only used when auto-generating new traces from scratch, not really to adjust existing traces (though it can of course be refactored). In this case, we'd have to auto-generate a server-side trace as well and select that (since we don't want to drop the original perspective in case the user mis-selects the trace as the second one etc.)
This is all doable for just 2 traces, but the sequence diagram is really made for N traces (e.g., also allowing a load balancer viewpoint etc.) so long term a better solution would be needed where traces' vantagepoint can be transformed at will (potentially via a separate UI?).
Error codes are currently displayed as decimal numbers. That makes it hard to interpret them.
For example, crypto errors are 0x1XX
(see https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#name-transport-error-codes).
Describe the bug
Attached file. There are a couple hundred packets sent each way, but the "sequence" display stops at packet 9.
To Reproduce
Expected behavior
Would liek to see the whole sequence of packets
Screenshots
If applicable, add screenshots to help explain your problem.
Additional context
If you are having problems loading a file, please attach it to this issue or email it to us at [email protected]
Note that qvis is currently only tested and maintained for the latest stable versions of Google Chrome. -- I was using Firefox.
copied-to-text.txt
Describe the bug
QVIS does not decode HANDSHAKE_DONE frames (0x1e == 30) (>=draft-25)
To Reproduce
How did you load the file?
Via quic tracker: https://quic-tracker.info.ucl.ac.be/traces/20200321/112
Which visualization had the error?
Sequence
Expected behavior
That it displays HANDSHAKE_DONE
Screenshots
If applicable, add screenshots to help explain your problem.
I uploaded a trace to Github in quic-go/quic-go#2521. Unfortunately, Github doesn't allow me to upload a .qlog file, so I had to rename it to .qlog.txt.
Now qvis refuses to read it:
Error: Trace had an error: {"qlog_version":"draft-01","description":"Generated 5/4/2020, 5:18:05 AM","traces":[{"error_description":"tshark:TransformToJSON : error : Error: Command failed: /wireshark/run/tshark --no-duplicate-keys -r /srv/qvis-cache/inputs/yev8bcvl9jsqphvm0cavdq/3iw6px6qek5so5bdqe1gff.txt -T json > /srv/qvis-cache/inputs/yev8bcvl9jsqphvm0cavdq/52tzqk7t823xuzl9osyzd.json\nRunning as user "root" and group "root". This could be dangerous.\ntshark: The file "/srv/qvis-cache/inputs/yev8bcvl9jsqphvm0cavdq/3iw6px6qek5so5bdqe1gff.txt" isn't a capture file in a format TShark understands.
Hi,
I'm using aioquic to study the streams in qlogs. I wanted to make sure about where to study the streams in qlogs. I see the stream details in Multiplexing tab which tells me when did the stream start and when it ended.
I use aioquic client to send multiple requests within a connection and I see that the throughput of each subsequent request keeps on decreasing. I raised an issue on aioquic regarding this
I was trying to visualize and figure out whether the streams are actually running in parallel or they are sequential ? Is there any place other than multiplexing tab where I can see the behavior of streams and confirm whether the requests are in parallel or in sequential manner. Secondly, if there is any feature in qlogs which can help me understand why the throughput keeps on decreasing ?
Thank You
Best,
Abhinav
Two main things:
Then we can also look at combining them (possibly easier to do this from the start):
cc @LPardue
Currently, when hovering over a packet sent in the congestion diagram, we lookup metrics like bytes_in_flight
by looking at the nearest events in time (instead of actually searching the closest events in terms of order/index in the qlog list).
This is because those events can be far removed from the actual packet_sent
event (or non-existing) and so we use separate lists for this (the same we use to draw the various lines for these metrics on the graph).
If the qlog implementation doesn't use fine-grained timestamps (e.g., purely at ms granularity), this can cause many packet_sent and metrics_updated events to be grouped onto the same timestamp. The hover-behaviour will then show the last data in that "timestamp bucket" instead of properly showing the metric at that packet's time.
In the attached example, this is true for e.g., packet 190 and its surroundings. There are metrics_updated
events interspersed, but they all have the same timestamp, causing the bytes_in_flight
to be 54000 (latest for that timestamp).
This could be resolved by also considering event order/index when doing the lookup, but we currently don't keep track of event indices for individual events, so that would require additional memory or an additional loop over (part of) the events...
CC @junhochoi
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.