Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
import Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
Expand Down
4 changes: 2 additions & 2 deletions lib/ex_ical.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ defmodule ExIcal do

alias ExIcal.{Parser,Recurrence,Utils,Event}

@spec parse(String.t) :: [%Event{}]
defdelegate parse(data), to: Parser
@spec parse(String.t, String.t|nil) :: [%Event{}]
defdelegate parse(data, locale \\ nil), to: Parser

@spec add_recurring_events([%Event{}]) :: [%Event{}]
defdelegate add_recurring_events(events), to: Recurrence
Expand Down
35 changes: 14 additions & 21 deletions lib/ex_ical/date_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,54 +67,44 @@ defmodule ExIcal.DateParser do

@type valid_timezone :: String.t | :utc | :local

@spec parse(String.t, valid_timezone | nil) :: %DateTime{}
def parse(data, tzid \\ nil)
@spec parse(String.t, valid_timezone | nil, String.t | nil) :: %DateTime{}
def parse(data, tzid \\ nil, locale \\ nil)

# Date Format: "19690620T201804Z", Timezone: *
def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "T",
hour :: binary-size(2), minutes :: binary-size(2), seconds :: binary-size(2), "Z" >>,
_timezone) do
date = {year, month, day}
time = {hour, minutes, seconds}

{to_integers(date), to_integers(time)}
|> NaiveDateTime.from_erl!()
|> DateTime.from_naive!("Etc/UTC")
end

# Date Format: "19690620T201804", Timezone: nil
def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "T",
hour :: binary-size(2), minutes :: binary-size(2), seconds :: binary-size(2) >>,
nil) do
_timezone, locale) do
date = {year, month, day}
time = {hour, minutes, seconds}

{to_integers(date), to_integers(time)}
|> NaiveDateTime.from_erl!()
#|> Timex.to_datetime(locale || timezone || "Etc/UTC")
|> DateTime.from_naive!("Etc/UTC")
|> maybe_shift_zone(locale)
end

# Date Format: "19690620T201804", Timezone: *
def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "T",
hour :: binary-size(2), minutes :: binary-size(2), seconds :: binary-size(2) >>,
timezone) do
timezone, locale) do
date = {year, month, day}
time = {hour, minutes, seconds}

{to_integers(date), to_integers(time)}
|> Timex.to_datetime(timezone)
|> Timex.to_datetime(locale || timezone || "Etc/UTC")
end

# Date Format: "19690620Z", Timezone: *
def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "Z" >>, _timezone) do
def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2), "Z" >>, _timezone, locale) do
{to_integers({year, month, day}), {0, 0, 0}}
|> Timex.to_datetime()
|> Timex.to_datetime(locale || "Etc/UTC")
end

# Date Format: "19690620", Timezone: *
def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2) >>, _timezone) do
def parse(<< year :: binary-size(4), month :: binary-size(2), day :: binary-size(2) >>, timezone, locale) do
{to_integers({year, month, day}), {0, 0, 0}}
|> Timex.to_datetime()
|> Timex.to_datetime(locale || timezone || "Etc/UTC")
end

@spec to_integers({String.t, String.t, String.t}) :: {integer, integer, integer}
Expand All @@ -125,4 +115,7 @@ defmodule ExIcal.DateParser do
String.to_integer(str3)
}
end

