Giter Club home page Giter Club logo

ahoy_captain's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ahoy_captain's Issues

Sqlite support

Hello

Thanks for this amazing project really love it

On RubyVideo I have chosen to explore a very simple stack based on SQLite and the Litestack gem.

As a poor man analytics I have implemented this but would love to replace it by Ahoy_captain. Of course I totally understand that Posgresql is the major player and I might be asking for something exotic.

Just in case you plan to support SQLite at some point I will be more than happy to provide a set or real-world data if that can help.

have a good day

Unique Visits always shows equal to Total Visitors

On my deployment these numbers are always the same even though when they should be different. I've verified the results being different for a given month when comparing these queries:

# @presenter.unique_visitors
SELECT SUM(count_visitor_token) AS total_unique_visitors
FROM (
    SELECT COUNT(DISTINCT "ahoy_visits"."visitor_token") AS "count_visitor_token", 
           DATE_TRUNC('day', "ahoy_visits"."started_at"::timestamptz AT TIME ZONE 'America/New_York')::date AS "date_trunc_day"
    FROM "ahoy_visits"
    LEFT OUTER JOIN "ahoy_events" ON "ahoy_events"."visit_id" = "ahoy_visits"."id"
    WHERE ("ahoy_visits"."started_at" > '2023-11-13 00:01:00' AND "ahoy_visits"."started_at" < '2023-12-13 14:20:00')
      AND ("ahoy_events"."time" > '2023-11-13 00:01:00' AND "ahoy_events"."time" < '2023-12-13 14:20:00')
      AND ("ahoy_visits"."started_at" IS NOT NULL)
    GROUP BY DATE_TRUNC('day', "ahoy_visits"."started_at"::timestamptz AT TIME ZONE 'America/New_York')::date
) AS daily_counts;

vs

# @presenter.total_visits
WITH 
  "current" AS (
    SELECT COUNT(DISTINCT "ahoy_visits"."id") 
    FROM "ahoy_visits" 
    LEFT OUTER JOIN "ahoy_events" 
      ON "ahoy_events"."visit_id" = "ahoy_visits"."id" 
    WHERE ("ahoy_visits"."started_at" > '2023-11-13 00:01:00' 
      AND "ahoy_visits"."started_at" < '2023-12-13 14:20:00') 
      AND ("ahoy_events"."time" > '2023-11-13 00:01:00' 
      AND "ahoy_events"."time" < '2023-12-13 14:20:00')
  ), 
  "compare" AS (
    SELECT COUNT(DISTINCT "ahoy_visits"."id") 
    FROM "ahoy_visits" 
    LEFT OUTER JOIN "ahoy_events" 
      ON "ahoy_events"."visit_id" = "ahoy_visits"."id" 
    WHERE ("ahoy_visits"."started_at" > '2023-10-13 09:42:00' 
      AND "ahoy_visits"."started_at" < '2023-11-13 00:01:00') 
      AND ("ahoy_events"."time" > '2023-10-13 09:42:00' 
      AND "ahoy_events"."time" < '2023-11-13 00:01:00')
  ) 
SELECT 
  current, 
  compare 
FROM 
  current, 
  compare;

I'm having a really hard diagnosing where the problem is in the ViewComponents. At the Stats level the queries look fine which is how I derived the ones above but I got lost in ComparableContainerComponent and ran out of time for this problem today.

Ahoy captain not recognizing data or failing to initialize

Hi I have a rails 7 esbuild app and am trying to get it to work with ahoy_captain. When I visit /ahoy_captain, I do not get any results:

img

I also get this error and other warnings in the console:

img

I followed the installation instructions to the tee (although, rails g ahoy_captain:migration does not work).

I also checked that ahoy_visits table has data

Any help is appreciated!

First time run immediately crashes

Just installed the gem, and I do have some events to show:

But the dashboard shows up with some placeholder skeletons, then immediately crashes:

Screenshot 2023-11-01 at 21 09 20

I can circumvent the crash by adding return 0 if value.current.nil? || value.compared_to.nil? before the diff calculation. Happy to open a PR unless you want the comparable itself to have safer logic.

config.disabled_widgets is not writable

