title fix

title fix

<a href="https://steemit.com/@<%= @post.author %>/<%= @post.permlink %>"><%= @post.title %>

Author: <a href="https://beyondboinc.net/authors/<%= @post.author %>/"><%= @post.author %>

      <%= raw(@post.body) %>

		  Home
		  /

Author: <a href="https://beyondboinc.net/authors/<%= @post.author %>/"><%= @post.author %>

		  /

<a href="https://steemit.com/@<%= @post.author %>/<%= @post.permlink %>"><%= @post.permlink %>

<a href="https://steemit.com/@<%= @post.author %>/<%= @post.permlink %>"><%= @post.permlink %>

Author: <a href="https://beyondboinc.net/authors/<%= @post.author %>/"><%= @post.author %>

      <%= raw(@post.body) %>

		  Home
		  /
		  Author
		  /

<a href="https://beyondboinc.net/authors/<%= @post.author %>/"><%= @post.author %>

		  /

<a href="https://steemit.com/@<%= @post.author %>/<%= @post.permlink %>"><%= @post.permlink %>


improve flash notifications styling

improve flash notifications styling

<!DOCTYPE html>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="">
  <meta name="author" content="">
  <title>Glasnost: <%= naive_translate("head title", @conn.assigns[:lang])%></title>
  <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.9/semantic.min.css"></link>

          <img class="logo" src="/images/<%=naive_image_chooser("logo", @conn.assigns[:lang])%>">

        <%=naive_translate("home", @conn.assigns[:lang])%>

        <a href="/authors/<%=@conn.assigns[:about_blog_author]%>/<%=@conn.assigns[:about_blog_permlink]%>" class="item"><%=naive_translate("about", @conn.assigns[:lang])%>
        <a href="<%=if @conn.assigns[:lang] == "ru", do: "https://golos.io", else: "https://steemit.com"%>" class="item"><%=naive_translate("about_steemlike_chain", @conn.assigns[:lang])%>

        <%= if get_flash(@conn, :info) do %>

<%= get_flash(@conn, :info) %>

        <% end %>
        <%= if get_flash(@conn, :error) do %>

<%= get_flash(@conn, :error) %>

        <% end %>

      <%= render @view_module, @view_template, assigns %>


Remove hardcoded url from twitter card endpoint

<!DOCTYPE html>

    <title>
      <%= page_title(assigns) %> - Today I Learned
    </title>

    <meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>">

    <meta name="format-detection" content="telephone=no">
    <meta name="description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day.">

    <meta itemprop="name" content="Today I Learned">
    <meta itemprop="brand" content="Today I Learned">
    <meta itemprop="description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day.">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@hashrockettil">
    <meta name="twitter:creator" content="@hashrockettil">
    <meta name="twitter:title" content="Today I Learned: a Hashrocket Project">
    <meta name="twitter:description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day. Posts have a 200-word limit, and posting is open to any Rocketeer as well as select friends of the team. We hope you enjoy learning along with us.">
    <meta name="twitter:image" content=<%= Tilex.Web.Endpoint.static_url() <> "/assets/til_twittercard.png" %>>

    <link href='//fonts.googleapis.com/css?family=Raleway:700,900' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Lora:400,700italic,700,400italic' rel='stylesheet' type='text/css'>
    <link rel="alternate feed" type="application/rss+xml" title="Today I Learned" href="/rss">

    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
    <%= if assigns[:canonical_url] do %>
      <link rel="canonical" href="<%= @canonical_url %>">
    <% end %>

    <%= if developer = Guardian.Plug.current_resource(@conn) do %>

 <%= link(developer.username, to: developer_path(@conn, :show, developer)) %>

 <%= link("Sign Out", to: auth_path(@conn, :delete), method: :delete) %>

 <%= link("Create Post", to: post_path(@conn, :new)) %>

 <%= link("Profile", to: developer_path(@conn, :edit)) %>

    <% end %>

Today I Learned

          A Hashrocket project

            Follow on Twitter

      <%= if message = get_flash(@conn, :info) do %>

          <%= message %>

      <% end %>

      <%= render @view_module, @view_template, assigns %>

          <%= link("search", to: "#", class: "site_nav__link") %>

            <%= form_tag post_path(@conn, :index), method: :get do %>
              <input type="search" name="q" id="q">
              <%= submit "Search" %>
            <% end %>

          <%= link("?", to: "#", class: "site_nav__link") %>

              Today I Learned is an open-source project by

                Hashrocket

              that exists to catalogue the sharing & accumulation of knowledge
              as it happens day-to-day. Posts have a 200-word limit, and
              posting is open to any Rocketeer as well as selected friends of
              Hashrocket. We hope you enjoy learning along with us.

                  <%= link("/hashrockettil", to: "https://twitter.com/hashrockettil", class: "social_twitter") %>

                  <%= link("/hashrocket/tilex", to: "https://github.com/hashrocket/tilex", class: "social_github") %>

          <%= link("Statistics", to: "/statistics", class: "site_nav__link") %>

            <%= link("Twitter", to: "https://twitter.com/hashrockettil", class: "site_nav__link") %>

            <%= link("Surprise Me", to: "/random", class: "site_nav__link", rel: "nofollow") %>

    <%= if Application.get_env(:tilex, :ga_identifier) do %>

    <% end %>

<!DOCTYPE html>

    <title>
      <%= page_title(assigns) %> - Today I Learned
    </title>

    <meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>">

    <meta name="format-detection" content="telephone=no">
    <meta name="description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day.">

    <meta itemprop="name" content="Today I Learned">
    <meta itemprop="brand" content="Today I Learned">
    <meta itemprop="description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day.">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@hashrockettil">
    <meta name="twitter:creator" content="@hashrockettil">
    <meta name="twitter:title" content="Today I Learned: a Hashrocket Project">
    <meta name="twitter:description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day. Posts have a 200-word limit, and posting is open to any Rocketeer as well as select friends of the team. We hope you enjoy learning along with us.">
    <meta name="twitter:image" content="https://til.hashrocket.com/assets/til_twittercard.png">

    <link href='//fonts.googleapis.com/css?family=Raleway:700,900' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Lora:400,700italic,700,400italic' rel='stylesheet' type='text/css'>
    <link rel="alternate feed" type="application/rss+xml" title="Today I Learned" href="/rss">

    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
    <%= if assigns[:canonical_url] do %>
      <link rel="canonical" href="<%= @canonical_url %>">
    <% end %>

    <%= if developer = Guardian.Plug.current_resource(@conn) do %>

 <%= link(developer.username, to: developer_path(@conn, :show, developer)) %>

 <%= link("Sign Out", to: auth_path(@conn, :delete), method: :delete) %>

 <%= link("Create Post", to: post_path(@conn, :new)) %>

 <%= link("Profile", to: developer_path(@conn, :edit)) %>

    <% end %>

Today I Learned

          A Hashrocket project

            Follow on Twitter

      <%= if message = get_flash(@conn, :info) do %>

          <%= message %>

      <% end %>

      <%= render @view_module, @view_template, assigns %>

          <%= link("search", to: "#", class: "site_nav__link") %>

            <%= form_tag post_path(@conn, :index), method: :get do %>
              <input type="search" name="q" id="q">
              <%= submit "Search" %>
            <% end %>

          <%= link("?", to: "#", class: "site_nav__link") %>

              Today I Learned is an open-source project by

                Hashrocket

              that exists to catalogue the sharing & accumulation of knowledge
              as it happens day-to-day. Posts have a 200-word limit, and
              posting is open to any Rocketeer as well as selected friends of
              Hashrocket. We hope you enjoy learning along with us.

                  <%= link("/hashrockettil", to: "https://twitter.com/hashrockettil", class: "social_twitter") %>

                  <%= link("/hashrocket/tilex", to: "https://github.com/hashrocket/tilex", class: "social_github") %>

          <%= link("Statistics", to: "/statistics", class: "site_nav__link") %>

            <%= link("Twitter", to: "https://twitter.com/hashrockettil", class: "site_nav__link") %>

            <%= link("Surprise Me", to: "/random", class: "site_nav__link", rel: "nofollow") %>

    <%= if Application.get_env(:tilex, :ga_identifier) do %>

    <% end %>


require name phone email

require name phone email

<% candidate = candidate_of(@event.tags) %>
<% donate_url = get_donate_url(candidate) %>

<%= if @mobile do %>

<% else %>

<% end %>
  <%= if @event != nil do %>

 <%= @event.title %>

         RSVP Now
        <%= if donate_url do %>
          <a class="button button-info" href="<%= donate_url %>"> Donate
        <% end %>

      <%= raw(scrub(@event.description)) %>

    <%= if @event.instructions != nil and @event.instructions != "" do %>

        <%= raw(scrub(@event.instructions)) %>

    <% end %>

 When

 <%= @event.date_line %>

 Where

        <%= if @event.location.public do %>

 <%= @event.location.address_lines |> List.first() %>

 <%= @event.location.locality %> <%= @event.location.region %>

        <% else %>

 The address is hidden to protect the privacy of the host. You will find out when you RSVP!

        <% end %>

 Contact

 <%= @event.contact.name %>

 <a href="mailto:<%= @event.contact.email_address %>"> <%= @event.contact.email_address %>

        <%= if @event.contact.public do %>

 <%= @event.contact.phone_number %>

        <% end %>

      <%= if assigns[:person] == nil do %>

 RSVP: Who is coming?

        <form name="rsvp" method="post" action="/events/<%= @event.name %>">
          <input type="hidden" name="_csrf_token" value="<%= csrf_token() %>" />

               Name

              <input name="name" type="text" required="required"/>

               Email

              <input name="email" type="email" required="required"/>

               Phone

              <input name="phone" type="tel" required="required"/>

               Address

              <input name="address" type="text" placeholder="1600 Pennsylvania Avenue" style="width: 100%;"/>

               Zip Code

              <input name="zip" type="text" placeholder="20500" style="width: 100%;"/>

               City

              <input name="city" type="text" placeholder="Washington" style="width: 100%;"/>

               State

              <input name="state" type="text" placeholder="DC" style="width: 100%;"/>

            <button type="submit"> I'm coming! </button>

        </form>

More Events

      <% else %>

 Thanks for rsvping!

 We'll be in touch soon with details and reminders.

 In the meantime, share the event and try to get some of your friends to come!

        <button onclick="refresh()"> RSVP A Different Person </button>

      <% end %>

  <% else %>

        Hm, it seems as if you've either stumbled upon an event that doesn't exist
        or is in the past.

        Go back to our events map to find an event in the future here.

More Events

  <% end %>

<% candidate = candidate_of(@event.tags) %>
<% donate_url = get_donate_url(candidate) %>

<%= if @mobile do %>

<% else %>

