zeenix / gps-share Goto Github PK
View Code? Open in Web Editor NEWUtility to share your GPS device on local network
License: GNU General Public License v2.0
Utility to share your GPS device on local network
License: GNU General Public License v2.0
Are Galileo and GLONASS location sources supported? Should be documented. Shouldn’t also the project be renamed “gnss-share” for global navigation satellite systems or “satloc-share” for satellite location share?
I try to build current git version:
$ cargo build
Updating registry https://github.com/rust-lang/crates.io-index
Updating git repository https://github.com/antoyo/dbus-macros-rs
Downloading serial v0.3.4
Downloading libudev v0.2.0
Downloading libc v0.2.36
Downloading chan v0.1.20
Downloading clap v2.29.2
Downloading chan-signal v0.2.0
Downloading dbus v0.5.4
Downloading termios v0.2.2
Downloading ioctl-rs v0.1.6
Downloading libdbus-sys v0.1.2
Downloading metadeps v1.1.2
Downloading error-chain v0.10.0
Downloading toml v0.2.1
Downloading pkg-config v0.3.9
Downloading libudev-sys v0.1.4
Downloading rand v0.3.20
Downloading atty v0.2.6
Downloading strsim v0.6.0
Downloading ansi_term v0.10.2
Downloading bitflags v1.0.1
Downloading textwrap v0.9.0
Downloading vec_map v0.8.0
Downloading unicode-width v0.1.4
Downloading lazy_static v0.2.11
Downloading bit-set v0.4.0
Downloading bit-vec v0.4.4
Compiling bit-vec v0.4.4
Compiling bitflags v1.0.1
Compiling lazy_static v0.2.11
Compiling pkg-config v0.3.9
error: expected ident, found #
--> /home/serge/.cargo/registry/src/github.com-1ecc6299db9ec823/bitflags-1.0.1/src/lib.rs:423:29
|
423 | #[allow(deprecated)]
| ^
|
::: /home/serge/.cargo/registry/src/github.com-1ecc6299db9ec823/bitflags-1.0.1/src/example_generated.rs
|
4 | / bitflags! {
5 | | /// This is the same Flags
struct defined in the crate level example.
6 | | /// Note that this struct is just for documentation purposes only, it must not be used outside
7 | | /// this crate.
... |
13 | | }
14 | | }
| |_- in this macro invocation
error: Could not compile bitflags
.
warning: build failed, waiting for other jobs to finish...
error: build failed
Hi, great work.
can you add some documentation how this service works together with geoclue2?
https://github.com/zeenix/gps-share/blob/master/src/cmdline_config.rs#L29
says 0.1 - but actually its 0.2
Building gps-share fails with:
All builds were performed using debian based rust toolchain available on dockerhub, namely
rust:1.28.0-stretch
rust:1.31.1-stretch
rust:1.42.0-buster
Sample Dockerfile:
ARG GPSSHARE_RELEASE=0.2.0
FROM alpine:latest AS fetch
ARG GPSSHARE_RELEASE
WORKDIR /work
RUN apk add curl
RUN curl -L https://github.com/zeenix/gps-share/archive/${GPSSHARE_RELEASE}.tar.gz | tar -xz
FROM rust:1.42.0-buster AS build
ARG GPSSHARE_RELEASE
WORKDIR /work
COPY --from=fetch /work/gps-share-${GPSSHARE_RELEASE} /work/source
RUN apt-get update && apt-get install -y libdbus-1-dev libudev-dev
WORKDIR /work/source
RUN cargo build --release
So in chronological order:
Step 13/14 : RUN cargo build --release
---> Running in a7ab44d7fcd9
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading dbus v0.5.4
Downloading dbus-macros v0.2.3
Downloading chan v0.1.23
Downloading serial v0.3.4
Downloading libc v0.2.68
Downloading chan-signal v0.2.0
Downloading clap v2.33.0
Downloading libudev v0.2.0
Downloading libdbus-sys v0.1.5
Downloading pkg-config v0.3.17
Downloading rand v0.3.23
Downloading rand v0.4.6
Downloading ioctl-rs v0.1.6
Downloading termios v0.2.2
Downloading lazy_static v0.2.11
Downloading bit-set v0.4.0
Downloading bit-vec v0.4.4
Downloading textwrap v0.11.0
Downloading ansi_term v0.11.0
Downloading unicode-width v0.1.7
error: unable to get packages from source
Caused by:
failed to parse manifest at `/usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/unicode-width-0.1.7/Cargo.toml`
Caused by:
feature `rename-dependency` is required
this Cargo does not support nightly features, but if you
switch to nightly channel you can add
`cargo-features = ["rename-dependency"]` to enable this feature
^^ Well, apparently this cargo (1.28.0) is too old
Step 13/14 : RUN cargo build --release
---> Running in a7ca4551e3db
Updating crates.io index
Downloading crates ...
Downloaded libudev v0.2.0
Downloaded libc v0.2.68
Downloaded clap v2.33.0
Downloaded chan-signal v0.2.0
Downloaded dbus v0.5.4
Downloaded serial v0.3.4
Downloaded chan v0.1.23
Downloaded lazy_static v0.2.11
Downloaded ansi_term v0.11.0
Downloaded strsim v0.8.0
Downloaded bit-set v0.4.0
Downloaded textwrap v0.11.0
Downloaded vec_map v0.8.1
Downloaded unicode-width v0.1.7
Downloaded atty v0.2.14
Downloaded bitflags v1.2.1
Downloaded dbus-macros v0.2.3
Downloaded libdbus-sys v0.1.5
Downloaded ioctl-rs v0.1.6
Downloaded libudev-sys v0.1.4
Downloaded rand v0.3.23
Downloaded bit-vec v0.4.4
Downloaded pkg-config v0.3.17
Downloaded rand v0.4.6
Downloaded termios v0.2.2
Compiling libc v0.2.68
Compiling pkg-config v0.3.17
Compiling bitflags v1.2.1
Compiling unicode-width v0.1.7
Compiling bit-vec v0.4.4
Compiling vec_map v0.8.1
Compiling strsim v0.8.0
Compiling lazy_static v0.2.11
Compiling ansi_term v0.11.0
Compiling textwrap v0.11.0
Compiling bit-set v0.4.0
Compiling libdbus-sys v0.1.5
Compiling libudev-sys v0.1.4
Compiling rand v0.4.6
Compiling ioctl-rs v0.1.6
Compiling termios v0.2.2
Compiling atty v0.2.14
Compiling clap v2.33.0
Compiling serial v0.3.4
Compiling dbus v0.5.4
Compiling libudev v0.2.0
Compiling rand v0.3.23
Compiling chan v0.1.23
Compiling chan-signal v0.2.0
Compiling dbus-macros v0.2.3
Compiling gps-share v0.2.0 (/work/source)
error[E0308]: mismatched types
--> src/config.rs:101:17
|
101 | host_ptr,
| ^^^^^^^^ expected u8, found i8
|
= note: expected type `*mut u8`
found type `*mut i8`
error[E0308]: mismatched types
--> src/config.rs:107:38
|
107 | host = CString::from_raw(host_ptr);
| ^^^^^^^^ expected u8, found i8
|
= note: expected type `*mut u8`
found type `*mut i8`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
error: Could not compile `gps-share`.
To learn more, run the command again with --verbose
^^ Hmph.
Step 13/14 : RUN cargo build --release
---> Running in 37e5d33bc8ff
Updating crates.io index
Downloading crates ...
Downloaded chan v0.1.23
Downloaded dbus v0.5.4
Downloaded dbus-macros v0.2.3
Downloaded chan-signal v0.2.0
Downloaded clap v2.33.0
Downloaded serial v0.3.4
Downloaded libudev v0.2.0
Downloaded libc v0.2.68
Downloaded ioctl-rs v0.1.6
Downloaded rand v0.3.23
Downloaded atty v0.2.14
Downloaded libudev-sys v0.1.4
Downloaded libdbus-sys v0.1.5
Downloaded lazy_static v0.2.11
Downloaded bit-set v0.4.0
Downloaded bitflags v1.2.1
Downloaded unicode-width v0.1.7
Downloaded vec_map v0.8.1
Downloaded textwrap v0.11.0
Downloaded termios v0.2.2
Downloaded strsim v0.8.0
Downloaded ansi_term v0.11.0
Downloaded rand v0.4.6
Downloaded bit-vec v0.4.4
Downloaded pkg-config v0.3.17
Compiling libc v0.2.68
Compiling pkg-config v0.3.17
Compiling bitflags v1.2.1
Compiling bit-vec v0.4.4
Compiling unicode-width v0.1.7
Compiling strsim v0.8.0
Compiling ansi_term v0.11.0
Compiling vec_map v0.8.1
Compiling lazy_static v0.2.11
Compiling textwrap v0.11.0
Compiling bit-set v0.4.0
Compiling libdbus-sys v0.1.5
Compiling libudev-sys v0.1.4
Compiling rand v0.4.6
Compiling ioctl-rs v0.1.6
Compiling termios v0.2.2
Compiling atty v0.2.14
Compiling clap v2.33.0
Compiling serial v0.3.4
Compiling dbus v0.5.4
Compiling libudev v0.2.0
Compiling rand v0.3.23
Compiling chan v0.1.23
Compiling chan-signal v0.2.0
Compiling dbus-macros v0.2.3
Compiling gps-share v0.2.0 (/work/source)
warning: use of deprecated item 'try': use the `?` operator instead
--> src/avahi.rs:27:1
|
27 | / dbus_interface!("org.freedesktop.Avahi.Server", interface Server {
28 | | fn entry_group_new() -> dbus::Path;
29 | | fn get_network_interface_index_by_name(name: &str) -> i32;
30 | | });
| |___^
|
= note: `#[warn(deprecated)]` on by default
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
warning: use of deprecated item 'try': use the `?` operator instead
--> src/avahi.rs:27:1
|
27 | / dbus_interface!("org.freedesktop.Avahi.Server", interface Server {
28 | | fn entry_group_new() -> dbus::Path;
29 | | fn get_network_interface_index_by_name(name: &str) -> i32;
30 | | });
| |___^
|
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
warning: trait objects without an explicit `dyn` are deprecated
--> src/rs232.rs:49:44
|
49 | RS232::configure(&mut port as &mut serial::SerialPort, config)?;
| ^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn serial::SerialPort`
|
= note: `#[warn(bare_trait_objects)]` on by default
warning: trait objects without an explicit `dyn` are deprecated
--> src/rs232.rs:54:29
|
54 | fn configure(port: &mut serial::SerialPort, config: &Config) -> serial::Result<()> {
| ^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn serial::SerialPort`
warning: trait objects without an explicit `dyn` are deprecated
--> src/server.rs:35:20
|
35 | gps: Arc<Mutex<gps::GPS>>,
| ^^^^^^^^ help: use `dyn`: `dyn gps::GPS`
warning: trait objects without an explicit `dyn` are deprecated
--> src/client_handler.rs:30:20
|
30 | gps: Arc<Mutex<gps::GPS>>,
| ^^^^^^^^ help: use `dyn`: `dyn gps::GPS`
warning: trait objects without an explicit `dyn` are deprecated
--> src/client_handler.rs:35:31
|
35 | pub fn new(gps: Arc<Mutex<gps::GPS>>, streams: Arc<Mutex<Vec<TcpStream>>>) -> Self {
| ^^^^^^^^ help: use `dyn`: `dyn gps::GPS`
warning: trait objects without an explicit `dyn` are deprecated
--> src/main.rs:90:39
|
90 | fn get_gps(config: Rc<Config>) -> Box<GPS> {
| ^^^ help: use `dyn`: `dyn GPS`
warning: trait objects without an explicit `dyn` are deprecated
--> src/main.rs:112:35
|
112 | fn run_server_handle_err(gps: Box<GPS>, config: Rc<Config>) {
| ^^^ help: use `dyn`: `dyn GPS`
warning: trait objects without an explicit `dyn` are deprecated
--> src/main.rs:120:24
|
120 | fn run_server(gps: Box<GPS>, config: Rc<Config>) -> ::std::io::Result<()> {
| ^^^ help: use `dyn`: `dyn GPS`
error[E0308]: mismatched types
--> src/config.rs:101:17
|
101 | host_ptr,
| ^^^^^^^^ expected `u8`, found `i8`
|
= note: expected raw pointer `*mut u8`
found raw pointer `*mut i8`
error[E0308]: mismatched types
--> src/config.rs:107:38
|
107 | host = CString::from_raw(host_ptr);
| ^^^^^^^^ expected `u8`, found `i8`
|
= note: expected raw pointer `*mut u8`
found raw pointer `*mut i8`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
error: could not compile `gps-share`.
To learn more, run the command again with --verbose.
Now that's a lot of noise, but the error is same as with 1.31.1 .... any ideas?
~/build/src/gps-share-0.3.0 $ cargo build --release --locked
Updating crates.io index
error: the lock file /home/pmos/build/src/gps-share-0.3.0/Cargo.lock needs to be updated but --locked was passed to prevent this
If you want to try to generate the lock file without accessing the network, use the --offline flag.
The device:
http://www.navilock.de/produkte/F_778_GPS_61422/merkmale.html?setLanguage=en
The Udev Output:
udevadm info /dev/ttyUSB0
P: /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0
N: ttyUSB0
S: gps0
S: serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0
S: serial/by-path/pci-0000:00:1a.0-usb-0:1.2:1.0-port0
E: DEVLINKS=/dev/gps0 /dev/serial/by-path/pci-0000:00:1a.0-usb-0:1.2:1.0-port0 /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0
E: DEVNAME=/dev/ttyUSB0
E: DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0
E: ID_BUS=usb
E: ID_MM_CANDIDATE=1
E: ID_MODEL=USB-Serial_Controller
E: ID_MODEL_ENC=USB-Serial\x20Controller
E: ID_MODEL_FROM_DATABASE=PL2303 Serial Port
E: ID_MODEL_ID=2303
E: ID_PATH=pci-0000:00:1a.0-usb-0:1.2:1.0
E: ID_PATH_TAG=pci-0000_00_1a_0-usb-0_1_2_1_0
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_PCI_INTERFACE_FROM_DATABASE=EHCI
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
E: ID_REVISION=0300
E: ID_SERIAL=Prolific_Technology_Inc._USB-Serial_Controller
E: ID_TYPE=generic
E: ID_USB_DRIVER=pl2303
E: ID_USB_INTERFACES=:ff0000:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=Prolific_Technology_Inc.
E: ID_VENDOR_ENC=Prolific\x20Technology\x20Inc.
E: ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.
E: ID_VENDOR_ID=067b
E: MAJOR=188
E: MINOR=0
E: SUBSYSTEM=tty
E: [email protected]
E: TAGS=:systemd:
E: USEC_INITIALIZED=520043777
lsusb:
Bus 001 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Terminal Output:
# ./gps-share -b 4800
Attempting to autodetect GPS device...
/dev/ttyUSB0 seems interesting
Needs verification
Reading from port..
Failed to read from serial port
Reading from port..
Failed to read from serial port
Not verified
Failed to autodetect GPS device
Specifying device and connecting via telnet:
# ./gps-share /dev/ttyUSB0 -b 4800
TCP server bound on all interfaces
Port: 37391
group: /Client2/EntryGroup1
Connection from 127.0.0.1
Failed to read from serial port: stream did not contain valid UTF-8
Failed to read from serial port: stream did not contain valid UTF-8
Failed to read from serial port: stream did not contain valid UTF-8 ...
Dear @zeenix ,
Could you please consider publishing gps-share on crates.io?
We have some automation for Rust package managment, downstream at Debian, but it rely on crates.io to pull the crates.
That would ease the downstream packaging of gps-share for Debian and its derivative.
Thanks and best regards,
The device:
http://www.navilock.de/produkte/F_778_GPS_61840/merkmale.html?setLanguage=en
The Udev output:
$ udevadm info /dev/ttyACM0
P: /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/tty/ttyACM0
N: ttyACM0
S: gps0
S: serial/by-id/usb-u-blox_AG_-_www.u-blox.com_u-blox_6_-_GPS_Receiver-if00
S: serial/by-path/pci-0000:00:1a.0-usb-0:1.2:1.0
E: DEVLINKS=/dev/serial/by-path/pci-0000:00:1a.0-usb-0:1.2:1.0 /dev/gps0 /dev/serial/by-id/usb-u-blox_AG_-_www.u-blox.com_u-blox_6_-_GPS_Receiver-if00
E: DEVNAME=/dev/ttyACM0
E: DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/tty/ttyACM0
E: ID_BUS=usb
E: ID_MM_CANDIDATE=1
E: ID_MODEL=u-blox_6_-_GPS_Receiver
E: ID_MODEL_ENC=u-blox\x206\x20\x20-\x20\x20GPS\x20Receiver
E: ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller
E: ID_MODEL_ID=01a6
E: ID_PATH=pci-0000:00:1a.0-usb-0:1.2:1.0
E: ID_PATH_TAG=pci-0000_00_1a_0-usb-0_1_2_1_0
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_PCI_INTERFACE_FROM_DATABASE=EHCI
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
E: ID_REVISION=0602
E: ID_SERIAL=u-blox_AG_-_www.u-blox.com_u-blox_6_-_GPS_Receiver
E: ID_TYPE=generic
E: ID_USB_CLASS_FROM_DATABASE=Communications
E: ID_USB_DRIVER=cdc_acm
E: ID_USB_INTERFACES=:020201:0a00ff:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=u-blox_AG_-_www.u-blox.com
E: ID_VENDOR_ENC=u-blox\x20AG\x20-\x20www.u-blox.com
E: ID_VENDOR_FROM_DATABASE=U-Blox AG
E: ID_VENDOR_ID=1546
E: MAJOR=166
E: MINOR=0
E: SUBSYSTEM=tty
E: [email protected]
E: TAGS=:systemd:
E: USEC_INITIALIZED=1311715376
lsusb:
Bus 001 Device 007: ID 1546:01a6 U-Blox AG
Terminal output:
./gps-share
Attempting to autodetect GPS device...
Skipping /dev/ttyACM0. Driver cdc_acm
Failed to autodetect GPS device
Specifying the device directly and telnetting into the port:
sudo ./gps-share /dev/ttyACM0
TCP server bound on all interfaces
Port: 41017
group: /Client4/EntryGroup1
Connection from 127.0.0.1
Failed to read from serial port: Operation timed out //these appear about every 3-5 seconds
Failed to read from serial port: Operation timed out
...
Telnet result:
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
$GPRMC,131639.00,V,,,,,,,180817,,,N*75
$GPVTG,,,,,,,,,N*30
$GPGGA,131639.00,,,,,0,00,99.99,,,,,,*69
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,13,01,11,262,,08,68,279,,10,65,100,,11,24,278,*7B
$GPGSV,4,2,13,14,01,147,,15,10,028,,16,16,193,,18,41,063,*76
$GPGSV,4,3,13,21,15,084,,27,67,157,,28,09,332,,30,06,310,*76
$GPGSV,4,4,13,32,13,136,*4C
$GPGLL,,,,,131639.00,V,N*45
$GPTXT,01,01,02,u-blox ag - www.u-blox.com*50
$GPTXT,01,01,02,HW UBX-G60xx 00040007 *52
$GPTXT,01,01,02,ROM CORE 6.02 (36023) Oct 15 2009 16:52:08*56
$GPTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*20
$GPTXT,01,01,02,ANTSTATUS=OK*3B
$GPRMC,131640.00,V,,,,,,,180817,,,N*7B
$GPVTG,,,,,,,,,N*30
$GPGGA,131640.00,,,,,0,00,99.99,,,,,,*67
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,13,01,11,262,,08,68,279,,10,65,100,,11,24,278,*7B
$GPGSV,4,2,13,14,01,147,,15,10,028,,16,16,193,,18,41,063,*76
$GPGSV,4,3,13,21,15,084,,27,67,157,,28,09,332,,30,06,310,*76
$GPGSV,4,4,13,32,13,136,*4C
$GPGLL,,,,,131640.00,V,N*4B
$GPRMC,131641.00,V,,,,,,,180817,,,N*7A
$GPVTG,,,,,,,,,N*30
$GPGGA,131641.00,,,,,0,00,99.99,,,,,,*66
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,13,01,11,262,,08,68,279,,10,65,100,,11,24,278,*7B
$GPGSV,4,2,13,14,01,147,,15,10,028,,16,16,193,,18,41,063,*76
$GPGSV,4,3,13,21,15,084,,27,67,157,,28,09,332,,30,06,310,*76
$GPGSV,4,4,13,32,13,136,*4C
$GPGLL,,,,,131641.00,V,N*4A
$GPRMC,131642.00,V,,,,,,,180817,,,N*79
$GPVTG,,,,,,,,,N*30
$GPGGA,131642.00,,,,,0,00,99.99,,,,,,*65
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,13,01,11,262,,08,68,279,,10,65,100,,11,24,278,*7B
$GPGSV,4,2,13,14,01,147,,15,10,028,,16,16,193,,18,41,063,*76
$GPGSV,4,3,13,21,15,084,,27,67,157,,28,09,332,,30,06,310,*76
$GPGSV,4,4,13,32,13,136,*4C
$GPGLL,,,,,131642.00,V,N*49
$GPRMC,131643.00,V,,,,,,,180817,,,N*78
$GPVTG,,,,,,,,,N*30
... AND SO ON
travis-ci.org is going away soon and GH actions is superior anyway so should move the CI to that.
cc @dcz-purism @nytowl.
TCP port 10110 is the standard port for nmea-0183
services. The port has been claimed and registered with IANA, making it an established industry standard.
Use of this port with GeoClue specifically has prescience in the GeoClueShare app for Android.
Using this port instead of a dynamically selected port will ease service discovery and uncomplicate packaging and firewall configuration.
If you agree to the change @zeenix, I’ll add generic firewall service definitions upstream so people will be able to just enable the nmea-0183 service in their firewall to allow remote connections to gps-share.
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.