I wanted to use config.disabled_widgets in the provided initializer to remove some (to me) unnecessary widgets, but I get an error:

undefined method `disabled_widgets='

Looking at line 6 of configuration.rb it is apparent that :disabled_widgets is only readable, not writable. Changing it to be writable removes the error, but in the actual dashboard I then get a 'content missing' turbo frame error for each of the disabled widgets, instead of the widget being removed, as I would expect.

improve empty state of when there is no data

Currently, seems like folks might want to see something that provides a bit more signal if they have little/no data when first setting things up.
Suggestion: In the event of no data, render a view that gives suggestions for what events should be tracked in order to see them rendered in a given tile

Accessing /ahoy_captain - undefined method `with_option_content'

Getting this error when trying to access the dashboard:

undefined method with_option_content' for #<AhoyCaptain::DropdownLinkComponent:0x00007f25a0495f08 @title="Campaign", @classes=nil, @__vc_original_view_context=#ActionView::Base:0x00000000034bc0, @view_context=#ActionView::Base:0x00000000034bc0, @output_buffer="<div class="dropdown dropdown-end" data-controller='dropdown-label'>\n <label\n tabindex="0"\n class="cursor-pointer flex "\n data-action='click->dropdown-label#removeHidden'\n >\n <span data-dropdown-label-target="label">Campaign\n\n \n <ul class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52" data-dropdown-label-target="close">\n", @lookup_context=#<ActionView::LookupContext:0x00007f25a04e5788 @details_key=#<ActionView::TemplateDetails::Requested:0x00007f25a3b83240 @Locale=[:en], @handlers=[:raw, :erb, :html, :builder, :ruby, :jbuilder], @formats=[:html], @Variants=[], @locale_idx={:en=>0, nil=>1}, @handlers_idx={:raw=>0, :erb=>1, :html=>2, :builder=>3, :ruby=>4, :jbuilder=>5, nil=>6}, @formats_idx={:html=>0, nil=>1}, @variants_idx={nil=>0}>, @digest_cache=nil, @cache=true, @Prefixes=["ahoy_captain/roots", "ahoy_captain/application"], @details={:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}, @view_paths=#<ActionView::PathSet:0x00007f25a04e5508 @paths=[#<ActionView::FileSystemResolver:0x00007f25a36c05f0 @unbound_templates=#<Concurrent::Map:0x00007f25a36c05c8 entries=13 default_proc=nil>, @path_parser=#<ActionView::Resolver::PathParser:0x00007f25a368c6b0 @regex=/
\A
(?:(?.)/)?
(?_)?
(?.
?)
(?:.(?[a-z]{2}(?:[-][A-Z]{2})?))??
(?:.(?html|text|js|css|ics|csv|vcf|vtt|png|jpeg|gif|bmp|tiff|svg|mpeg|mp3|ogg|m4a|webm|mp4|otf|ttf|woff|woff2|xml|rss|atom|yaml|multipart_form|url_encoded_form|json|pdf|zip|gzip|turbo_stream))??
(?:+(?[^.]))??
(?:.(?raw|erb|html|builder|ruby|jbuilder))?
\z
/x>, @path="/home/james/src/clubs/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c08e8 @unbound_templates=#<Concurrent::Map:0x00007f25a36c07a8 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c660, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/letter_opener_web-1.4.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c0ac8 @unbound_templates=#<Concurrent::Map:0x00007f25a36c0aa0 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c638, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/bootstrap5-kaminari-views-0.0.1/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c0d70 @unbound_templates=#<Concurrent::Map:0x00007f25a36c0d20 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c610, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/kaminari-core-1.2.2/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1040 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1018 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c5c0, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/paul_revere-3.3.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c12c0 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1298 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c598, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/devise-4.8.1/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1568 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1518 entries=7 default_proc=nil>, @path_parser=#<ActionView::Resolver::PathParser:0x00007f25a368c570 @regex=/
\A
(?:(?.
)/)?
(?
)?
(?.?)
(?:.(?[a-z]{2}(?:[-_][A-Z]{2})?))??
(?:.(?html|text|js|css|ics|csv|vcf|vtt|png|jpeg|gif|bmp|tiff|svg|mpeg|mp3|ogg|m4a|webm|mp4|otf|ttf|woff|woff2|xml|rss|atom|yaml|multipart_form|url_encoded_form|json|pdf|zip|gzip|turbo_stream))??
(?:+(?[^.]
))??
(?:.(?raw|erb|html|builder|ruby|jbuilder))?
\z
/x>, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/ahoy_captain-1.0.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1748 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1720 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c548, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/view_component-2.82.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c19c8 @unbound_templates=#<Concurrent::Map:0x00007f25a36c19a0 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c4f8, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/turbo-rails-1.4.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1b80 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1b58 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c430, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/active_analytics-0.2.1/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1d60 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1d38 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c408, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/actiontext-7.0.4/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c2080 @unbound_templates=#<Concurrent::Map:0x00007f25a36c2008 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c3e0, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/actionmailbox-7.0.4/app/views">]>>, @view_renderer=#<ActionView::Renderer:0x00007f25a04cb7c0 @lookup_context=#<ActionView::LookupContext:0x00007f25a04e5788 @details_key=#<ActionView::TemplateDetails::Requested:0x00007f25a3b83240 @Locale=[:en], @handlers=[:raw, :erb, :html, :builder, :ruby, :jbuilder], @formats=[:html], @Variants=[], @locale_idx={:en=>0, nil=>1}, @handlers_idx={:raw=>0, :erb=>1, :html=>2, :builder=>3, :ruby=>4, :jbuilder=>5, nil=>6}, @formats_idx={:html=>0, nil=>1}, @variants_idx={nil=>0}>, @digest_cache=nil, @cache=true, @Prefixes=["ahoy_captain/roots", "ahoy_captain/application"], @details={:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}, @view_paths=#<ActionView::PathSet:0x00007f25a04e5508 @paths=[#<ActionView::FileSystemResolver:0x00007f25a36c05f0 @unbound_templates=#<Concurrent::Map:0x00007f25a36c05c8 entries=13 default_proc=nil>, @path_parser=#<ActionView::Resolver::PathParser:0x00007f25a368c6b0 @regex=/
\A
(?:(?.)/)?
(?_)?
(?.
?)
(?:.(?[a-z]{2}(?:[-][A-Z]{2})?))??
(?:.(?html|text|js|css|ics|csv|vcf|vtt|png|jpeg|gif|bmp|tiff|svg|mpeg|mp3|ogg|m4a|webm|mp4|otf|ttf|woff|woff2|xml|rss|atom|yaml|multipart_form|url_encoded_form|json|pdf|zip|gzip|turbo_stream))??
(?:+(?[^.]))??
(?:.(?raw|erb|html|builder|ruby|jbuilder))?
\z
/x>, @path="/home/james/src/clubs/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c08e8 @unbound_templates=#<Concurrent::Map:0x00007f25a36c07a8 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c660, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/letter_opener_web-1.4.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c0ac8 @unbound_templates=#<Concurrent::Map:0x00007f25a36c0aa0 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c638, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/bootstrap5-kaminari-views-0.0.1/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c0d70 @unbound_templates=#<Concurrent::Map:0x00007f25a36c0d20 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c610, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/kaminari-core-1.2.2/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1040 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1018 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c5c0, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/paul_revere-3.3.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c12c0 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1298 entries=7 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c598, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/devise-4.8.1/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1568 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1518 entries=7 default_proc=nil>, @path_parser=#<ActionView::Resolver::PathParser:0x00007f25a368c570 @regex=/
\A
(?:(?.
)/)?
(?
)?
(?.?)
(?:.(?[a-z]{2}(?:[-_][A-Z]{2})?))??
(?:.(?html|text|js|css|ics|csv|vcf|vtt|png|jpeg|gif|bmp|tiff|svg|mpeg|mp3|ogg|m4a|webm|mp4|otf|ttf|woff|woff2|xml|rss|atom|yaml|multipart_form|url_encoded_form|json|pdf|zip|gzip|turbo_stream))??
(?:+(?[^.]
))??
(?:.(?raw|erb|html|builder|ruby|jbuilder))?
\z
/x>, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/ahoy_captain-1.0.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1748 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1720 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c548, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/view_component-2.82.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c19c8 @unbound_templates=#<Concurrent::Map:0x00007f25a36c19a0 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c4f8, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/turbo-rails-1.4.0/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1b80 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1b58 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c430, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/active_analytics-0.2.1/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c1d60 @unbound_templates=#<Concurrent::Map:0x00007f25a36c1d38 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c408, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/actiontext-7.0.4/app/views">, #<ActionView::FileSystemResolver:0x00007f25a36c2080 @unbound_templates=#<Concurrent::Map:0x00007f25a36c2008 entries=4 default_proc=nil>, @path_parser=#ActionView::Resolver::PathParser:0x00007f25a368c3e0, @path="/home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/actionmailbox-7.0.4/app/views">]>>, @cache_hits={}>, @view_flow=#<ActionView::OutputFlow:0x00007f25a04cb680 @content={}>, @virtual_path="/ahoy_captain/dropdown_link_component", @__vc_variant=nil, @current_template=nil, @__vc_content_evaluated=true, @__vc_render_in_block=#<Proc:0x00007f25a0495e40 /home/james/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/ahoy_captain-1.0.0/app/views/ahoy_captain/roots/show.html.erb:50>>`