<% end %>
  <%= if @event != nil do %>

 <%= @event.title %>

         RSVP Now
        <%= if donate_url do %>
          <a class="button button-info" href="<%= donate_url %>"> Donate
        <% end %>

      <%= raw(scrub(@event.description)) %>

    <%= if @event.instructions != nil and @event.instructions != "" do %>

        <%= raw(scrub(@event.instructions)) %>

    <% end %>

 When

 <%= @event.date_line %>

 Where

        <%= if @event.location.public do %>

 <%= @event.location.address_lines |> List.first() %>

 <%= @event.location.locality %> <%= @event.location.region %>

        <% else %>

 The address is hidden to protect the privacy of the host. You will find out when you RSVP!

        <% end %>

 Contact

 <%= @event.contact.name %>

 <a href="mailto:<%= @event.contact.email_address %>"> <%= @event.contact.email_address %>

        <%= if @event.contact.public do %>

 <%= @event.contact.phone_number %>

        <% end %>

      <%= if assigns[:person] == nil do %>

 RSVP: Who is coming?

        <form name="rsvp" method="post" action="/events/<%= @event.name %>">
          <input type="hidden" name="_csrf_token" value="<%= csrf_token() %>" />

               Name

              <input name="name" type="text" />

               Email

              <input name="email" type="email" />

               Phone

              <input name="phone" type="tel" />

               Address

              <input name="address" type="text" placeholder="1600 Pennsylvania Avenue" style="width: 100%;"/>

               Zip Code

              <input name="zip" type="text" placeholder="20500" style="width: 100%;"/>

               City

              <input name="city" type="text" placeholder="Washington" style="width: 100%;"/>

               State

              <input name="state" type="text" placeholder="DC" style="width: 100%;"/>

            <button type="submit"> I'm coming! </button>

        </form>

More Events

      <% else %>

 Thanks for rsvping!

 We'll be in touch soon with details and reminders.

 In the meantime, share the event and try to get some of your friends to come!

        <button onclick="refresh()"> RSVP A Different Person </button>

      <% end %>

  <% else %>

        Hm, it seems as if you've either stumbled upon an event that doesn't exist
        or is in the past.

        Go back to our events map to find an event in the future here.

More Events

  <% end %>


Add stores links on index page

Add stores links on index page

Band Indigo — instrumental rock from Siberia

Get our music on iTunes, Google play or Amazon.


Escape search string in presentation

Escape search string in presentation

Fixes #35

  <%= if logged_in?(@conn) do %>
    <%= if @page_number == 1 do %>
      <%= if @just_signed_in do %>

          <%= render "form.html", current_user: current_user(@conn),
                                  changeset: @changeset,
                                  action: posting_path(@conn, :create),
                                  conn: @conn,
                                  posting: nil,
                                  css_class: "new-post",
                                  editing?: false %>

      <% else %>

            <div class="image" style="background-image: url(<%= raw avatar_path(current_user(@conn).user_name) %>)">

           Submit a post

          <%= render "form.html", current_user: current_user(@conn),
                                  changeset: @changeset,
                                  action: posting_path(@conn, :create),
                                  conn: @conn,
                                  posting: nil,
                                  css_class: "new-post",
                                  editing?: false %>

      <% end %>
    <% else %>

          <div class="image" style="background-image: url(<%= raw avatar_path(current_user(@conn).user_name) %>)">

         Submit another post

    <% end %>
  <% else %>

       Sign in and post

  <% end %>

  <%= if @searching? do %>
    Search results for <%= @search_query %>
    clear
  <% end %>

  <%= for {posting, index} <- Enum.with_index(@postings) do %>
    <%= render ElixirStatus.PostingView, "posting.html", conn: @conn,
                posting: posting,
                belongs_to_me?: ElixirStatus.Auth.belongs_to_current_user?(@conn, posting),
                just_created_by_me?: @created_posting == posting
                %>
    <%= if index == 2 do %>
      <%= render ElixirStatus.SharedView, "promo_credo.html", conn: @conn %>
    <% end %>
  <% end %>

  <%= if @page_number > 1 do %>
    <%= link "Previous", to: posting_path(@conn, :index, page: @page_number - 1), class: "pagination-item older" %>
  <% else %>
    Previous
  <% end %>
  <%= if @page_number < @total_pages do %>
    <%= link "Next", to: posting_path(@conn, :index, page: @page_number + 1), class: "pagination-item newer" %>
  <% else %>
    Next
  <% end %>

  <form method="get" action="/">
    <input type="text" name="q"/ placeholder="Search ...">
  </form>

  <%= if logged_in?(@conn) do %>
    <%= if @page_number == 1 do %>
      <%= if @just_signed_in do %>

          <%= render "form.html", current_user: current_user(@conn),
                                  changeset: @changeset,
                                  action: posting_path(@conn, :create),
                                  conn: @conn,
                                  posting: nil,
                                  css_class: "new-post",
                                  editing?: false %>

      <% else %>

            <div class="image" style="background-image: url(<%= raw avatar_path(current_user(@conn).user_name) %>)">

           Submit a post

          <%= render "form.html", current_user: current_user(@conn),
                                  changeset: @changeset,
                                  action: posting_path(@conn, :create),
                                  conn: @conn,
                                  posting: nil,
                                  css_class: "new-post",
                                  editing?: false %>

      <% end %>
    <% else %>

          <div class="image" style="background-image: url(<%= raw avatar_path(current_user(@conn).user_name) %>)">

         Submit another post

    <% end %>
  <% else %>

       Sign in and post

  <% end %>

  <%= if @searching? do %>
    <%= sanitized_inline_markdown "Search results for #{@search_query}" %>
    clear
  <% end %>

  <%= for {posting, index} <- Enum.with_index(@postings) do %>
    <%= render ElixirStatus.PostingView, "posting.html", conn: @conn,
                posting: posting,
                belongs_to_me?: ElixirStatus.Auth.belongs_to_current_user?(@conn, posting),
                just_created_by_me?: @created_posting == posting
                %>
    <%= if index == 2 do %>
      <%= render ElixirStatus.SharedView, "promo_credo.html", conn: @conn %>
    <% end %>
  <% end %>

  <%= if @page_number > 1 do %>
    <%= link "Previous", to: posting_path(@conn, :index, page: @page_number - 1), class: "pagination-item older" %>
  <% else %>
    Previous
  <% end %>
  <%= if @page_number < @total_pages do %>
    <%= link "Next", to: posting_path(@conn, :index, page: @page_number + 1), class: "pagination-item newer" %>
  <% else %>
    Next
  <% end %>

  <form method="get" action="/">
    <input type="text" name="q"/ placeholder="Search ...">
  </form>


fix: typos

fix: typos

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="alternate" type="application/atom+xml" title="Articles" href="<%= article_url(@conn, :index) %>.atom">
    <link rel="alternate" type="application/atom+xml" title="Notes" href="<%= note_url(@conn, :index) %>.atom">
    <link rel="alternate" type="application/atom+xml" title="Pictures" href="<%= picture_url(@conn, :index) %>.atom">
    <link rel="alternate" type="application/atom+xml" title="Combined" href="<%= page_url(@conn, :index) %>whatsnew.atom">

    <link rel="apple-touch-icon" href="<%= static_path(@conn, "/images/christian-kruse.png") %>">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">

    <link rel="author" href="<%= page_path(@conn, :index) %>humans.txt" type="text/plain">

    <%= if assigns[:mention_link] do %>
      <link rel="webmention" href="<%= @mention_link %>">
    <% end %>

    <meta name="description" content="<%= description(@conn, assigns) %>">
    <meta name="author" content="Christian Kruse">

    <title><%= page_title(@conn, assigns) %></title>

    <meta property="og:title" content="<%= page_title(@conn, assigns) %>">
    <meta property="og:type" content="website">
    <meta property="og:image" content="<%= static_path(@conn, "/images/christian-kruse.png") %>">

    <meta name="twitter:card" content="summary">
    <meta name="twitter:site" content="@cjk101010">
    <meta name="twitter:domain" content="wwwtech.de">

    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">

<%= link "WWWTech", to: page_path(@conn, :index) %>

Free/Libre Open Source Software by <%= link "Christian Kruse", to: page_path(@conn, :about) %>

        <%= if get_flash(@conn, :info) do %>
<%= get_flash(@conn, :info) %>
<% end %>
        <%= if get_flash(@conn, :error) do %>
<%= get_flash(@conn, :error) %>
<% end %>

        <%= render @view_module, @view_template, assigns %>

<%= link "Main", to: page_path(@conn, :index) %>

<%= link "Software", to: page_path(@conn, :software) %>

<%= link "Articles", to: article_path(@conn, :index) %>

<%= link "Notes", to: note_path(@conn, :index) %>

<%= link "Pictures", to: picture_path(@conn, :index) %>

          <%= if logged_in?(@conn) do %>

<%= link "Logout", to: session_path(@conn, :delete), method: :delete %>

          <% end %>

<%= link "Imprint", to: page_path(@conn, :about), rel: "me" %>

<%= link "cjk@defunct.ch", to: "xmpp:cjk@defunct.ch", rel: "me" %> via Jabber

<%= link "cjk@defunct.ch", to: "mailto:cjk@defunct.ch", rel: "me" %> via Email

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="alternate" type="application/atom+xml" title="Articles" href="<%= article_url(@conn, :index) %>.atom">
    <link rel="alternate" type="application/atom+xml" title="Notes" href="<%= note_url(@conn, :index) %>.atom">
    <link rel="alternate" type="application/atom+xml" title="Pictures" href="<%= picture_url(@conn, :index) %>.atom">
    <link rel="alternate" type="application/atom+xml" title="Combined" href="<%# atom_feed_url(format: :atom) %>">

    <link rel="apple-touch-icon" href="<%= static_path(@conn, "/images/christian-kruse.png") %>">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">

    <link rel="author" href="<%= page_path(@conn, :index) %>humans.txt" type="text/plain">

    <% if assigns[:mention_link] do %>
      <link rel="webmention" href="<%= @mention_link %>">
    <% end %>

    <meta name="description" content="<%= description(@conn, assigns) %>">
    <meta name="author" content="Christian Kruse">

    <title><%= page_title(@conn, assigns) %></title>

    <meta property="og:title" content="<%= page_title(@conn, assigns) %>">
    <meta property="og:type" content="website">
    <meta property="og:image" content="<%= static_path(@conn, "/images/christian-kruse.png") %>">

    <meta name="twitter:card" content="summary">
    <meta name="twitter:site" content="@cjk101010">
    <meta name="twitter:domain" content="wwwtech.de">

    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">

<%= link "WWWTech", to: page_path(@conn, :index) %>

Free/Libre Open Source Software by <%= link "Christian Kruse", to: page_path(@conn, :about) %>

        <%= if get_flash(@conn, :info) do %>
<%= get_flash(@conn, :info) %>
<% end %>
        <%= if get_flash(@conn, :error) do %>
<%= get_flash(@conn, :error) %>
<% end %>

          <%= render @view_module, @view_template, assigns %>

