├── test ├── test_helper.exs ├── lowflyingrocks_test.exs └── api.json ├── .tool-versions ├── config ├── dev.exs ├── test.exs ├── prod.exs.example ├── releases.exs └── config.exs ├── .formatter.exs ├── priv ├── asteroid.jpg └── background.jpg ├── .dockerignore ├── lib └── lowflyingrocks │ ├── neo.ex │ ├── mastodon.ex │ ├── application.ex │ ├── formatter.ex │ ├── parser.ex │ ├── importer.ex │ └── tweeter.ex ├── rel ├── env.bat.eex ├── vm.args.eex └── env.sh.eex ├── README.md ├── .gitignore ├── mix.exs ├── Dockerfile └── mix.lock /test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | erlang 27.0.1 2 | elixir 1.17.2-otp-27 3 | -------------------------------------------------------------------------------- /config/dev.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | import_config "dev.secret.exs" 4 | -------------------------------------------------------------------------------- /config/test.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :lowflyingrocks, import_interval: 3600 4 | -------------------------------------------------------------------------------- /.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | inputs: ["*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"] 3 | ] 4 | -------------------------------------------------------------------------------- /priv/asteroid.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomtaylor/lowflyingrocks/HEAD/priv/asteroid.jpg -------------------------------------------------------------------------------- /priv/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomtaylor/lowflyingrocks/HEAD/priv/background.jpg -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | _build/ 2 | deps/ 3 | .git/ 4 | .gitignore 5 | Dockerfile 6 | README* 7 | test/ 8 | .elixir_ls 9 | .vscode 10 | _build -------------------------------------------------------------------------------- /lib/lowflyingrocks/neo.ex: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.NEO do 2 | @enforce_keys [:name, :timestamp, :diameter_min, :diameter_max, :speed, :distance, :url] 3 | defstruct [:name, :timestamp, :diameter_min, :diameter_max, :speed, :distance, :url] 4 | end 5 | -------------------------------------------------------------------------------- /config/prod.exs.example: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :lowflyingrocks, import_interval: 3600 4 | config :lowflyingrocks, perform_tweets: true 5 | 6 | config :extwitter, :oauth, [ 7 | consumer_key: "", 8 | consumer_secret: "", 9 | access_token: "", 10 | access_token_secret: "" 11 | ] 12 | -------------------------------------------------------------------------------- /rel/env.bat.eex: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem Set the release to work across nodes. If using the long name format like 3 | rem the one below (my_app@127.0.0.1), you need to also uncomment the 4 | rem RELEASE_DISTRIBUTION variable below. Must be "sname", "name" or "none". 5 | rem set RELEASE_DISTRIBUTION=name 6 | rem set RELEASE_NODE=<%= @release.name %>@127.0.0.1 7 | -------------------------------------------------------------------------------- /rel/vm.args.eex: -------------------------------------------------------------------------------- 1 | ## Customize flags given to the VM: http://erlang.org/doc/man/erl.html 2 | ## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here 3 | 4 | ## Number of dirty schedulers doing IO work (file, sockets, and others) 5 | ##+SDio 5 6 | 7 | ## Increase number of concurrent ports/sockets 8 | ##+Q 65536 9 | 10 | ## Tweak GC to run more often 11 | ##-env ERL_FULLSWEEP_AFTER 10 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LowFlyingRocks 2 | 3 | A Twitter bot that tweets whenever a Near Earth Object passes the Earth. 4 | 5 | It's an Elixir/OTP application, that pulls data from [NASA JPL's API](http://ssd-api.jpl.nasa.gov) and schedules it to be tweeted at the right time. 6 | 7 | It's running at [@lowflyingrocks](https://twitter.com/lowflyingrocks). 8 | 9 | ## Getting Started 10 | 11 | You'll need to copy `config/prod.exs.example` to `config/prod.exs`, replacing the oauth tokens with your own. 12 | 13 | -------------------------------------------------------------------------------- /config/releases.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :lowflyingrocks, import_interval: 3600 4 | config :lowflyingrocks, perform_tweets: true 5 | 6 | config :extwitter, :oauth, 7 | consumer_key: System.fetch_env!("TWITTER_CONSUMER_KEY"), 8 | consumer_secret: System.fetch_env!("TWITTER_CONSUMER_SECRET"), 9 | access_token: System.fetch_env!("TWITTER_ACCESS_TOKEN"), 10 | access_token_secret: System.fetch_env!("TWITTER_ACCESS_TOKEN_SECRET") 11 | 12 | config :lowflyingrocks, :mastodon, 13 | base_url: System.fetch_env!("MASTODON_BASE_URL"), 14 | bearer_token: System.fetch_env!("MASTODON_TOKEN") 15 | -------------------------------------------------------------------------------- /lib/lowflyingrocks/mastodon.ex: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.Mastodon do 2 | use GenServer 3 | 4 | def start_link(_) do 5 | GenServer.start_link(__MODULE__, :ok, name: __MODULE__) 6 | end 7 | 8 | def init(:ok) do 9 | conn = 10 | Application.get_env(:lowflyingrocks, :mastodon, []) 11 | |> Hunter.new() 12 | 13 | {:ok, conn} 14 | end 15 | 16 | def publish(text) do 17 | GenServer.call(__MODULE__, {:publish, text}, 30_000) 18 | end 19 | 20 | def handle_call({:publish, text}, _from, conn) do 21 | %Hunter.Status{} = status = Hunter.create_status(conn, text) 22 | 23 | {:reply, status, conn} 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /rel/env.sh.eex: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Sets and enables heart (recommended only in daemon mode) 4 | # case $RELEASE_COMMAND in 5 | # daemon*) 6 | # HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND" 7 | # export HEART_COMMAND 8 | # export ELIXIR_ERL_OPTIONS="-heart" 9 | # ;; 10 | # *) 11 | # ;; 12 | # esac 13 | 14 | # Set the release to work across nodes. If using the long name format like 15 | # the one below (my_app@127.0.0.1), you need to also uncomment the 16 | # RELEASE_DISTRIBUTION variable below. Must be "sname", "name" or "none". 17 | # export RELEASE_DISTRIBUTION=name 18 | # export RELEASE_NODE=<%= @release.name %>@127.0.0.1 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | config/prod.exs 23 | .deliver/releases/ 24 | 25 | .vscode 26 | .elixir_ls 27 | 28 | config/dev.secret.exs 29 | -------------------------------------------------------------------------------- /lib/lowflyingrocks/application.ex: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.Application do 2 | @moduledoc false 3 | 4 | use Application 5 | require Logger 6 | 7 | def start(_type, _args) do 8 | log_config() 9 | 10 | import Supervisor.Spec, warn: false 11 | 12 | children = [ 13 | {Finch, name: LowFlyingRocks.Pool}, 14 | LowFlyingRocks.Tweeter, 15 | LowFlyingRocks.Importer, 16 | LowFlyingRocks.Mastodon 17 | ] 18 | 19 | opts = [strategy: :rest_for_one, name: LowFlyingRocks.Supervisor] 20 | Supervisor.start_link(children, opts) 21 | end 22 | 23 | defp log_config do 24 | interval = Application.fetch_env!(:lowflyingrocks, :import_interval) 25 | Logger.info("Set to import every #{interval} seconds") 26 | 27 | perform_tweets = Application.fetch_env!(:lowflyingrocks, :perform_tweets) 28 | Logger.info("Perform tweets set to #{perform_tweets}") 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :lowflyingrocks, 7 | version: "0.1.0", 8 | elixir: "~> 1.9", 9 | build_embedded: Mix.env() == :prod, 10 | start_permanent: Mix.env() == :prod, 11 | deps: deps(), 12 | releases: [ 13 | lowflyingrocks: [ 14 | include_executables_for: [:unix], 15 | applications: [runtime_tools: :permanent] 16 | ] 17 | ] 18 | ] 19 | end 20 | 21 | def application do 22 | [extra_applications: [:logger], mod: {LowFlyingRocks.Application, []}] 23 | end 24 | 25 | defp deps do 26 | [ 27 | {:timex, "~> 3.5"}, 28 | {:finch, "~> 0.14"}, 29 | {:number, "~> 1.0"}, 30 | {:extwitter, "~> 0.12"}, 31 | {:oauther, "~> 1.1"}, 32 | {:jason, "~> 1.2"}, 33 | {:hunter, "~> 0.5"} 34 | ] 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/lowflyingrocks/formatter.ex: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.Formatter do 2 | def format(neo) do 3 | t = neo.timestamp 4 | body = generate_body(neo) 5 | {t, body} 6 | end 7 | 8 | defp generate_body(neo) do 9 | "#{neo.name}, #{format_diameter_range(neo)} in diameter, just passed the Earth at #{ 10 | format_speed(neo) 11 | }, missing by #{format_distance(neo)}. #{neo.url}" 12 | end 13 | 14 | defp format_diameter_range(neo) do 15 | min = neo.diameter_min |> round 16 | max = neo.diameter_max |> round 17 | "#{min}m-#{max}m" 18 | end 19 | 20 | defp format_speed(neo) do 21 | s = neo.speed |> round 22 | "#{s}km/s" 23 | end 24 | 25 | defp format_distance(neo) do 26 | au = neo.distance 27 | km = au * 149_598_000 28 | count = km |> round |> Integer.digits() |> Enum.count() 29 | non_sig_count = count - 3 30 | divider = :math.pow(10, non_sig_count) 31 | s = round(km / divider) * divider 32 | "#{Number.Delimit.number_to_delimited(s, precision: 0)}km" 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /config/config.exs: -------------------------------------------------------------------------------- 1 | # This file is responsible for configuring your application 2 | # and its dependencies with the aid of the Mix.Config module. 3 | import Config 4 | 5 | # This configuration is loaded before any dependency and is restricted 6 | # to this project. If another project depends on this project, this 7 | # file won't be loaded nor affect the parent project. For this reason, 8 | # if you want to provide default values for your application for 9 | # 3rd-party users, it should be done in your "mix.exs" file. 10 | 11 | # You can configure for your application as: 12 | # 13 | # config :lowflyingrocks, key: :value 14 | # 15 | # And access this configuration in your application as: 16 | # 17 | # Application.get_env(:lowflyingrocks, :key) 18 | # 19 | # Or configure a 3rd-party app: 20 | # 21 | # config :logger, level: :info 22 | # 23 | 24 | # It is also possible to import configuration files, relative to this 25 | # directory. For example, you can emulate configuration per environment 26 | # by uncommenting the line below and defining dev.exs, test.exs and such. 27 | # Configuration from the imported file will override the ones defined 28 | # here (which is why it is important to import them last). 29 | # 30 | 31 | config :lowflyingrocks, import_interval: 60 32 | config :lowflyingrocks, perform_tweets: false 33 | 34 | config :logger, handle_sasl_reports: true 35 | 36 | import_config "#{Mix.env()}.exs" 37 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # The version of Alpine to use for the final image 2 | # This should match the version of Alpine that the `elixir:1.8.1-alpine` image uses 3 | ARG ALPINE_VERSION=3.16 4 | 5 | FROM --platform=linux/amd64 elixir:1.14.1-alpine AS builder 6 | 7 | # The environment to build with 8 | ARG MIX_ENV=prod 9 | 10 | ENV APP_NAME="lowflyingrocks" \ 11 | APP_VSN="0.1.0" \ 12 | MIX_ENV=${MIX_ENV} 13 | 14 | # By convention, /opt is typically used for applications 15 | WORKDIR /opt/app 16 | 17 | # This step installs all the build tools we'll need 18 | RUN apk update && \ 19 | apk upgrade --no-cache && \ 20 | apk add --no-cache \ 21 | git \ 22 | build-base && \ 23 | mix local.rebar --force && \ 24 | mix local.hex --force 25 | 26 | COPY . . 27 | 28 | RUN mix do deps.get, deps.compile, compile, release 29 | 30 | # From this line onwards, we're in a new image, which will be the image used in production 31 | FROM --platform=linux/amd64 alpine:${ALPINE_VERSION} 32 | 33 | # We need python, curl, openssh and procps for Heroku ps:exec to work 34 | RUN apk update && \ 35 | apk add --no-cache \ 36 | bash \ 37 | openssl-dev \ 38 | curl \ 39 | libgcc \ 40 | libstdc++ \ 41 | ncurses-libs 42 | 43 | ENV REPLACE_OS_VARS=true \ 44 | LANG=en_US.UTF-8 \ 45 | APP_NAME="lowflyingrocks" \ 46 | MIX_ENV=prod 47 | 48 | WORKDIR /opt/app 49 | 50 | COPY --from=builder /opt/app/_build/${MIX_ENV}/rel/${APP_NAME} . 51 | 52 | CMD trap 'exit' INT; /opt/app/bin/${APP_NAME} start 53 | -------------------------------------------------------------------------------- /lib/lowflyingrocks/parser.ex: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.Parser do 2 | alias LowFlyingRocks.NEO 3 | 4 | def parse(json) do 5 | Jason.decode!(json) 6 | |> Map.fetch!("data") 7 | |> Enum.reject(fn d -> 8 | d |> Enum.at(10) == nil 9 | end) 10 | |> Enum.map(fn d -> 11 | name = d |> Enum.at(0) 12 | distance = d |> Enum.at(4) |> parse_float() 13 | speed = d |> Enum.at(7) |> parse_float() 14 | h = d |> Enum.at(10) |> parse_float() 15 | timestamp = d |> Enum.at(3) |> parse_timestamp 16 | 17 | url = "https://ssd.jpl.nasa.gov/sbdb.cgi?sstr=#{name}" |> URI.encode() 18 | 19 | %NEO{ 20 | name: name, 21 | timestamp: timestamp, 22 | distance: distance, 23 | speed: speed, 24 | diameter_min: diameter_min(h), 25 | diameter_max: diameter_max(h), 26 | url: url 27 | } 28 | end) 29 | end 30 | 31 | defp diameter_min(h) do 32 | h_to_diameter(h, 0.25) 33 | end 34 | 35 | defp diameter_max(h) do 36 | h_to_diameter(h, 0.05) 37 | end 38 | 39 | defp h_to_diameter(h, p) do 40 | ee = -0.2 * h 41 | 1329.0 / :math.sqrt(p) * :math.pow(10, ee) * 1000 42 | end 43 | 44 | defp parse_timestamp(ts) do 45 | s = "{YYYY}-{Mshort}-{0D} {0h24}:{m}" 46 | 47 | Timex.Parse.DateTime.Parser.parse!(ts, s) 48 | |> DateTime.from_naive!("Etc/UTC") 49 | end 50 | 51 | defp parse_float(str) do 52 | {float, _} = Float.parse(str) 53 | float 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /test/lowflyingrocks_test.exs: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocksTest do 2 | use ExUnit.Case 3 | alias LowFlyingRocks.{NEO, Formatter, Parser} 4 | 5 | test "parsing json" do 6 | json = File.read!("test/api.json") 7 | neos = Parser.parse(json) 8 | assert Enum.count(neos) == 89 9 | 10 | first = neos |> Enum.at(0) 11 | 12 | assert first.name == "2017 AN4" 13 | assert first.distance == 0.0631318206847728 14 | assert first.speed == 25.7077504402114 15 | assert first.diameter_max == 133.48730920412905 16 | assert first.diameter_min == 59.69733950279317 17 | assert first.url == "https://ssd.jpl.nasa.gov/sbdb.cgi?sstr=2017%20AN4" 18 | 19 | timestamp = DateTime.from_naive!(~N[2017-01-16 10:44:00.000], "Etc/UTC") 20 | assert DateTime.compare(timestamp, first.timestamp) == :eq 21 | end 22 | 23 | test "formatting NEO" do 24 | timestamp = DateTime.from_naive!(~N[2017-01-16 10:44:00.000], "Etc/UTC") 25 | 26 | neo = %NEO{ 27 | name: "2017 AN4", 28 | timestamp: timestamp, 29 | distance: 0.0631318206847728, 30 | speed: 25.7077504402114, 31 | diameter_max: 133.48730920412905, 32 | diameter_min: 59.69733950279317, 33 | url: "http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=2017%20AN4" 34 | } 35 | 36 | {t, s} = Formatter.format(neo) 37 | assert DateTime.compare(t, timestamp) == :eq 38 | 39 | assert s == 40 | "2017 AN4, 60m-133m in diameter, just passed the Earth at 26km/s, missing by 9,440,000km. #{ 41 | neo.url 42 | }" 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/lowflyingrocks/importer.ex: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.Importer do 2 | require Logger 3 | use GenServer 4 | alias LowFlyingRocks.{Parser, Formatter, Tweeter} 5 | 6 | @url "https://ssd-api.jpl.nasa.gov/cad.api?dist-max=0.2" 7 | @timeout 60_000 8 | @pool LowFlyingRocks.Pool 9 | 10 | def start_link(_) do 11 | GenServer.start_link(__MODULE__, :ok, name: __MODULE__) 12 | end 13 | 14 | def init(:ok) do 15 | {:ok, {}, 0} 16 | end 17 | 18 | def handle_info(:timeout, _) do 19 | run() 20 | {:noreply, {}, next_timeout()} 21 | end 22 | 23 | defp run do 24 | case fetch() do 25 | {:ok, body} -> 26 | body |> parse |> format |> schedule |> log 27 | 28 | :error -> 29 | Logger.error("Failed to download NEOs") 30 | end 31 | end 32 | 33 | defp fetch do 34 | Logger.info("Downloading NEOs from JPL API") 35 | 36 | case do_request() do 37 | {:ok, %Finch.Response{status: 200, body: body}} -> {:ok, body} 38 | _ -> :error 39 | end 40 | end 41 | 42 | defp do_request() do 43 | headers = [] 44 | body = "" 45 | 46 | Finch.build(:get, @url, headers, body) 47 | |> Finch.request(@pool, receive_timeout: @timeout) 48 | end 49 | 50 | defp parse(json) do 51 | Parser.parse(json) 52 | end 53 | 54 | defp format(neos) do 55 | neos |> Enum.map(&Formatter.format/1) 56 | end 57 | 58 | defp schedule(tweets) do 59 | Tweeter.set_tweets(LowFlyingRocks.Tweeter, tweets) 60 | end 61 | 62 | defp next_timeout() do 63 | trunc(interval() * 1000) 64 | end 65 | 66 | defp interval do 67 | Application.fetch_env!(:lowflyingrocks, :import_interval) 68 | end 69 | 70 | defp log({:ok, tweets}) do 71 | Logger.info("Scheduled #{Enum.count(tweets)} tweets") 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /lib/lowflyingrocks/tweeter.ex: -------------------------------------------------------------------------------- 1 | defmodule LowFlyingRocks.Tweeter do 2 | require Logger 3 | use GenServer 4 | use Timex 5 | alias Timex.Duration 6 | alias LowFlyingRocks.Mastodon 7 | 8 | def start_link(_) do 9 | GenServer.start_link(__MODULE__, :ok, name: __MODULE__) 10 | end 11 | 12 | def set_tweets(server, tweets) do 13 | GenServer.call(server, {:set_tweets, tweets}) 14 | end 15 | 16 | def init(:ok) do 17 | {:ok, []} 18 | end 19 | 20 | def handle_call({:set_tweets, new_tweets}, _from, _state) do 21 | tweets = new_tweets |> filter_old_tweets |> sort_tweets_by_timestamp 22 | timeout = tweets |> Enum.at(0) |> timeout_for_tweet 23 | {:reply, {:ok, tweets}, tweets, timeout} 24 | end 25 | 26 | def handle_info(:timeout, tweets) do 27 | {tweet, new_tweets} = List.pop_at(tweets, 0) 28 | publish_tweet(tweet) 29 | 30 | timeout = new_tweets |> Enum.at(0) |> timeout_for_tweet 31 | {:noreply, new_tweets, timeout} 32 | end 33 | 34 | defp timeout_for_tweet(nil) do 35 | :infinity 36 | end 37 | 38 | defp timeout_for_tweet({timestamp, _body}) do 39 | timestamp 40 | |> Timex.diff(Timex.now(), :duration) 41 | |> Duration.to_milliseconds(truncate: true) 42 | |> max(0) 43 | end 44 | 45 | defp publish_tweet(nil) do 46 | # no-op 47 | end 48 | 49 | defp publish_tweet({_timestamp, body}) do 50 | Logger.info(body) 51 | 52 | if Application.fetch_env!(:lowflyingrocks, :perform_tweets) do 53 | Mastodon.publish(body) 54 | end 55 | end 56 | 57 | defp filter_old_tweets(tweets) do 58 | now = DateTime.utc_now() 59 | 60 | tweets 61 | |> Enum.reject(fn {t, _} -> 62 | compare_timestamps(t, now) 63 | end) 64 | end 65 | 66 | defp sort_tweets_by_timestamp(tweets) do 67 | tweets 68 | |> Enum.sort(fn {a, _}, {b, _} -> 69 | compare_timestamps(a, b) 70 | end) 71 | end 72 | 73 | defp compare_timestamps(a, b) do 74 | case DateTime.compare(a, b) do 75 | :eq -> true 76 | :lt -> true 77 | :gt -> false 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{ 2 | "castore": {:hex, :castore, "0.1.20", "62a0126cbb7cb3e259257827b9190f88316eb7aa3fdac01fd6f2dfd64e7f46e9", [:mix], [], "hexpm", "a020b7650529c986c454a4035b6b13a328e288466986307bea3aadb4c95ac98a"}, 3 | "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, 4 | "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, 5 | "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, 6 | "extwitter": {:hex, :extwitter, "0.14.0", "5e15c5ea5e6a09baaf03fd5da6de1431eeeca0ef05a9c0f6cc62872e5b8816ed", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:oauther, "~> 1.3", [hex: :oauther, repo: "hexpm", optional: false]}], "hexpm", "5e9bbb491531317062df42ab56ccb8368addb00931b0785c8a5e1d652813b0a8"}, 7 | "finch": {:hex, :finch, "0.14.0", "619bfdee18fc135190bf590356c4bf5d5f71f916adb12aec94caa3fa9267a4bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5459acaf18c4fdb47a8c22fb3baff5d8173106217c8e56c5ba0b93e66501a8dd"}, 8 | "gettext": {:hex, :gettext, "0.20.0", "75ad71de05f2ef56991dbae224d35c68b098dd0e26918def5bb45591d5c8d429", [:mix], [], "hexpm", "1c03b177435e93a47441d7f681a7040bd2a816ece9e2666d1c9001035121eb3d"}, 9 | "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, 10 | "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, 11 | "httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"}, 12 | "hunter": {:hex, :hunter, "0.5.1", "374dc4a800e2c340659657f8875e466075c7ea532e0d7a7787665f272b410150", [:mix], [{:httpoison, "~> 1.5", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 4.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "209b2cca7e4d51d5ff7ee4a0ab6cdc4c6ad23ddd61c9e12ceeee6f7ffbeae9c8"}, 13 | "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, 14 | "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, 15 | "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, 16 | "mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"}, 17 | "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, 18 | "mint": {:hex, :mint, "1.4.2", "50330223429a6e1260b2ca5415f69b0ab086141bc76dc2fbf34d7c389a6675b2", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "ce75a5bbcc59b4d7d8d70f8b2fc284b1751ffb35c7b6a6302b5192f8ab4ddd80"}, 19 | "nimble_options": {:hex, :nimble_options, "0.5.2", "42703307b924880f8c08d97719da7472673391905f528259915782bb346e0a1b", [:mix], [], "hexpm", "4da7f904b915fd71db549bcdc25f8d56f378ef7ae07dc1d372cbe72ba950dce0"}, 20 | "nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"}, 21 | "number": {:hex, :number, "1.0.3", "932c8a2d478a181c624138958ca88a78070332191b8061717270d939778c9857", [:mix], [{:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "dd397bbc096b2ca965a6a430126cc9cf7b9ef7421130def69bcf572232ca0f18"}, 22 | "oauther": {:hex, :oauther, "1.3.0", "82b399607f0ca9d01c640438b34d74ebd9e4acd716508f868e864537ecdb1f76", [:mix], [], "hexpm", "78eb888ea875c72ca27b0864a6f550bc6ee84f2eeca37b093d3d833fbcaec04e"}, 23 | "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, 24 | "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm", "ba8836feea4b394bb718a161fc59a288fe0109b5006d6bdf97b6badfcf6f0f25"}, 25 | "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, 26 | "telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"}, 27 | "timex": {:hex, :timex, "3.7.9", "790cdfc4acfce434e442f98c02ea6d84d0239073bfd668968f82ac63e9a6788d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "64691582e5bb87130f721fc709acfb70f24405833998fabf35be968984860ce1"}, 28 | "tzdata": {:hex, :tzdata, "1.1.2", "45e5f1fcf8729525ec27c65e163be5b3d247ab1702581a94674e008413eef50b", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "cec7b286e608371602318c414f344941d5eb0375e14cfdab605cca2fe66cba8b"}, 29 | "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, 30 | } 31 | -------------------------------------------------------------------------------- /test/api.json: -------------------------------------------------------------------------------- 1 | {"signature":{"source":"NASA/JPL SBDB Close Approach Data API","version":"1.1"},"count":"90","fields":["des","orbit_id","jd","cd","dist","dist_min","dist_max","v_rel","v_inf","t_sigma_f","h"],"data":[["2017 AN4","1","2457769.946893393","2017-Jan-16 10:44","0.0631318206847728","0.0603168352983387","0.0659748293472184","25.7077504402114","25.7061086644673","00:04","23.243"],["2010 AG40","14","2457770.860085108","2017-Jan-17 08:39","0.172325691272328","0.172325146605029","0.172326235941165","22.2824818745047","22.2817879606992","< 00:01","22.1"],["2010 UY7","9","2457771.102734771","2017-Jan-17 14:28","0.134783973531487","0.12745348631196","0.141993901398607","8.210025221163","8.20761701696416","01:00","28.5"],["2016 YC8","11","2457771.694114908","2017-Jan-18 04:40","0.024333045931242","0.0243032225325533","0.0243628627871817","6.66567725909519","6.64922946167938","< 00:01","24.595"],["2015 BB","3","2457771.858482596","2017-Jan-18 08:36","0.0354310136610128","0.0344204624602711","0.0769240478399199","15.8456533733157","15.8409067618949","1_02:45","24.9"],["2017 AP13","3","2457772.195106347","2017-Jan-18 16:41","0.0796108281508225","0.07853684590966","0.0806877056121367","12.9535114854327","12.9509274645436","< 00:01","23.446"],["2013 QC11","18","2457772.683425647","2017-Jan-19 04:24","0.185680084248447","0.185674387137077","0.185685781356612","24.8464011351069","24.8458235864379","< 00:01","21.6"],["2017 AO13","2","2457773.391660572","2017-Jan-19 21:24","0.060804434411075","0.0603139144632501","0.0612936088762296","5.98147971449326","5.97414919635433","00:12","22.982"],["2015 BG4","11","2457774.622037828","2017-Jan-21 02:56","0.0685840893080754","0.0586132113119508","0.0780636779804028","3.87351190343654","3.863469274048","2_00:32","26.3"],["2016 YM1","6","2457776.078169630","2017-Jan-22 13:53","0.106064626472745","0.105456047770611","0.106672843357496","7.18989170081593","7.18639687927711","< 00:01","22.117"],["2017 AE5","1","2457776.747246611","2017-Jan-23 05:56","0.129512427286662","0.122673000936941","0.13639887599314","12.4678978581534","12.4662476587726","00:03","22.04"],["2011 CO14","8","2457777.550669325","2017-Jan-24 01:13","0.0590447818900206","0.0589773318939562","0.0779493098501243","5.7255075422939","5.71762046542478","01:12","25.1"],["2002 LS32","38","2457778.284443508","2017-Jan-24 18:50","0.13843996849737","0.138439366652337","0.138440570344435","21.3376952581852","21.3367932457262","< 00:01","18.2"],["2016 RM20","3","2457778.660262317","2017-Jan-25 03:51","0.185895706213004","0.184696403294836","0.187092779573487","4.67627821172223","4.67321212060529","01:59","26.2"],["7341","257","2457779.035700645","2017-Jan-25 12:51","0.0647091022846649","0.0647090875093768","0.0647091170599693","8.7289947765419","8.72427631800471","< 00:01","16.7"],["2016 YZ","4","2457779.110287746","2017-Jan-25 14:39","0.157601427372936","0.156575676619667","0.158627920615839","11.4617645700664","11.4602894455727","< 00:01","21.379"],["106589","95","2457779.524658886","2017-Jan-26 00:36","0.160164069573129","0.160163730477438","0.160164408668829","16.7194210453873","16.7184260090284","< 00:01","16.0"],["2017 AZ13","1","2457779.532671955","2017-Jan-26 00:47","0.190701625098537","0.185535346055497","0.195904631840664","10.6792253371953","10.6779169242935","00:30","21.891"],["2017 AK3","2","2457779.725556731","2017-Jan-26 05:25","0.0289618246569369","0.0284871307506094","0.0294368078822558","10.7198477253007","10.7112621031669","00:16","24.716"],["2016 YP4","4","2457779.767225560","2017-Jan-26 06:25","0.0325130525606762","0.0324150443037527","0.032610801858096","2.33188765469198","2.29647510345516","00:05","27.016"],["2008 CM20","34","2457783.458145986","2017-Jan-29 23:00","0.112144900894828","0.112144504347947","0.112145297441878","12.8591075734772","12.8572597809774","< 00:01","21.4"],["2017 AX3","2","2457784.163787517","2017-Jan-30 15:56","0.0847666076668337","0.0838540743113898","0.0856800870249391","9.57096312190409","9.56767834073242","00:04","22.897"],["2016 UU80","13","2457784.443896605","2017-Jan-30 22:39","0.111409582169982","0.111397079295012","0.111422084659398","8.44540595753918","8.4425736388938","< 00:01","20.64"],["2008 ER7","27","2457785.286199080","2017-Jan-31 18:52","0.163803396151467","0.163711397440444","0.163895415121665","14.194034538086","14.1928884945119","00:03","20.0"],["2003 EZ16","15","2457785.469120572","2017-Jan-31 23:16","0.168333835928417","0.168332814150165","0.168334857863891","3.56035104231595","3.55590248161982","00:02","22.6"],["2016 CG18","8","2457785.659782364","2017-Feb-01 03:50","0.158594620938732","0.158284183523462","0.158904873712624","8.43072388155578","8.42873086744232","00:02","28.5"],["364136","51","2457785.763087516","2017-Feb-01 06:19","0.0797946545029456","0.079794508250684","0.0797948007553925","23.1252271684553","23.1237831720575","< 00:01","20.2"],["2015 ME116","18","2457786.761390365","2017-Feb-02 06:16","0.178443737247643","0.178441018782244","0.178446455715549","15.7551298150356","15.7541820468563","< 00:01","22.3"],["2015 FJ36","28","2457787.671693640","2017-Feb-03 04:07","0.115792663718944","0.115789671377109","0.115795656061351","12.8981639558788","12.8963797972809","< 00:01","22.1"],["413002","52","2457787.855845075","2017-Feb-03 08:32","0.161487274781264","0.16148716537966","0.161487384183467","3.67923545055077","3.67474818896547","< 00:01","18.7"],["2005 VL1","12","2457788.888590221","2017-Feb-04 09:20","0.023337804423638","0.00904096363930642","0.0406469668733804","5.76983998698922","5.75001854660999","15:00","27.0"],["2015 CE1","5","2457789.223217144","2017-Feb-04 17:21","0.0607504757900503","0.00838609804514134","0.153169674709357","22.443094377311","22.4411400430444","1_12:44","24.6"],["2011 EP51","9","2457789.534937346","2017-Feb-05 00:50","0.0903963728643556","0.0903792459548231","0.090413498851439","6.481453619646","6.47690435319274","< 00:01","24.7"],["2014 BW32","15","2457789.677644166","2017-Feb-05 04:16","0.160840801776726","0.159447326509772","0.162232400323661","12.4092767596757","12.4079417235464","00:14","26.6"],["2013 FK","15","2457790.230551850","2017-Feb-05 17:32","0.0182420366482894","0.018241464038387","0.0182426092589142","8.71909036637123","8.70232219657806","< 00:01","23.3"],["459872","92","2457790.921229023","2017-Feb-06 10:07","0.0595605727405142","0.0595604329070898","0.05956071257392","3.94175566258202","3.93039011513695","< 00:01","23.4"],["2000 UG11","40","2457790.954520377","2017-Feb-06 10:55","0.187072298027795","0.187071474112721","0.187073121969536","10.3359977773173","10.3346196814783","< 00:01","20.4"],["2016 YN1","6","2457792.238212291","2017-Feb-07 17:43","0.0781714806763676","0.0780775609855939","0.0782653613616699","5.9168672310747","5.91110376470518","00:02","23.61"],["2015 BN509","21","2457792.396288410","2017-Feb-07 21:31","0.0416492464191328","0.0416487919309239","0.0416497009092833","19.3716566935068","19.3683539452739","< 00:01","20.6"],["2016 YT8","8","2457792.446008121","2017-Feb-07 22:42","0.179180207555703","0.178264106400209","0.180096897502138","12.8488423422232","12.8476849571378","00:01","20.461"],["2016 YJ4","5","2457793.280118772","2017-Feb-08 18:43","0.0445470903745553","0.0442324584508666","0.0448614919806855","9.89633618343231","9.89029041858363","00:21","23.291"],["2016 YQ8","4","2457794.272919452","2017-Feb-09 18:33","0.189318776478361","0.188458045038626","0.19017796556405","4.73153798164025","4.72856252988677","02:25","23.072"],["2014 DV110","9","2457795.323136386","2017-Feb-10 19:45","0.0253083550733762","0.00224859946978153","0.0753859140877635","7.95036134798681","7.93710805782805","17:21","24.9"],["45P","K162/2","2457795.849546584","2017-Feb-11 08:23","0.083172521378862","0.0831677181788051","0.08317732491104","22.9073974965629","22.9059989723339","< 00:01",null],["2015 QR3","5","2457796.987351455","2017-Feb-12 11:42","0.033711162421311","0.0325032603879042","0.0349391642738082","7.01018773900349","6.99890385404937","00:55","25.7"],["2014 QC3","12","2457797.095927325","2017-Feb-12 14:18","0.0504592815890961","0.0504482428301732","0.0504703230826489","23.0822558978656","23.0799681162526","< 00:01","20.6"],["2016 DJ","16","2457797.527185913","2017-Feb-13 00:39","0.193910272316038","0.193791513637695","0.194029026026098","10.549633404913","10.5483308351748","00:02","25.6"],["2016 CN248","2","2457799.906560110","2017-Feb-15 09:45","0.0959865274958418","0.0933559488947924","0.0986354309386865","10.5829544972658","10.5803311911164","00:11","27.3"],["2016 YX7","2","2457800.695379661","2017-Feb-16 04:41","0.186915208797342","0.186577985062259","0.187252352649756","11.9778995015007","11.9767093325154","00:09","21.392"],["2011 GF3","6","2457801.821811296","2017-Feb-17 07:43","0.192758952686117","0.181737971735745","0.218557650813046","14.474681042708","14.4737260432543","1_01:20","22.4"],["443103","88","2457802.268594895","2017-Feb-17 18:27","0.113489987237795","0.113488850605536","0.11349112386947","14.3106976880222","14.3090570268587","< 00:01","18.0"],["2016 CA138","10","2457802.584924638","2017-Feb-18 02:02","0.0590765988857476","0.0561917219078925","0.0627567352029769","14.2821570766366","14.2789987933026","00:18","23.4"],["2013 DF","5","2457803.200330158","2017-Feb-18 16:48","0.157585141643148","0.1546899798237","0.160488042854896","9.80719347702769","9.80546926557414","08:48","24.6"],["2015 DY198","3","2457803.301726644","2017-Feb-18 19:14","0.185100929183121","0.123504894100088","0.245462833858594","21.6602361155458","21.659571535597","22:51","26.6"],["2015 VL64","4","2457805.315728665","2017-Feb-20 19:35","0.109092385992835","0.107237249019823","0.110943896791644","12.0470032448121","12.0449756767697","00:17","28.3"],["478784","33","2457805.898540211","2017-Feb-21 09:34","0.122433507864337","0.122432930302157","0.122434085425232","3.95058540122901","3.94507283629728","< 00:01","25.5"],["2014 BJ25","15","2457806.078672937","2017-Feb-21 13:53","0.120561752652907","0.112464984979305","0.128471449567618","6.18911783405748","6.18554593323271","15:32","24.4"],["2001 TD","10","2457806.231704817","2017-Feb-21 17:34","0.134351091988292","0.131772445811392","0.13700716420836","9.11364958156081","9.11147322179568","02:46","25.1"],["2016 CO246","8","2457806.587643307","2017-Feb-22 02:06","0.0393715702995135","0.0393254842845857","0.039424092451468","5.41891272664198","5.40640959569685","00:11","25.9"],["2015 YT","3","2457808.467248154","2017-Feb-23 23:13","0.19943878648128","0.197457621395679","0.201413330955508","6.52697963327168","6.52493244120457","13:01","25.8"],["5604","98","2457808.918936700","2017-Feb-24 10:03","0.0335965210257761","0.0335962351891611","0.0335968068949126","11.9435375093354","11.9368954026181","< 00:01","17.2"],["10636","66","2457809.063748030","2017-Feb-24 13:32","0.136153328342356","0.136151844907145","0.136154811801211","14.4350719450388","14.433716176546","< 00:01","17.6"],["2016 EO56","2","2457809.783567240","2017-Feb-25 06:48","0.191574211767855","0.0996300983727044","0.299429320808944","23.9163430592354","23.9157615109023","07:24","23.0"],["2016 TB57","19","2457810.397633156","2017-Feb-25 21:33","0.106089227141909","0.106087183106552","0.106091271155274","1.02783895250455","1.00310617577816","< 00:01","26.1"],["2014 HP4","8","2457810.931236005","2017-Feb-26 10:21","0.0730406894635962","0.0725165495080349","0.0759333936374685","9.26493243731364","9.26099423931142","3_06:49","22.3"],["2016 WG10","6","2457811.069553853","2017-Feb-26 13:40","0.159095148915613","0.159033959112065","0.159156338325034","13.1003912994617","13.0991128241573","00:03","20.869"],["2016 FU12","3","2457811.191773497","2017-Feb-26 16:36","0.0417476383481158","0.0402426981171101","0.0434274386100849","3.88081993077641","3.86433906196379","00:37","26.9"],["2016 WJ7","8","2457811.255792343","2017-Feb-26 18:08","0.105134470700958","0.105082789456827","0.105186147858612","9.29510511657133","9.29237817000099","00:04","21.656"],["252558","48","2457811.586509470","2017-Feb-27 02:05","0.155133317984663","0.155132412839986","0.155134223142471","9.71624407359564","9.71447621155325","< 00:01","20.0"],["2005 QB5","7","2457811.886382610","2017-Feb-27 09:16","0.055956280484863","0.0523334569514341","0.141822951607745","10.8866897844054","10.882315017291","1_00:53","23.7"],["2015 XC352","18","2457813.121456921","2017-Feb-28 14:55","0.13526626106661","0.135262145735222","0.135270376536292","4.01782893941549","4.01292328851021","00:05","25.7"],["2013 ET","28","2457813.204254589","2017-Feb-28 16:54","0.163746046688586","0.163702514314907","0.163789577942467","16.8165138818147","16.8155462323557","< 00:01","23.1"],["2012 DR32","5","2457815.202612967","2017-Mar-02 16:52","0.0068725980782818","0.00580307167970166","0.0358145544118608","16.7182739137273","16.6950678493218","04:08","24.6"],["2011 OJ45","5","2457815.331896996","2017-Mar-02 19:58","0.0793167292267984","0.0701276164654928","0.0882289749995743","8.1129707322299","8.10882903336394","02:52","26.0"],["2016 RZ17","3","2457815.635807825","2017-Mar-03 03:16","0.0778894161394083","0.0753265826748635","0.0805134922001651","15.0519463143578","15.0496734472772","00:48","25.5"],["2000 CE59","58","2457817.364014159","2017-Mar-04 20:44","0.191665713862689","0.191665214261822","0.191666213480762","7.18657746143909","7.18464280311803","< 00:01","20.4"],["2005 EY169","22","2457819.846042622","2017-Mar-07 08:18","0.16117783786062","0.161177300066582","0.16117837565677","14.2549048449857","14.2537451056829","< 00:01","22.1"],["2012 BB124","26","2457820.044607665","2017-Mar-07 13:04","0.19088069070405","0.190880184352671","0.190881197055224","10.1397850172737","10.1384082799195","< 00:01","21.2"],["2014 HB124","11","2457821.105654630","2017-Mar-08 14:32","0.0924993157912559","0.0924223002332038","0.120018105592781","14.2011193987132","14.1990908647812","04:00","23.1"],["2009 EM1","16","2457821.395285335","2017-Mar-08 21:29","0.121417877761771","0.121416129323044","0.121419626269959","11.7615668927717","11.7597009471316","< 00:01","22.9"],["2015 EF","4","2457822.652539294","2017-Mar-10 03:40","0.0483430420508262","0.00580339516053175","0.127506064180142","15.9610419701487","15.9575884330236","1_17:35","26.8"],["2011 YW10","14","2457822.717828698","2017-Mar-10 05:14","0.119742722863429","0.119544369930903","0.119941131400161","16.4662536799376","16.4649022726788","00:02","24.5"],["2008 CA6","10","2457823.139922505","2017-Mar-10 15:21","0.0835877409414677","0.0818026580566779","0.0855136835814638","11.6228504932037","11.6201076033682","02:52","20.7"],["138404","63","2457823.256173359","2017-Mar-10 18:09","0.0666810797516718","0.0666795436048378","0.0666826159227132","7.12473271213837","7.1191220748815","< 00:01","19.1"],["2008 EY68","14","2457823.328444390","2017-Mar-10 19:53","0.137811957092893","0.137790783675257","0.137833131122322","19.7039673324917","19.7029860758897","< 00:01","22.0"],["2012 EQ10","7","2457823.975801030","2017-Mar-11 11:25","0.0445262291530535","0.0228777609421561","0.100519415047121","7.67965158010987","7.67185551571555","2_10:23","25.9"],["2016 EX202","2","2457824.058159024","2017-Mar-11 13:24","0.0527203175250079","0.0373934505602835","0.0705334218859786","10.8691263793448","10.8644755261908","04:12","25.6"],["2002 EM7","15","2457825.108859776","2017-Mar-12 14:37","0.169410550351645","0.156657769591553","0.182055795511989","15.4968794719781","15.4958645284699","03:11","24.4"],["2005 ES70","29","2457827.354503948","2017-Mar-14 20:30","0.0558965553455518","0.0558960469516687","0.0558970637399023","12.0700613022353","12.0661113767478","< 00:01","23.8"],["1998 SL36","25","2457829.062742492","2017-Mar-16 13:30","0.0214334976709151","0.0214290938333473","0.0214379018234235","14.8244741989063","14.8160861125055","< 00:01","20.2"]]} 2 | --------------------------------------------------------------------------------