Ruby 3.1.0

stacktrace.txt
Gemfile_lock.txt

MySQL support?

Any chance you're planning to add support MySQL databases?

I played around a bit and it's close to working out of the box except the JSONB_EXISTS and jsonb_object_keys methods which are Postgres specific. I have a JSON column in my database and apart from the missing methods, it seems like it could work. MySQL 8 introduced the JSON_CONTAINS_PATH method and JSON_EXTRACT has been available since v5. Either of those will work to check if a key exists. And the JSON_KEYS function allows for access to the key value store.

Looks like support for MySQL databases would be possible, but it would require a bunch of refactoring to allow for choosing different database adapters. I'll tinker around a bit more myself to see if I can get a fork working for my application, but it would be great to know if others are doing anything similar!

Entry Pages query crashes

I'm guessing this is because I use UUIDs as my primary key type, and the query is expecting integer IDs:

image

Update README with example of correct Ahoy event tracking?

This project looks really cool, thanks for putting it out there!

The ahoy_captain README just points to the section in the Ahoy documents that show:

class ApplicationController < ActionController::Base
  after_action :track_action

  protected

  def track_action
    ahoy.track "Ran action", request.path_parameters
  end
end

What's a properly working example configuration for capturing events they way they have been in the screenshot? Are we supposed to literally track an event with the name "$view", or is that supposed to be a substitution example?