<%= link "Main", to: page_path(@conn, :index) %>

<%= link "Software", to: page_path(@conn, :software) %>

<%= link "Articles", to: article_path(@conn, :index) %>

<%= link "Notes", to: note_path(@conn, :index) %>

<%= link "Pictures", to: picture_path(@conn, :index) %>

          <%= if logged_in?(@conn) do %>

<%= link "Logout", to: session_path(@conn, :delete), method: :delete %>

          <% end %>

<%= link "Imprint", to: page_path(@conn, :about), rel: "me" %>

<%= link "cjk@defunct.ch", to: "xmpp:cjk@defunct.ch", rel: "me" %> via Jabber

<%= link "cjk@defunct.ch", to: "mailto:cjk@defunct.ch", rel: "me" %> via Email


Updated app index's metadata to list elm as frontend

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Animu v3: Phenoix + Elm">
    <meta name="author" content="Ethan Larkham">

    <title>Animu</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/main.css") %>">
  </head>

  <body>
    <main id="root-container" role="main"></main>
    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
  </body>
</html>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Animu v3: Phenoix + React/Redux">
    <meta name="author" content="Ethan Larkham">

    <title>Animu</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/main.css") %>">
  </head>

  <body>
    <main id="root-container" role="main"></main>
    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
  </body>
</html>


add "."

add "."

<%= gettext "Welcome to %{name}", name: "Classlab.org!" %>

A simple way
to share your knowledge.

    <%= for event <- @events do %>

            <%= link event.name, to: event_path(@conn, :show, event) %>

            <%= if current_user(@conn) && has_permission?(@current_memberships, [1, 2, 3], event) do %>
              attending
            <% end %>

<%= "#{l(event.starts_at)} - #{l(event.ends_at)}" %>

    <% end %>
    <%= if length(@events) == 0 do %>

            No public events in the near future.

    <% end %>

<%= gettext "Welcome to %{name}", name: "Classlab.org!" %>

A simple way
to share your knowledge.

    <%= for event <- @events do %>

            <%= link event.name, to: event_path(@conn, :show, event) %>

            <%= if current_user(@conn) && has_permission?(@current_memberships, [1, 2, 3], event) do %>
              attending
            <% end %>

<%= "#{l(event.starts_at)} - #{l(event.ends_at)}" %>

    <% end %>
    <%= if length(@events) == 0 do %>

            No public events in the near future

    <% end %>


Save player_id in agent

Save player_id in agent


Add version info at bottom of home page.

ReadErl

An RSS feed aggregator written in Elixir/Phoenix

I'm working on it: github.com/billstclair/readerl

  <%= :erlang.system_info(:system_version) %>

  Elixir: <%= System.version %>, Phoenix: <%= Phoenix.Mixfile.project[:version] %>


Remove redundant a tag

Remove redundant a tag

  <%= for post <- @posts do %>

            <%= link(post.title, to: "#") %>

          <%= post.body %>

              <%= link(display_date(post), to: "#", class: "post__permalink") %>

  <% end %>

  <%= for post <- @posts do %>

            <%= link(post.title, to: "#") %>

          <%= post.body %>

                <%= link(display_date(post), to: "#") %>

  <% end %>


Update GraphiQL styles and React version

<!--
The request to this GraphQL server provided the header "Accept: text/html"
and as a result has been presented GraphiQL - an in-browser IDE for
exploring GraphQL.

If you wish to receive JSON, provide the header "Accept: application/json" or
add "&raw" to the end of the URL within a browser.
-->
<!DOCTYPE html>
<html>
<head>
  <style>
    html, body {
      height: 100%;
      margin: 0;
      overflow: hidden;
      width: 100%;
    }
  </style>
  <link href="//cdn.jsdelivr.net/graphiql/<%= graphiql_version %>/graphiql.css" rel="stylesheet" />
  <script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
  <script src="//cdn.jsdelivr.net/react/0.14.7/react.min.js"></script>
  <script src="//cdn.jsdelivr.net/react/0.14.7/react-dom.min.js"></script>
  <script src="//cdn.jsdelivr.net/graphiql/<%= graphiql_version %>/graphiql.min.js"></script>
</head>
<body>
  <script>
    // Collect the URL parameters
    var parameters = {};
    window.location.search.substr(1).split('&').forEach(function (entry) {
      var eq = entry.indexOf('=');
      if (eq >= 0) {
        parameters[decodeURIComponent(entry.slice(0, eq))] =
          decodeURIComponent(entry.slice(eq + 1));
      }
    });

    // Produce a Location query string from a parameter object.
    function locationQuery(params) {
      return '?' + Object.keys(params).map(function (key) {
        return encodeURIComponent(key) + '=' +
          encodeURIComponent(params[key]);
      }).join('&');
    }

    // Derive a fetch URL from the current URL, sans the GraphQL parameters.
    var graphqlParamNames = {
      query: true,
      variables: true,
      operationName: true
    };

    var otherParams = {};
    for (var k in parameters) {
      if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
        otherParams[k] = parameters[k];
      }
    }
    var fetchURL = locationQuery(otherParams);

    // Defines a GraphQL fetcher using the fetch API.
    function graphQLFetcher(graphQLParams) {
      return fetch(fetchURL, {
        method: 'post',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(graphQLParams),
        credentials: 'include',
      }).then(function (response) {
        return response.json();
      });
    }

    // When the query and variables string is edited, update the URL bar so
    // that it can be easily shared.
    function onEditQuery(newQuery) {
      parameters.query = newQuery;
      updateURL();
    }

    function onEditVariables(newVariables) {
      parameters.variables = newVariables;
      updateURL();
    }

    function updateURL() {
      history.replaceState(null, null, locationQuery(parameters));
    }

    // Render <GraphiQL /> into the body.
    React.render(
      React.createElement(GraphiQL, {
        fetcher: graphQLFetcher,
        onEditQuery: onEditQuery,
        onEditVariables: onEditVariables,
        query: '<%= query %>',
        response: '<%= result %>',
        variables: '<%= variables %>'
      }),
      document.body
    );
  </script>
</body>
</html>

<!--
The request to this GraphQL server provided the header "Accept: text/html"
and as a result has been presented GraphiQL - an in-browser IDE for
exploring GraphQL.

If you wish to receive JSON, provide the header "Accept: application/json" or
add "&raw" to the end of the URL within a browser.
-->
<!DOCTYPE html>
<html>
<head>
  <link href="//cdn.jsdelivr.net/graphiql/<%= graphiql_version %>/graphiql.css" rel="stylesheet" />
  <script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
  <script src="//cdn.jsdelivr.net/react/0.14.2/react.min.js"></script>
  <script src="//cdn.jsdelivr.net/react/0.14.2/react-dom.min.js"></script>
  <script src="//cdn.jsdelivr.net/graphiql/<%= graphiql_version %>/graphiql.min.js"></script>
</head>
<body>
  <script>
    // Collect the URL parameters
    var parameters = {};
    window.location.search.substr(1).split('&').forEach(function (entry) {
      var eq = entry.indexOf('=');
      if (eq >= 0) {
        parameters[decodeURIComponent(entry.slice(0, eq))] =
          decodeURIComponent(entry.slice(eq + 1));
      }
    });

    // Produce a Location query string from a parameter object.
    function locationQuery(params) {
      return '?' + Object.keys(params).map(function (key) {
        return encodeURIComponent(key) + '=' +
          encodeURIComponent(params[key]);
      }).join('&');
    }

    // Derive a fetch URL from the current URL, sans the GraphQL parameters.
    var graphqlParamNames = {
      query: true,
      variables: true,
      operationName: true
    };

    var otherParams = {};
    for (var k in parameters) {
      if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
        otherParams[k] = parameters[k];
      }
    }
    var fetchURL = locationQuery(otherParams);

    // Defines a GraphQL fetcher using the fetch API.
    function graphQLFetcher(graphQLParams) {
      return fetch(fetchURL, {
        method: 'post',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(graphQLParams),
        credentials: 'include',
      }).then(function (response) {
        return response.json();
      });
    }

    // When the query and variables string is edited, update the URL bar so
    // that it can be easily shared.
    function onEditQuery(newQuery) {
      parameters.query = newQuery;
      updateURL();
    }

    function onEditVariables(newVariables) {
      parameters.variables = newVariables;
      updateURL();
    }

    function updateURL() {
      history.replaceState(null, null, locationQuery(parameters));
    }

    // Render <GraphiQL /> into the body.
    React.render(
      React.createElement(GraphiQL, {
        fetcher: graphQLFetcher,
        onEditQuery: onEditQuery,
        onEditVariables: onEditVariables,
        query: '<%= query %>',
        response: '<%= result %>',
        variables: '<%= variables %>'
      }),
      document.body
    );
  </script>
</body>
</html>


Move to 100% client side

Move to 100% client side

We'll fix server rendering later on

	<%= for {posting, index} <- Enum.with_index(@postings) do %>

 <img src="<%= posting.picture %>" style="width: 48px; height: 48px;" width=48 height=48>

<a target="blank" href="<%= posting.uri %>" class=""><%= posting.title %>

				 Elixir
				 Pi

<%= posting.description %>

				<a target="blank" href="<%= posting.uri %>" class="btn btn-primary">Visit→
				<button class="btn btn-primary">♥</button>

  <% end %>

      <%= paginate @conn, @kerosene %>


Ignore git in dockerignore, but keep HEAD and refs.

Closes #4735

This allows accessing current commit hash without including
the entire repo in the docker build context.

Example:

$ git show HEAD --pretty=full | head -n 1
commit d0b8727759e1e0e7aa3d41707d12376e373d5ecc

$ cat .git/HEAD
ref: refs/heads/master

$ cat .git/HEAD | awk '{print ".git/"$2}' | xargs cat
d0b8727759e1e0e7aa3d41707d12376e373d5ecc

Co-authored-by: Gary Rennie <8d8cdd8554fa832780fdb6e3f92477f6cc403c1e@gmail.com>

# This file excludes paths from the Docker build context.
#
# By default, Docker's build context includes all files (and folders) in the
# current directory. Even if a file isn't copied into the container it is still sent to
# the Docker daemon.
#
# There are multiple reasons to exclude files from the build context:
#
# 1. Prevent nested folders from being copied into the container (ex: exclude
#    /assets/node_modules when copying /assets)
# 2. Reduce the size of the build context and improve build time (ex. /build, /deps, /doc)
# 3. Avoid sending files containing sensitive information
#
# More information on using .dockerignore is available here:
# https://docs.docker.com/engine/reference/builder/#dockerignore-file

.dockerignore

# Ignore git, but keep git HEAD and refs to access current commit hash if needed:
#
# $ git show HEAD --pretty=full | head -n 1
# commit d0b8727759e1e0e7aa3d41707d12376e373d5ecc
.git
!.git/HEAD
!.git/refs

# Common development/test artifacts
/cover/
/doc/
/test/
/tmp/
.elixir_ls