defp maybe_shift_zone(datetime, nil), do: datetime
defp maybe_shift_zone(datetime, timezone), do: DateTime.shift_zone!(datetime, timezone)
end
34 changes: 17 additions & 17 deletions lib/ex_ical/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ defmodule ExIcal.Parser do
```
"""

@spec parse(String.t) :: [%Event{}]
def parse(data) do
@spec parse(String.t, String.t|nil) :: [%Event{}]
def parse(data, locale \\ nil) do
data
|> String.replace(~s"\n\t", ~S"\n")
|> String.replace(~s"\n\x20", ~S"\n")
Expand All @@ -41,37 +41,37 @@ defmodule ExIcal.Parser do
|> Enum.reduce(%{events: []}, fn(line, data) ->
line
|> String.trim()
|> parse_line(data)
|> parse_line(data, locale)
end)
|> Map.get(:events)
end

defp parse_line("BEGIN:VEVENT" <> _, data), do: %{data | events: [%Event{} | data[:events]]}
defp parse_line("DTSTART" <> start, data), do: data |> put_to_map(:start, process_date(start, data[:tzid]))
defp parse_line("DTEND" <> endd, data), do: data |> put_to_map(:end, process_date(endd, data[:tzid]))
defp parse_line("DTSTAMP" <> stamp, data), do: data |> put_to_map(:stamp, process_date(stamp, data[:tzid]))
defp parse_line("SUMMARY:" <> summary, data), do: data |> put_to_map(:summary, process_string(summary))
defp parse_line("DESCRIPTION:" <> description, data), do: data |> put_to_map(:description, process_string(description))
defp parse_line("UID:" <> uid, data), do: data |> put_to_map(:uid, uid)
defp parse_line("RRULE:" <> rrule, data), do: data |> put_to_map(:rrule, process_rrule(rrule, data[:tzid]))
defp parse_line("TZID:" <> tzid, data), do: data |> Map.put(:tzid, tzid)
defp parse_line("CATEGORIES:" <> categories, data), do: data |> put_to_map(:categories, String.split(categories, ","))
defp parse_line(_, data), do: data
defp parse_line("BEGIN:VEVENT" <> _, data, _locale), do: %{data | events: [%Event{} | data[:events]]}
defp parse_line("DTSTART" <> start, data, locale), do: data |> put_to_map(:start, process_date(start, data[:tzid], locale))
defp parse_line("DTEND" <> endd, data, locale), do: data |> put_to_map(:end, process_date(endd, data[:tzid], locale))
defp parse_line("DTSTAMP" <> stamp, data, locale), do: data |> put_to_map(:stamp, process_date(stamp, data[:tzid], locale))
defp parse_line("SUMMARY:" <> summary, data, _locale), do: data |> put_to_map(:summary, process_string(summary))
defp parse_line("DESCRIPTION:" <> description, data, _locale), do: data |> put_to_map(:description, process_string(description))
defp parse_line("UID:" <> uid, data, _locale), do: data |> put_to_map(:uid, uid)
defp parse_line("RRULE:" <> rrule, data, _locale), do: data |> put_to_map(:rrule, process_rrule(rrule, data[:tzid]))
defp parse_line("TZID:" <> tzid, data, _locale), do: data |> Map.put(:tzid, tzid)
defp parse_line("CATEGORIES:" <> categories, data, _locale), do: data |> put_to_map(:categories, String.split(categories, ","))
defp parse_line(_, data, _locale), do: data

defp put_to_map(%{events: [event | events]} = data, key, value) do
updated_event = %{event | key => value}
%{data | events: [updated_event | events]}
end
defp put_to_map(data, _key, _value), do: data

defp process_date(":" <> date, tzid), do: DateParser.parse(date, tzid)
defp process_date(";" <> date, _) do
defp process_date(":" <> date, tzid, locale), do: DateParser.parse(date, tzid, locale)
defp process_date(";" <> date, _, locale) do
[timezone, date] = date |> String.split(":")
timezone = case timezone do
"TZID=" <> timezone -> timezone
_ -> nil
end
DateParser.parse(date, timezone)
DateParser.parse(date, timezone, locale)
end

defp process_rrule(rrule, tzid) do
Expand Down
4 changes: 2 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule ExIcal.Mixfile do

def project do
[app: :ex_ical,
version: "0.2.0",
version: "0.3.0",
elixir: "~> 1.4",
description: "ICalendar parser.",
package: package(),
Expand Down Expand Up @@ -33,7 +33,7 @@ defmodule ExIcal.Mixfile do
defp deps() do
[
{:ex_doc, "~> 0.16", only: :dev, runtime: false},
{:credo, "~> 0.9.1", only: [:dev, :test], runtime: false},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
{:timex, "~> 3.1"}
]
end
Expand Down
42 changes: 25 additions & 17 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
"credo": {:hex, :credo, "0.9.2", "841d316612f568beb22ba310d816353dddf31c2d94aa488ae5a27bb53760d0bf", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.16.1", "b4b8a23602b4ce0e9a5a960a81260d1f7b29635b9652c67e95b0c2f7ccee5e81", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
"gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.12.1", "8bf2d0e11e722e533903fe126e14d6e7e94d9b7983ced595b75f532e04b7fdc7", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.1", "cbc3b2fa1645113267cc59c760bafa64b2ea0334635ef06dbac8801e42f7279c", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"certifi": {:hex, :certifi, "2.14.0", "ed3bef654e69cde5e6c022df8070a579a79e8ba2368a00acf3d75b82d9aceeed", [:rebar3], [], "hexpm", "ea59d87ef89da429b8e905264fdec3419f84f2215bb3d81e07a18aac919026c3"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"credo": {:hex, :credo, "1.7.11", "d3e805f7ddf6c9c854fd36f089649d7cf6ba74c42bc3795d587814e3c9847102", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "56826b4306843253a66e47ae45e98e7d284ee1f95d53d1612bb483f88a8cf219"},
"earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm", "59514c4a207f9f25c5252e09974367718554b6a0f41fe39f7dc232168f9cb309"},
"earmark_parser": {:hex, :earmark_parser, "1.4.43", "34b2f401fe473080e39ff2b90feb8ddfeef7639f8ee0bbf71bb41911831d77c5", [:mix], [], "hexpm", "970a3cd19503f5e8e527a190662be2cee5d98eed1ff72ed9b3d1a3d466692de8"},
"ex_doc": {:hex, :ex_doc, "0.37.3", "f7816881a443cd77872b7d6118e8a55f547f49903aef8747dbcb345a75b462f9", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "e6aebca7156e7c29b5da4daa17f6361205b2ae5f26e5c7d8ca0d3f7e18972233"},
"expo": {:hex, :expo, "1.1.0", "f7b9ed7fb5745ebe1eeedf3d6f29226c5dd52897ac67c0f8af62a07e661e5c75", [:mix], [], "hexpm", "fbadf93f4700fb44c331362177bdca9eeb8097e8b0ef525c9cc501cb9917c960"},
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},
"gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"},
"hackney": {:hex, :hackney, "1.23.0", "55cc09077112bcb4a69e54be46ed9bc55537763a96cd4a80a221663a7eafd767", [:rebar3], [{:certifi, "~> 2.14.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", "6cd1c04cd15c81e5a493f167b226a15f0938a84fc8f0736ebe4ddcab65c0b44e"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"},
"makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"},
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
"poison": {:hex, :poison, "6.0.0", "9bbe86722355e36ffb62c51a552719534257ba53f3271dacd20fbbd6621a583a", [:mix], [{:decimal, "~> 2.1", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "bb9064632b94775a3964642d6a78281c07b7be1319e0016e1643790704e739a2"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
"ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.6", "45866d958d9ae51cfe8fef0050ab8054d25cba23ace43b88046092aa2c714645", [:make], []},
"timex": {:hex, :timex, "3.3.0", "e0695aa0ddb37d460d93a2db34d332c2c95a40c27edf22fbfea22eb8910a9c8d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"tzdata": {:hex, :tzdata, "0.5.16", "13424d3afc76c68ff607f2df966c0ab4f3258859bbe3c979c9ed1606135e7352", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
"timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"},
"tzdata": {:hex, :tzdata, "1.1.3", "b1cef7bb6de1de90d4ddc25d33892b32830f907e7fc2fccd1e7e22778ab7dfbc", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "d4ca85575a064d29d4e94253ee95912edfb165938743dbf002acdf0dcecb0c28"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
}
Loading