Issues while trying app

  • The syntax for the template configuration file is wrong.
AhoyCaptain.configure 

should be

AhoyCaptain.configure do |config|
  • Docs imply that I should run a generator to add additional indexes, but this task does not exist.

  • We do not use the turbo gem in our application. We do render some templates in background jobs. After installing the ahoy_captain gem those jobs get errors like this:

    NoMethodError:
       Could not render layout: undefined method `headers' for nil:NilClass
     # /usr/local/bundle/gems/turbo-rails-1.4.0/app/controllers/turbo/frames/frame_request.rb:34:in `turbo_frame_request_id'
     # /usr/local/bundle/gems/turbo-rails-1.4.0/app/controllers/turbo/frames/frame_request.rb:30:in `turbo_frame_request?'
     # /usr/local/bundle/gems/turbo-rails-1.4.0/app/controllers/turbo/frames/frame_request.rb:24:in `block (2 levels) in <module:FrameRequest>'
     # ./app/sidekiq/add_card_to_stage.rb:11:in `perform'

I'm not clear on why adding the ahoy_captain gem causes turbo gem code to be called outside of the engine itself.

Date issues

Hi,

I just noticed an issue with the overview:

image

As you can see the dates go from 29th of March, 31st of March, 2nd of April and then jump back to the 4th of March and continue from there.

The view is set to 30 days and I am using my own fork to have the shim fixes from here #40 and the latest ahoy_captain code.

The fork is here:

https://github.com/abuisman/ahoy_captain

I can't get the forkless version working because of the #40 issues and I am experiencing these issues: #36

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.