# Mix artifacts
/_build/
/deps/
*.ez

# Generated on crash by the VM
erl_crash.dump

# Static artifacts - These should be fetched and built inside the Docker image
/assets/node_modules/
/priv/static/assets/
/priv/static/cache_manifest.json

# This file excludes paths from the Docker build context.
#
# By default, Docker's build context includes all files (and folders) in the
# current directory. Even if a file isn't copied into the container it is still sent to
# the Docker daemon.
#
# There are multiple reasons to exclude files from the build context:
#
# 1. Prevent nested folders from being copied into the container (ex: exclude
#    /assets/node_modules when copying /assets)
# 2. Reduce the size of the build context and improve build time (ex. /build, /deps, /doc)
# 3. Avoid sending files containing sensitive information
#
# More information on using .dockerignore is available here:
# https://docs.docker.com/engine/reference/builder/#dockerignore-file

.dockerignore
# There are valid reasons to keep .git, namely so that you can get the
# current commit hash
#/.git/

# Common development/test artifacts
/cover/
/doc/
/test/
/tmp/
.elixir_ls

# Mix artifacts
/_build/
/deps/
*.ez

# Generated on crash by the VM
erl_crash.dump

# Static artifacts - These should be fetched and built inside the Docker image
/assets/node_modules/
/priv/static/assets/
/priv/static/cache_manifest.json


Add describe command

Add describe command

#!/bin/sh

set -e

# Set VERBOSE to enable verbose logging of the boot script
#VERBOSE=true
if [ ! -z $DEBUG_BOOT ]; then
    set -x
fi;

my_readlink_f() {
    TARGET_FILE="$1"
    cd $(dirname "$TARGET_FILE")
    TARGET_FILE=$(basename "$TARGET_FILE")

    # Iterate down a (possible) chain of symlinks
    while [ -L "$TARGET_FILE" ]
    do
        TARGET_FILE=$(readlink "$TARGET_FILE")
        cd $(dirname "$TARGET_FILE")
        TARGET_FILE=$(basename "$TARGET_FILE")
    done
    # Compute the canonicalized name by finding the physical path
    # for the directory we're in and appending the target file.
    PHYS_DIR=$(pwd -P)
    RESULT="$PHYS_DIR/$TARGET_FILE"
    echo "$RESULT"
}

# Path to this script
if uname | grep -q 'Darwin'; then
  # on OSX, best to install coreutils from homebrew or similar
  # to get greadlink
  if command -v greadlink >/dev/null 2>&1; then
    SCRIPT=$(greadlink -f "$0")
  else
    SCRIPT=$(my_readlink_f "$0" )
  fi
else
  SCRIPT=$(readlink -f "$0" )
fi

# Parent directory of this script
SCRIPT_DIR=$(dirname "${SCRIPT}")
# Root directory of all releases
RELEASE_ROOT_DIR=$(dirname $(dirname ${SCRIPT_DIR}))

# Disable flow control for run_erl
# Flow control can cause several problems. On Linux, if you
# accidentally hit Ctrl-S (instead of Ctrl-D to detach) and
# then some other key, the entire beam process will hang when
# attempting to write to stdout. On Solaris, the beam process
# will hang on writing if ScrollLock is on.
RUN_ERL_DISABLE_FLOWCNTRL="${RUN_ERL_DISABLE_FLOWCNTRL:-true}"
# Name of the release
REL_NAME="<%= release_name %>"
# Current version of the release
REL_VSN="<%= release_version %>"
# Current version of ERTS being used
# If this is not present/unset, it will be detected
<%= if ((is_binary(include_erts) or include_erts) and not is_nil(erts_vsn)) do %>ERTS_VSN="<%= erts_vsn %>"<% end %>
# VM code loading mode, embedded by default, can also be interactive
# See http://erlang.org/doc/man/code.html
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
# Path to start_erl.data
START_ERL_DATA="$RELEASE_ROOT_DIR/releases/start_erl.data"
# Directory containing the current version of this release
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
# The lib directory for this release
REL_LIB_DIR="$RELEASE_ROOT_DIR/lib"
# Options passed to erl
ERL_OPTS="<%= release.profile.erl_opts %>"
# When stdout is piped to a file, this is the directory those files will
# be stored in. defaults to /log in the release root directory

# RELEASE_MUTABLE_DIR
RELEASE_MUTABLE_DIR="${RELEASE_MUTABLE_DIR:-$RELEASE_ROOT_DIR/var}"

RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_MUTABLE_DIR/log}"
# A string of extra options to pass to erl, here for plugins
EXTRA_OPTS=""

# Pre-start/stop event hook paths
PRE_START_HOOKS="$REL_DIR/hooks/pre_start.d"
POST_START_HOOKS="$REL_DIR/hooks/post_start.d"
PRE_STOP_HOOKS="$REL_DIR/hooks/pre_stop.d"
POST_STOP_HOOKS="$REL_DIR/hooks/post_stop.d"
PRE_UPGRADE_HOOKS="$REL_DIR/hooks/pre_upgrade.d"
POST_UPGRADE_HOOKS="$REL_DIR/hooks/post_upgrade.d"

# Get node pid
get_pid() {
    if output="$(nodetool rpcterms os getpid)"
    then
        echo "$output" | sed -e 's/"//g'
        return 0
    else
        echo "$output"
        return 1
    fi
}

# Generate a unique nodename
gen_nodename() {
    id="longname$(gen_id)-${NAME}"
    "$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
}

# Generate a random id
gen_id() {
    od -t x -N 4 /dev/urandom | head -n1 | awk '{print $2}'
}

# Control a node
# Use like `nodetool "ping"`
nodetool() {
    command="$1"; shift
    name=${PEERNAME:-$NAME}
    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$name" \
                            -setcookie "$COOKIE" "$command" $@
}

# Run an escript in the node's environment
# Use like `escript "path/to/escript"`
escript() {
    shift; scriptpath="$1"; shift
    export RELEASE_ROOT_DIR

    "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
}

# Private. Load target cookie, either from vm.args or $HOME/.cookie
_load_cookie() {
    COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)"
    DEFAULT_COOKIE_FILE="$HOME/.erlang.cookie"
    if [ -z "$COOKIE_ARG" ]; then
        if [ -f "$DEFAULT_COOKIE_FILE" ]; then
            COOKIE="$(cat "$DEFAULT_COOKIE_FILE")"
        fi
    else
        # Extract cookie name from COOKIE_ARG
        COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
    fi
}

# Private. Ensure that cookie is set.
_check_cookie() {
    # Attempt reloading cookie in case it has been set in a hook
    if [ -z "$COOKIE" ]; then
        _load_cookie
    fi
    # Die if cookie is still not set, as connecting via distribution will fail
    if [ -z "$COOKIE" ]; then
        printf "a secret cookie must be provided in one of the following ways:\n  - with vm.args using the -setcookie parameter,\n  or\n  by writing the cookie to '$DEFAULT_COOKIE_FILE', with permissions set to 0400"
        exit 1
    fi
}

# Private. For determining the version of ERTS available to the release
# This is only ever called if ERTS_VSN is not set
_detect_erts_vsn() {
    set +e # temporarily disable so we can display a nice error message to the user
    __erl="$(which erl)"
    set -e
    if [ -z "${__erl}"  ]; then
        echo 'erlang runtime not found. If erlang is installed check your $PATH. aborting.'
        exit 1
    fi
    "$__erl" -boot start_clean -eval 'Ver = erlang:system_info(version), io:format("~s~n", [Ver]), halt()' -noshell
}

# Private. Gets a list of code paths for this release
_get_code_paths() {
    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/release_utils.escript" "get_code_paths" "$ROOTDIR" "$ERTS_DIR" "$REL_NAME" "$REL_VSN"
}

# Private. For setting ERTS_DIR and ROOTDIR
_find_erts_dir() {
    __erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
    if [ -d "$__erts_dir" ]; then
        ERTS_DIR="$__erts_dir";
        ROOTDIR="$RELEASE_ROOT_DIR"
    else
        set +e # temporarily disable so we can display a nice error message to the user
        __erl="$(which erl)"
        set -e
        if [ -z "${__erl}"  ]; then
          echo 'erlang runtime not found. If erlang is installed check your $PATH. aborting.'
          exit 1
        fi
        code="io:format(\"~s\", [code:root_dir()]), halt()."
        __erl_root="$("$__erl" -noshell -eval "$code")"
        ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
        ROOTDIR="$__erl_root"
    fi
}

# Private. Open a shell on a remote node
_rem_sh() {
    # Generate a unique id used to allow multiple remsh to the same node
    # transparently
    id="remsh$(gen_id)-${NAME}"

    # Get the node's ticktime so that we use the same thing.
    TICKTIME="$(nodetool rpcterms net_kernel get_net_ticktime)"

    # Setup remote shell command to control node
    if [ ! -z "$USE_ERL_SHELL" ]; then
        exec "$BINDIR/erl" \
            -hidden \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            "$NAME_TYPE" "$id" -remsh "$NAME" -setcookie "$COOKIE"
    else
        __code_paths=$(_get_code_paths)
        exec "$BINDIR/erl" \
            -pa "$CONSOLIDATED_DIR" \
            ${__code_paths} \
            -hidden -noshell \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            -user Elixir.IEx.CLI "$NAME_TYPE" "$id" -setcookie "$COOKIE" \
            -extra --no-halt +iex -"$NAME_TYPE" "$id" --cookie "$COOKIE" --remsh "$NAME"
    fi
}

# Output a start command for the last argument of run_erl
_start_command() {
    printf "exec \"%s\" \"%s\" -- %s %s" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
           "$START_OPTION" "${ARGS}" "${EXTRA_OPTS}"
}

# Do a textual replacement of ${VAR} occurances in $1 and pipe to $2
_replace_os_vars() {
    awk '
        function escape(s) {
            gsub(/'\&'/, "\\\\&", s);
            return s;
        }
        {
            while(match($0,"[$]{[^}]*}")) {
                var=substr($0,RSTART+2,RLENGTH-3);
                gsub("[$]{"var"}", escape(ENVIRON[var]))
            }
        }1' < "$1" > "$1.bak"
    mv -- "$1.bak" "$1"
}

# Private. Run hooks from directory.
_run_hooks_from_dir() {
   if [ -d "$1" ]; then
      for file in $1/[0-9a-zA-Z]*.sh; do
        [ -f "$file" ] || continue
        . "$file"
      done
   fi
}

# If TERM is not set, set it to xterm
if [ -z "$TERM" ]; then
    export TERM=xterm
fi

# If ERTS_VSN is not set, detect it
if [ -z "$ERTS_VSN" ]; then
    ERTS_VSN="$(_detect_erts_vsn)"
    echo "$ERTS_VSN $REL_VSN" > "$START_ERL_DATA"
fi

# Allow override of where to read configuration from
# By default it's RELEASE_ROOT_DIR
if [ -z "$RELEASE_CONFIG_DIR" ]; then
    RELEASE_CONFIG_DIR="$RELEASE_ROOT_DIR"
fi

# Make sure directories exist
mkdir -p "$RELEASE_MUTABLE_DIR"
echo "Files in this directory are regenerated frequently, edits will be lost" \
    > "$RELEASE_MUTABLE_DIR/WARNING_README"
mkdir -p "$RUNNER_LOG_DIR"

# Set VMARGS_PATH, the path to the vm.args file to use
# Use $RELEASE_CONFIG_DIR/vm.args if exists, otherwise releases/VSN/vm.args
if [ -z "$VMARGS_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/vm.args" ]; then
        VMARGS_PATH="$RELEASE_CONFIG_DIR/vm.args"
    else
        VMARGS_PATH="$REL_DIR/vm.args"
    fi
fi
if [ "$VMARGS_PATH" != "$RELEASE_MUTABLE_DIR/vm.args" ]; then
    echo "#### Generated - edit/create $RELEASE_CONFIG_DIR/vm.args instead." \
        >  "$RELEASE_MUTABLE_DIR/vm.args"
    cat  "$VMARGS_PATH"                              \
        >> "$RELEASE_MUTABLE_DIR/vm.args"
    VMARGS_PATH=$RELEASE_MUTABLE_DIR/vm.args
fi
if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$VMARGS_PATH"
fi

# Set SYS_CONFIG_PATH, the path to the sys.config file to use
# Use $RELEASE_CONFIG_DIR/sys.config if exists, otherwise releases/VSN/sys.config
if [ -z "$SYS_CONFIG_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
fi
if [ "$SYS_CONFIG_PATH" != "$RELEASE_MUTABLE_DIR/sys.config" ]; then
    echo "%% Generated - edit/create $RELEASE_CONFIG_DIR/sys.config instead." \
        >  "$RELEASE_MUTABLE_DIR/sys.config"
    cat  "$SYS_CONFIG_PATH"                              \
        >> "$RELEASE_MUTABLE_DIR/sys.config"
    SYS_CONFIG_PATH=$RELEASE_MUTABLE_DIR/sys.config
fi
if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$SYS_CONFIG_PATH"
fi

# Extract the target node name from node.args
# Should be `-sname somename` or `-name somename@somehost`
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
if [ -z "$NAME_ARG" ]; then
    echo "vm.args needs to have either -name or -sname parameter."
    exit 1
fi

# Extract the name type and name from the NAME_ARG for REMSH
# NAME_TYPE should be -name or -sname
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
# NAME will be either `somename` or `somename@somehost`
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"

# Where the pipe will be stored when using `start`
# This is used so you can attach the running application to the current
# shell using `attach`
PIPE_DIR="${PIPE_DIR:-$RELEASE_MUTABLE_DIR/erl_pipes/$NAME/}"

# Extract the target cookie
_load_cookie

_find_erts_dir
export ROOTDIR="$RELEASE_ROOT_DIR"
export BINDIR="$ERTS_DIR/bin"
export EMU="beam"
export PROGNAME="erl"
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
ERTS_LIB_DIR="$ERTS_DIR/../lib"
CONSOLIDATED_DIR="$ROOTDIR/lib/${REL_NAME}-${REL_VSN}/consolidated"

cd "$ROOTDIR"

# User can specify an sname without @hostname
# This will fail when creating remote shell
# So here we check for @ and add @hostname if missing
case $NAME in
    *@*)
        # Nothing to do
        ;;
    *)
        NAME=$NAME@$(gen_nodename)
        ;;
esac

# For Elixir runtime
export DISTILLERY_TASK="$1"

# Check the first argument for instructions
case "$1" in
    start|start_boot)

        # Make sure there is not already a node running
        #RES=`$NODETOOL ping`
        #if [ "$RES" = "pong" ]; then
        #    echo "Node is already running!"
        #    exit 1
        #fi
        # Save this for later.
        CMD=$1
        case "$1" in
            start)
                shift
                START_OPTION="console"
                HEART_OPTION="start"
                ;;
            start_boot)
                shift
                START_OPTION="console_boot"
                HEART_OPTION="start_boot"
                ;;
        esac
        ARGS="$@"
        RUN_PARAM="$@"

        _check_cookie
        _run_hooks_from_dir "$PRE_START_HOOKS"

        # Set arguments for the heart command
        set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
        [ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"

        # Export the HEART_COMMAND
        HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD"
        export HEART_COMMAND

        mkdir -p "$PIPE_DIR"

        "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
                          "$(_start_command)"

        _run_hooks_from_dir "$POST_START_HOOKS"
        ;;

    stop)
        _check_cookie
        _run_hooks_from_dir "$PRE_STOP_HOOKS"
        # Wait for the node to completely stop...
        PID="$(get_pid)"
        if ! nodetool "stop"; then
            exit 1
        fi
        while $(kill -s 0 "$PID" 2>/dev/null);
        do
            sleep 1
        done
        _run_hooks_from_dir "$POST_STOP_HOOKS"
        ;;

    restart)
        _check_cookie
        _run_hooks_from_dir "$PRE_START_HOOKS"
        ## Restart the VM without exiting the process
        if ! nodetool "restart"; then
            exit 1
        fi
        ;;

    reboot)
        _check_cookie
        _run_hooks_from_dir "$PRE_START_HOOKS"
        ## Restart the VM completely (uses heart to restart it)
        if ! nodetool "reboot"; then
            exit 1
        fi
        ;;

    pid)
        ## Get the VM's pid
        _check_cookie
        if ! get_pid; then
            exit 1
        fi
        ;;

    ping)
        _check_cookie
        ## See if the VM is alive
        if ! nodetool "ping"; then
            exit 1
        fi
        ;;

    pingpeer)
        PEERNAME=$2 nodetool "ping"
        exit_status=$?
        if [ "$exit_status" -ne 0 ]; then
            exit $exit_status
        fi
        ;;

    escript)
        _check_cookie
        ## Run an escript under the node's environment
        if ! escript $@; then
            exit 1
        fi
        ;;

    attach)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;

    remote_console)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        _rem_sh
        ;;

    upgrade|downgrade|install)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        SOURCE_VERSION="$REL_VSN"
        TARGET_VERSION="$2"

        "$BINDIR/escript" "$ROOTDIR/bin/release_utils.escript" \
             "unpack_release" "$REL_NAME" "$NAME_TYPE"  "$NAME" "$COOKIE" "$TARGET_VERSION"

        _run_hooks_from_dir "$PRE_UPGRADE_HOOKS"

        "$BINDIR/escript" "$ROOTDIR/bin/release_utils.escript" \
             "install_release" "$REL_NAME" "$NAME_TYPE"  "$NAME" "$COOKIE" "$TARGET_VERSION"

        _run_hooks_from_dir "$POST_UPGRADE_HOOKS"

        ;;
    unpack)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/release_utils.escript" \
             "unpack_release" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    console|console_clean|console_boot)
        # .boot file typically just $REL_NAME (ie, the app name)
        # however, for debugging, sometimes start_clean.boot is useful.
        # For e.g. 'setup', one may even want to name another boot script.
        case "$1" in
            console)
                if [ -f "$REL_DIR/$REL_NAME.boot" ]; then
                  BOOTFILE="$REL_DIR/$REL_NAME"
                else
                  BOOTFILE="$REL_DIR/start"
                fi
                ;;
            console_clean)
                BOOTFILE="$ROOTDIR/bin/start_clean"
                __code_paths=$(_get_code_paths)
                EXTRA_CODE_PATHS=${__code_paths}
                ;;
            console_boot)
                shift
                BOOTFILE="$1"
                shift
                ;;
        esac
        # Setup beam-required vars
        EMU="beam"
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        _check_cookie

        # Start the VM, executing pre_start hook along
        # the way. We can't run the post_start hook because
        # the console will crash with no TTY attached
        _run_hooks_from_dir "$PRE_START_HOOKS"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" \
            -boot "$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            ${EXTRA_CODE_PATHS} \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -user Elixir.IEx.CLI \
            -extra --no-halt +iex

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS} ${EXTRA_OPTS}
            echo "Root: $ROOTDIR"

            # Log the startup
            echo "$RELEASE_ROOT_DIR"
        fi;

        logger -t "$REL_NAME[$$]" "Starting up"

        exec "$@" -- ${1+$ARGS} ${EXTRA_OPTS}
        ;;

    foreground)
        # start up the release in the foreground for use by runit
        # or other supervision services

        [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
        FOREGROUNDOPTIONS="-noshell -noinput +Bd"

        # Setup beam-required vars
        EMU=beam
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        _check_cookie

        # Start the VM, executing pre and post start hooks
        _run_hooks_from_dir "$PRE_START_HOOKS"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
            -boot "$REL_DIR/$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -extra ${EXTRA_OPTS}

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS}
            echo "Root: $ROOTDIR"
        fi;

        "$@" -- ${1+$ARGS} &
        __bg_pid=$!
        _run_hooks_from_dir "$POST_START_HOOKS"
        wait $__bg_pid
        ;;
    rpc)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpc $@
        ;;
    rpcterms)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpcterms $@
        ;;
    eval)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        nodetool "eval" $@
        ;;
    command)
        # Execute as command-line utility
        #
        # Like the escript command, this does not start the OTP application.
        # If your command depends on a running OTP application,
        # use
        #
        #     {:ok, _} = Application.ensure_all_started(:your_app)

        _check_cookie

        shift
        MODULE="$1"; shift
        FUNCTION="$1"; shift

        # Save extra arguments
        ARGS="$@"

        # Build arguments for erlexec
        __code_paths=$(_get_code_paths)
        set -- "$ERL_OPTS"
        [ "$SYS_CONFIG_PATH" ] && set -- "$@" -config "$SYS_CONFIG_PATH"
        set -- "$@" -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR"
        set -- "$@" -noshell
        set -- "$@" -boot start_clean
        set -- "$@" -pa "$CONSOLIDATED_DIR"
        set -- "$@" ${__code_paths}
        set -- "$@" -s "$MODULE" "$FUNCTION"

        $BINDIR/erlexec $@ -extra $ARGS
        exit "$?"
        ;;
    describe)
        ## Print a summary of information about this release
        echo "$REL_NAME-$REL_VSN\n"
        echo "erts:       $ERTS_VSN"
        echo "path:       $REL_DIR"
        echo "sys.config: $SYS_CONFIG_PATH"
        echo "vm.args:    $VMARGS_PATH"
        echo "name:       $NAME"
        echo "cookie:     $COOKIE"
        echo "erl_opts:   ${ERL_OPTS:-none provided}"
        echo ""
        echo "hooks:"
        __has_hooks=0
        for hook in "$REL_DIR"/hooks/*.d/[0-9a-zA-Z]*.sh; do
            [ -f "$hook" ] || continue
            __has_hooks=1
            echo "$hook"
        done
        if [ $__has_hooks -eq 0 ]; then
            echo "No custom hooks found."
        fi
        echo ""
        echo "commands:"
        __has_commands=0
        for command in "$REL_DIR"/commands/*.sh; do
            [ -f "$command" ] || continue
            __has_commands=1
            echo "$command"
        done
        if [ $__has_commands -eq 0 ]; then
            echo "No custom commands found."
        fi
        exit 0
        ;;
    *)
        __command_path="$REL_DIR/commands/$1"
        if [ -f "$__command_path" ]; then
            _check_cookie
            . "$__command_path"
        else
            echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|pingpeer|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|escript|rpc|rpcterms|eval|command <module> <function> <args>}|describe"
            exit 1
        fi
        ;;
esac

exit 0

#!/bin/sh

set -e

# Set VERBOSE to enable verbose logging of the boot script
#VERBOSE=true
if [ ! -z $DEBUG_BOOT ]; then
    set -x
fi;

my_readlink_f() {
    TARGET_FILE="$1"
    cd $(dirname "$TARGET_FILE")
    TARGET_FILE=$(basename "$TARGET_FILE")

    # Iterate down a (possible) chain of symlinks
    while [ -L "$TARGET_FILE" ]
    do
        TARGET_FILE=$(readlink "$TARGET_FILE")
        cd $(dirname "$TARGET_FILE")
        TARGET_FILE=$(basename "$TARGET_FILE")
    done
    # Compute the canonicalized name by finding the physical path
    # for the directory we're in and appending the target file.
    PHYS_DIR=$(pwd -P)
    RESULT="$PHYS_DIR/$TARGET_FILE"
    echo "$RESULT"
}

# Path to this script
if uname | grep -q 'Darwin'; then
  # on OSX, best to install coreutils from homebrew or similar
  # to get greadlink
  if command -v greadlink >/dev/null 2>&1; then
    SCRIPT=$(greadlink -f "$0")
  else
    SCRIPT=$(my_readlink_f "$0" )
  fi
else
  SCRIPT=$(readlink -f "$0" )
fi

# Parent directory of this script
SCRIPT_DIR=$(dirname "${SCRIPT}")
# Root directory of all releases
RELEASE_ROOT_DIR=$(dirname $(dirname ${SCRIPT_DIR}))

# Disable flow control for run_erl
# Flow control can cause several problems. On Linux, if you
# accidentally hit Ctrl-S (instead of Ctrl-D to detach) and
# then some other key, the entire beam process will hang when
# attempting to write to stdout. On Solaris, the beam process
# will hang on writing if ScrollLock is on.
RUN_ERL_DISABLE_FLOWCNTRL="${RUN_ERL_DISABLE_FLOWCNTRL:-true}"
# Name of the release
REL_NAME="<%= release_name %>"
# Current version of the release
REL_VSN="<%= release_version %>"
# Current version of ERTS being used
# If this is not present/unset, it will be detected
<%= if ((is_binary(include_erts) or include_erts) and not is_nil(erts_vsn)) do %>ERTS_VSN="<%= erts_vsn %>"<% end %>
# VM code loading mode, embedded by default, can also be interactive
# See http://erlang.org/doc/man/code.html
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
# Path to start_erl.data
START_ERL_DATA="$RELEASE_ROOT_DIR/releases/start_erl.data"
# Directory containing the current version of this release
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
# The lib directory for this release
REL_LIB_DIR="$RELEASE_ROOT_DIR/lib"
# Options passed to erl
ERL_OPTS="<%= release.profile.erl_opts %>"
# When stdout is piped to a file, this is the directory those files will
# be stored in. defaults to /log in the release root directory

# RELEASE_MUTABLE_DIR
RELEASE_MUTABLE_DIR="${RELEASE_MUTABLE_DIR:-$RELEASE_ROOT_DIR/var}"

RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_MUTABLE_DIR/log}"
# A string of extra options to pass to erl, here for plugins
EXTRA_OPTS=""

# Pre-start/stop event hook paths
PRE_START_HOOKS="$REL_DIR/hooks/pre_start.d"
POST_START_HOOKS="$REL_DIR/hooks/post_start.d"
PRE_STOP_HOOKS="$REL_DIR/hooks/pre_stop.d"
POST_STOP_HOOKS="$REL_DIR/hooks/post_stop.d"
PRE_UPGRADE_HOOKS="$REL_DIR/hooks/pre_upgrade.d"
POST_UPGRADE_HOOKS="$REL_DIR/hooks/post_upgrade.d"

# Get node pid
get_pid() {
    if output="$(nodetool rpcterms os getpid)"
    then
        echo "$output" | sed -e 's/"//g'
        return 0
    else
        echo "$output"
        return 1
    fi
}

# Generate a unique nodename
gen_nodename() {
    id="longname$(gen_id)-${NAME}"
    "$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
}

# Generate a random id
gen_id() {
    od -t x -N 4 /dev/urandom | head -n1 | awk '{print $2}'
}

# Control a node
# Use like `nodetool "ping"`
nodetool() {
    command="$1"; shift
    name=${PEERNAME:-$NAME}
    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$name" \
                            -setcookie "$COOKIE" "$command" $@
}

# Run an escript in the node's environment
# Use like `escript "path/to/escript"`
escript() {
    shift; scriptpath="$1"; shift
    export RELEASE_ROOT_DIR

    "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
}

# Private. Load target cookie, either from vm.args or $HOME/.cookie
_load_cookie() {
    COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)"
    DEFAULT_COOKIE_FILE="$HOME/.erlang.cookie"
    if [ -z "$COOKIE_ARG" ]; then
        if [ -f "$DEFAULT_COOKIE_FILE" ]; then
            COOKIE="$(cat "$DEFAULT_COOKIE_FILE")"
        fi
    else
        # Extract cookie name from COOKIE_ARG
        COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
    fi
}

# Private. Ensure that cookie is set.
_check_cookie() {
    # Attempt reloading cookie in case it has been set in a hook
    if [ -z "$COOKIE" ]; then
        _load_cookie
    fi
    # Die if cookie is still not set, as connecting via distribution will fail
    if [ -z "$COOKIE" ]; then
        printf "a secret cookie must be provided in one of the following ways:\n  - with vm.args using the -setcookie parameter,\n  or\n  by writing the cookie to '$DEFAULT_COOKIE_FILE', with permissions set to 0400"
        exit 1
    fi
}

# Private. For determining the version of ERTS available to the release
# This is only ever called if ERTS_VSN is not set
_detect_erts_vsn() {
    set +e # temporarily disable so we can display a nice error message to the user
    __erl="$(which erl)"
    set -e
    if [ -z "${__erl}"  ]; then
        echo 'erlang runtime not found. If erlang is installed check your $PATH. aborting.'
        exit 1
    fi
    "$__erl" -boot start_clean -eval 'Ver = erlang:system_info(version), io:format("~s~n", [Ver]), halt()' -noshell
}

# Private. Gets a list of code paths for this release
_get_code_paths() {
    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/release_utils.escript" "get_code_paths" "$ROOTDIR" "$ERTS_DIR" "$REL_NAME" "$REL_VSN"
}

# Private. For setting ERTS_DIR and ROOTDIR
_find_erts_dir() {
    __erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
    if [ -d "$__erts_dir" ]; then
        ERTS_DIR="$__erts_dir";
        ROOTDIR="$RELEASE_ROOT_DIR"
    else
        set +e # temporarily disable so we can display a nice error message to the user
        __erl="$(which erl)"
        set -e
        if [ -z "${__erl}"  ]; then
          echo 'erlang runtime not found. If erlang is installed check your $PATH. aborting.'
          exit 1
        fi
        code="io:format(\"~s\", [code:root_dir()]), halt()."
        __erl_root="$("$__erl" -noshell -eval "$code")"
        ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
        ROOTDIR="$__erl_root"
    fi
}

# Private. Open a shell on a remote node
_rem_sh() {
    # Generate a unique id used to allow multiple remsh to the same node
    # transparently
    id="remsh$(gen_id)-${NAME}"

    # Get the node's ticktime so that we use the same thing.
    TICKTIME="$(nodetool rpcterms net_kernel get_net_ticktime)"

    # Setup remote shell command to control node
    if [ ! -z "$USE_ERL_SHELL" ]; then
        exec "$BINDIR/erl" \
            -hidden \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            "$NAME_TYPE" "$id" -remsh "$NAME" -setcookie "$COOKIE"
    else
        __code_paths=$(_get_code_paths)
        exec "$BINDIR/erl" \
            -pa "$CONSOLIDATED_DIR" \
            ${__code_paths} \
            -hidden -noshell \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            -user Elixir.IEx.CLI "$NAME_TYPE" "$id" -setcookie "$COOKIE" \
            -extra --no-halt +iex -"$NAME_TYPE" "$id" --cookie "$COOKIE" --remsh "$NAME"
    fi
}

# Output a start command for the last argument of run_erl
_start_command() {
    printf "exec \"%s\" \"%s\" -- %s %s" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
           "$START_OPTION" "${ARGS}" "${EXTRA_OPTS}"
}

# Do a textual replacement of ${VAR} occurances in $1 and pipe to $2
_replace_os_vars() {
    awk '
        function escape(s) {
            gsub(/'\&'/, "\\\\&", s);
            return s;
        }
        {
            while(match($0,"[$]{[^}]*}")) {
                var=substr($0,RSTART+2,RLENGTH-3);
                gsub("[$]{"var"}", escape(ENVIRON[var]))
            }
        }1' < "$1" > "$1.bak"
    mv -- "$1.bak" "$1"
}

# Private. Run hooks from directory.
_run_hooks_from_dir() {
   if [ -d "$1" ]; then
      for file in $1/[0-9a-zA-Z]*.sh; do
        [ -f "$file" ] || continue
        . "$file"
      done
   fi
}

# If TERM is not set, set it to xterm
if [ -z "$TERM" ]; then
    export TERM=xterm
fi

# If ERTS_VSN is not set, detect it
if [ -z "$ERTS_VSN" ]; then
    ERTS_VSN="$(_detect_erts_vsn)"
    echo "$ERTS_VSN $REL_VSN" > "$START_ERL_DATA"
fi

# Allow override of where to read configuration from
# By default it's RELEASE_ROOT_DIR
if [ -z "$RELEASE_CONFIG_DIR" ]; then
    RELEASE_CONFIG_DIR="$RELEASE_ROOT_DIR"
fi

# Make sure directories exist
mkdir -p "$RELEASE_MUTABLE_DIR"
echo "Files in this directory are regenerated frequently, edits will be lost" \
    > "$RELEASE_MUTABLE_DIR/WARNING_README"
mkdir -p "$RUNNER_LOG_DIR"

# Set VMARGS_PATH, the path to the vm.args file to use
# Use $RELEASE_CONFIG_DIR/vm.args if exists, otherwise releases/VSN/vm.args
if [ -z "$VMARGS_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/vm.args" ]; then
        VMARGS_PATH="$RELEASE_CONFIG_DIR/vm.args"
    else
        VMARGS_PATH="$REL_DIR/vm.args"
    fi
fi
if [ "$VMARGS_PATH" != "$RELEASE_MUTABLE_DIR/vm.args" ]; then
    echo "#### Generated - edit/create $RELEASE_CONFIG_DIR/vm.args instead." \
        >  "$RELEASE_MUTABLE_DIR/vm.args"
    cat  "$VMARGS_PATH"                              \
        >> "$RELEASE_MUTABLE_DIR/vm.args"
    VMARGS_PATH=$RELEASE_MUTABLE_DIR/vm.args
fi
if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$VMARGS_PATH"
fi

# Set SYS_CONFIG_PATH, the path to the sys.config file to use
# Use $RELEASE_CONFIG_DIR/sys.config if exists, otherwise releases/VSN/sys.config
if [ -z "$SYS_CONFIG_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
fi
if [ "$SYS_CONFIG_PATH" != "$RELEASE_MUTABLE_DIR/sys.config" ]; then
    echo "%% Generated - edit/create $RELEASE_CONFIG_DIR/sys.config instead." \
        >  "$RELEASE_MUTABLE_DIR/sys.config"
    cat  "$SYS_CONFIG_PATH"                              \
        >> "$RELEASE_MUTABLE_DIR/sys.config"
    SYS_CONFIG_PATH=$RELEASE_MUTABLE_DIR/sys.config
fi
if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$SYS_CONFIG_PATH"
fi

# Extract the target node name from node.args
# Should be `-sname somename` or `-name somename@somehost`
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
if [ -z "$NAME_ARG" ]; then
    echo "vm.args needs to have either -name or -sname parameter."
    exit 1
fi

# Extract the name type and name from the NAME_ARG for REMSH
# NAME_TYPE should be -name or -sname
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
# NAME will be either `somename` or `somename@somehost`
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"

# Where the pipe will be stored when using `start`
# This is used so you can attach the running application to the current
# shell using `attach`
PIPE_DIR="${PIPE_DIR:-$RELEASE_MUTABLE_DIR/erl_pipes/$NAME/}"

# Extract the target cookie
_load_cookie

_find_erts_dir
export ROOTDIR="$RELEASE_ROOT_DIR"
export BINDIR="$ERTS_DIR/bin"
export EMU="beam"
export PROGNAME="erl"
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
ERTS_LIB_DIR="$ERTS_DIR/../lib"
CONSOLIDATED_DIR="$ROOTDIR/lib/${REL_NAME}-${REL_VSN}/consolidated"

cd "$ROOTDIR"

# User can specify an sname without @hostname
# This will fail when creating remote shell
# So here we check for @ and add @hostname if missing
case $NAME in
    *@*)
        # Nothing to do
        ;;
    *)
        NAME=$NAME@$(gen_nodename)
        ;;
esac

# For Elixir runtime
export DISTILLERY_TASK="$1"

# Check the first argument for instructions
case "$1" in
    start|start_boot)

        # Make sure there is not already a node running
        #RES=`$NODETOOL ping`
        #if [ "$RES" = "pong" ]; then
        #    echo "Node is already running!"
        #    exit 1
        #fi
        # Save this for later.
        CMD=$1
        case "$1" in
            start)
                shift
                START_OPTION="console"
                HEART_OPTION="start"
                ;;
            start_boot)
                shift
                START_OPTION="console_boot"
                HEART_OPTION="start_boot"
                ;;
        esac
        ARGS="$@"
        RUN_PARAM="$@"

        _check_cookie
        _run_hooks_from_dir "$PRE_START_HOOKS"

        # Set arguments for the heart command
        set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
        [ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"

        # Export the HEART_COMMAND
        HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD"
        export HEART_COMMAND

        mkdir -p "$PIPE_DIR"

        "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
                          "$(_start_command)"

        _run_hooks_from_dir "$POST_START_HOOKS"
        ;;

    stop)
        _check_cookie
        _run_hooks_from_dir "$PRE_STOP_HOOKS"
        # Wait for the node to completely stop...
        PID="$(get_pid)"
        if ! nodetool "stop"; then
            exit 1
        fi
        while $(kill -s 0 "$PID" 2>/dev/null);
        do
            sleep 1
        done
        _run_hooks_from_dir "$POST_STOP_HOOKS"
        ;;

    restart)
        _check_cookie
        _run_hooks_from_dir "$PRE_START_HOOKS"
        ## Restart the VM without exiting the process
        if ! nodetool "restart"; then
            exit 1
        fi
        ;;

    reboot)
        _check_cookie
        _run_hooks_from_dir "$PRE_START_HOOKS"
        ## Restart the VM completely (uses heart to restart it)
        if ! nodetool "reboot"; then
            exit 1
        fi
        ;;

    pid)
        ## Get the VM's pid
        _check_cookie
        if ! get_pid; then
            exit 1
        fi
        ;;

    ping)
        _check_cookie
        ## See if the VM is alive
        if ! nodetool "ping"; then
            exit 1
        fi
        ;;

    pingpeer)
        PEERNAME=$2 nodetool "ping"
        exit_status=$?
        if [ "$exit_status" -ne 0 ]; then
            exit $exit_status
        fi
        ;;

    escript)
        _check_cookie
        ## Run an escript under the node's environment
        if ! escript $@; then
            exit 1
        fi
        ;;

    attach)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;

    remote_console)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        _rem_sh
        ;;

    upgrade|downgrade|install)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        SOURCE_VERSION="$REL_VSN"
        TARGET_VERSION="$2"

        "$BINDIR/escript" "$ROOTDIR/bin/release_utils.escript" \
             "unpack_release" "$REL_NAME" "$NAME_TYPE"  "$NAME" "$COOKIE" "$TARGET_VERSION"

        _run_hooks_from_dir "$PRE_UPGRADE_HOOKS"

        "$BINDIR/escript" "$ROOTDIR/bin/release_utils.escript" \
             "install_release" "$REL_NAME" "$NAME_TYPE"  "$NAME" "$COOKIE" "$TARGET_VERSION"

        _run_hooks_from_dir "$POST_UPGRADE_HOOKS"

        ;;
    unpack)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/release_utils.escript" \
             "unpack_release" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    console|console_clean|console_boot)
        # .boot file typically just $REL_NAME (ie, the app name)
        # however, for debugging, sometimes start_clean.boot is useful.
        # For e.g. 'setup', one may even want to name another boot script.
        case "$1" in
            console)
                if [ -f "$REL_DIR/$REL_NAME.boot" ]; then
                  BOOTFILE="$REL_DIR/$REL_NAME"
                else
                  BOOTFILE="$REL_DIR/start"
                fi
                ;;
            console_clean)
                BOOTFILE="$ROOTDIR/bin/start_clean"
                __code_paths=$(_get_code_paths)
                EXTRA_CODE_PATHS=${__code_paths}
                ;;
            console_boot)
                shift
                BOOTFILE="$1"
                shift
                ;;
        esac
        # Setup beam-required vars
        EMU="beam"
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        _check_cookie

        # Start the VM, executing pre_start hook along
        # the way. We can't run the post_start hook because
        # the console will crash with no TTY attached
        _run_hooks_from_dir "$PRE_START_HOOKS"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" \
            -boot "$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            ${EXTRA_CODE_PATHS} \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -user Elixir.IEx.CLI \
            -extra --no-halt +iex

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS} ${EXTRA_OPTS}
            echo "Root: $ROOTDIR"

            # Log the startup
            echo "$RELEASE_ROOT_DIR"
        fi;

        logger -t "$REL_NAME[$$]" "Starting up"

        exec "$@" -- ${1+$ARGS} ${EXTRA_OPTS}
        ;;

    foreground)
        # start up the release in the foreground for use by runit
        # or other supervision services

        [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
        FOREGROUNDOPTIONS="-noshell -noinput +Bd"

        # Setup beam-required vars
        EMU=beam
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        _check_cookie

        # Start the VM, executing pre and post start hooks
        _run_hooks_from_dir "$PRE_START_HOOKS"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
            -boot "$REL_DIR/$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -extra ${EXTRA_OPTS}

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS}
            echo "Root: $ROOTDIR"
        fi;

        "$@" -- ${1+$ARGS} &
        __bg_pid=$!
        _run_hooks_from_dir "$POST_START_HOOKS"
        wait $__bg_pid
        ;;
    rpc)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpc $@
        ;;
    rpcterms)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpcterms $@
        ;;
    eval)
        _check_cookie

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        nodetool "eval" $@
        ;;
    command)
        # Execute as command-line utility
        #
        # Like the escript command, this does not start the OTP application.
        # If your command depends on a running OTP application,
        # use
        #
        #     {:ok, _} = Application.ensure_all_started(:your_app)

        _check_cookie

        shift
        MODULE="$1"; shift
        FUNCTION="$1"; shift

        # Save extra arguments
        ARGS="$@"

        # Build arguments for erlexec
        __code_paths=$(_get_code_paths)
        set -- "$ERL_OPTS"
        [ "$SYS_CONFIG_PATH" ] && set -- "$@" -config "$SYS_CONFIG_PATH"
        set -- "$@" -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR"
        set -- "$@" -noshell
        set -- "$@" -boot start_clean
        set -- "$@" -pa "$CONSOLIDATED_DIR"
        set -- "$@" ${__code_paths}
        set -- "$@" -s "$MODULE" "$FUNCTION"

        $BINDIR/erlexec $@ -extra $ARGS
        exit "$?"
        ;;
    *)
        __command_path="$REL_DIR/commands/$1"
        if [ -f "$__command_path" ]; then
            _check_cookie
            . "$__command_path"
        else
            echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|pingpeer|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|escript|rpc|rpcterms|eval|command <module> <function> <args>}"
            exit 1
        fi
        ;;
esac

exit 0


layout style

layout style

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Статистика проектов</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/application.css") %>">

<%= get_flash(@conn, :info) %>

<%= get_flash(@conn, :error) %>

    <%= render @view_module, @view_template, assigns %>


ga key option

ga key option

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Anivia</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
    <%= if System.get_env("GA_KEY") do %>
  <script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', '<%= System.get_env("GA_KEY") %>', 'auto');
  ga('send', 'pageview');
  </script>
  <% end %>

  </head>

  <body>
    <%= render @view_module, @view_template, assigns %>
    <%= if Mix.env == :dev do %>
      <script src='http://localhost:4001/index.bundle.js'></script>
    <% else %>
      <script src="<%= static_path(@conn, "/js/index.bundle.js") %>"></script>
    <% end %>
  </body>
</html>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Anivia</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">

  </head>

  <body>
    <%= render @view_module, @view_template, assigns %>
    <%= if Mix.env == :dev do %>
      <script src='http://localhost:4001/index.bundle.js'></script>
    <% else %>
      <script src="<%= static_path(@conn, "/js/index.bundle.js") %>"></script>
    <% end %>
  </body>
</html>


Add title field to show PR title.

Add title field to show PR title.

    <%= for user <- Map.keys(@prs) do %>
      <%= for commit <- @prs[user] do %>

            <img src="<%= commit.github_user_avatar %>" style="width: 32px; height: 32px;" />
            <%= user %>

            <%= commit.pr.title %>

          <%= link("Travis", to: commit.travis_url) %>
          <%= link("Github", to: commit.pr.html_url) %>

            <span class="label label-<%= status_class(commit.status) %> text-uppercase">
              <%= to_string(commit.status) %>

      <% end %>
    <% end %>

    <%= for user <- Map.keys(@prs) do %>
      <%= for commit <- @prs[user] do %>

            <img src="<%= commit.github_user_avatar %>" style="width: 32px; height: 32px;" />
            <%= user %>

          <%= link("Travis", to: commit.travis_url) %>
          <%= link("Github", to: commit.pr.html_url) %>

            <span class="label label-<%= status_class(commit.status) %> text-uppercase">
              <%= to_string(commit.status) %>

      <% end %>
    <% end %>


Switch to plain anchor tag because of phoenix_html issue.

    <%= for user <- Map.keys(@prs) do %>
      <%= for commit <- @prs[user] do %>

            <img src="<%= commit.github_user_avatar %>" style="width: 32px; height: 32px;" />
            <%= user %>

            <%= commit.pr.title %>

            <a href="<%= commit.travis_url %>">Travis

            <a href="<%= commit.pr.html_url %>">Github

            <span class="label label-<%= status_class(commit.status) %> text-uppercase">
              <%= to_string(commit.status) %>

      <% end %>
    <% end %>

    <%= for user <- Map.keys(@prs) do %>
      <%= for commit <- @prs[user] do %>

            <img src="<%= commit.github_user_avatar %>" style="width: 32px; height: 32px;" />
            <%= user %>

            <%= commit.pr.title %>

          <%= link("Travis", to: commit.travis_url) %>
          <%= link("Github", to: commit.pr.html_url) %>

            <span class="label label-<%= status_class(commit.status) %> text-uppercase">
              <%= to_string(commit.status) %>

      <% end %>
    <% end %>


Add SVG <img> to test html page

Add SVG <img> to test html page

Embed script

  Science is the key to our future, and if you don't believe in science, then you're holding everybody back. -- Bill Nye

<%= embed_script @asciicast %>

SVG

  If the Earth gets hit by an asteroid, it's game over. It's control-alt-delete
  for civilization. -- Bill Nye

<img src="<%= asciicast_path(@conn, :show, @asciicast) %>.svg" />

Embed script for home asciicast

<%= embed_script @home_asciicast %>

  You're dressed in a tuxedo, you wear a bow tie. A bow tie with a tuxedo is more formal than a straight tie with a tuxedo. -- Bill Nye

  Science is the key to our future, and if you don't believe in science, then you're holding everybody back. -- Bill Nye

<%= embed_script @asciicast %>

  If the Earth gets hit by an asteroid, it's game over. It's control-alt-delete
  for civilization. -- Bill Nye

<%= embed_script @home_asciicast %>

  You're dressed in a tuxedo, you wear a bow tie. A bow tie with a tuxedo is more formal than a straight tie with a tuxedo. -- Bill Nye


Clarify where the cookie is stored on Nerves

If you remove the cookie line completely, Distillery produces a warning.
Instead of doing that, use a bogus informational cookie.

use Mix.Releases.Config,
    # This sets the default release built by `mix release`
    default_release: :default,
    # This sets the default environment used by `mix release`
    default_environment: :dev
<%= unless no_docs do %>
# For a full list of config options for both releases
# and environments, visit https://hexdocs.pm/distillery/config/distillery.html
<% end %>
<%= unless no_docs do %>
# You may define one or more environments in this file,
# an environment's settings will override those of a release
# when building in that environment, this combination of release
# and environment configuration is called a profile
<% end %>
environment :dev do
  set cookie: :"Unused with Nerves. See vm.args"
end

environment :prod do
  set cookie: :"Unused with Nerves. See vm.args"
end
<%= unless no_docs do %>
# You may define one or more releases in this file.
# If you have not set a default release, or selected one
# when running `mix release`, the first release in the file
# will be used by default<% end %>
<%= for release <- releases do %><%= if Keyword.get(release, :is_umbrella) do %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: "0.1.0"
  set applications: [
<%= Enum.map(Keyword.get(release, :release_applications), fn {app, start_type} ->
    "    #{app}: :#{start_type}"
    end) |> Enum.join(",\n") %>
  ]
  plugin Nerves
  plugin Shoehorn
end<% else %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: current_version(:<%= Keyword.get(release, :release_name)%>)
  plugin Nerves
  plugin Shoehorn
end<% end %>
<% end %>

use Mix.Releases.Config,
    # This sets the default release built by `mix release`
    default_release: :default,
    # This sets the default environment used by `mix release`
    default_environment: :dev
<%= unless no_docs do %>
# For a full list of config options for both releases
# and environments, visit https://hexdocs.pm/distillery/config/distillery.html
<% end %>
<%= unless no_docs do %>
# You may define one or more environments in this file,
# an environment's settings will override those of a release
# when building in that environment, this combination of release
# and environment configuration is called a profile
<% end %>
environment :dev do
  set cookie: <%= inspect(cookie) %>
end

environment :prod do
  set cookie: <%= inspect(cookie) %>
end
<%= unless no_docs do %>
# You may define one or more releases in this file.
# If you have not set a default release, or selected one
# when running `mix release`, the first release in the file
# will be used by default<% end %>
<%= for release <- releases do %><%= if Keyword.get(release, :is_umbrella) do %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: "0.1.0"
  set applications: [
<%= Enum.map(Keyword.get(release, :release_applications), fn {app, start_type} ->
    "    #{app}: :#{start_type}"
    end) |> Enum.join(",\n") %>
  ]
  plugin Nerves
  plugin Shoehorn
end<% else %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: current_version(:<%= Keyword.get(release, :release_name)%>)
  plugin Nerves
  plugin Shoehorn
end<% end %>
<% end %>


Add information to submit new offers

Add information to submit new offers

<%= gettext("Hire a great Elixir/Erlang developer") %>

<%= raw gettext("Elixir/Erlang community is in a very vibrant moment. Start looking for your next hiring in the right place.") %>

<%= gettext("How does this works?") %>

<%= raw gettext("Once you submit your offer, we will review it to avoid SPAM or dead links and, if everything is correct, we will publish it as son as possible!") %>

<%= raw gettext("Publishing an offer on ElixirJobs is free and will be also posted to our Twitter account, so feel free of %{follow_link} and retweet your offer when published!", follow_link: "#{gettext("follow us")}") %>

<%= render "_form.html",
  changeset: @changeset,
  action: offer_path(@conn, :create),
  conn: @conn,
  css_class: "offer-new" %>

<%= gettext("Publish a job offer") %>

<%= render "_form.html",
  changeset: @changeset,
  action: offer_path(@conn, :create),
  conn: @conn,
  css_class: "offer-new" %>


Update LA committee

Update LA committee

<%= gettext("Contact") %>

  <%= gettext("Here is how you can get in touch with us.") %>

<%= gettext("Message us") %>

      <%= gettext("This form is for contacting the international committee of Grouping 2.") %>

      <%= gettext("For questions about local contests, consider contacting your local Jumu organizer (see list below).") %>

    <%= render "_contact_form.html", conn: @conn %>

<%= gettext("State level") %>

Landesausschuss DSA-Verbund 1

          c/o Peter Seidelmann

          Deutsche Schule Valencia

          c/ Jaime Roig 14, 46010 Valencia

          <%= link "jugendmusiziert@dsvalencia.org", to: "mailto:jugendmusiziert@dsvalencia.org" %>

          Landesausschuss DSA-Verbund 2
          (<%= gettext("responsible for this website") %>)

          c/o <%= link "Robert Bär", to: "mailto:robert.bar@dsh.fi" %>

          Deutsche Schule Helsinki

          Malminkatu 14, 00100 Helsinki

Robert Bär (<%= gettext("chair") %>)

Irene Rieck (<%= gettext("deputy chair") %>)

Martin Richter

Landesausschuss DSA-Verbund 3

          c/o <%= link "Lorenzo Rüdiger", to: "mailto:lorenzorudiger@tiscali.it" %>

          Deutsche Schule Rom

          Via Aurelia Antica 397-403, 00165 Rom

      <%= gettext("Regional-level hosts") %>
      (<%= gettext("currently grouping 2 only") %>)

    <%= render "_accordion.html",
      id: "hosts-accordion",
      items: Enum.map(@hosts, &to_accordion_item/1)
    %>

<%= gettext("Privacy") %>

      <%= gettext("To find out how we process your data, please see our") %>
      <%= link gettext("privacy policy"), to: Routes.page_path(@conn, :privacy) %>.

<%= gettext("Contact") %>

  <%= gettext("Here is how you can get in touch with us.") %>

<%= gettext("Message us") %>

      <%= gettext("This form is for contacting the international committee of Grouping 2.") %>

      <%= gettext("For questions about local contests, consider contacting your local Jumu organizer (see list below).") %>

    <%= render "_contact_form.html", conn: @conn %>

<%= gettext("State level") %>

Landesausschuss DSA-Verbund 1

          c/o Peter Seidelmann

          Deutsche Schule Valencia

          c/ Jaime Roig 14, 46010 Valencia

          <%= link "jugendmusiziert@dsvalencia.org", to: "mailto:jugendmusiziert@dsvalencia.org" %>

          Landesausschuss DSA-Verbund 2
          (<%= gettext("responsible for this website") %>)

          c/o <%= link "Robert Bär", to: "mailto:robert.bar@dsh.fi" %>

          Deutsche Schule Helsinki

          Malminkatu 14, 00100 Helsinki

Robert Bär (<%= gettext("chair") %>)

Irene Rieck (<%= gettext("deputy chair") %>)

Joonas Ruppel

Martin Richter

Landesausschuss DSA-Verbund 3

          c/o <%= link "Lorenzo Rüdiger", to: "mailto:lorenzorudiger@tiscali.it" %>

          Deutsche Schule Rom

          Via Aurelia Antica 397-403, 00165 Rom

      <%= gettext("Regional-level hosts") %>
      (<%= gettext("currently grouping 2 only") %>)

    <%= render "_accordion.html",
      id: "hosts-accordion",
      items: Enum.map(@hosts, &to_accordion_item/1)
    %>

<%= gettext("Privacy") %>

      <%= gettext("To find out how we process your data, please see our") %>
      <%= link gettext("privacy policy"), to: Routes.page_path(@conn, :privacy) %>.