after multiple experimental versions and considering the need for more metadata in the future, label will be now used for an indicaton of an author

  <%= for post <- @posts do %>
  <% img_src = hd(post.json_metadata["image"]) %>

      <a href="/posts/<%= post.permlink %>"> <img src="<%= img_src %>">

        @<%= post.author  %>

        <a class="header" href="/posts/<%= post.permlink %>"> <%= post.title %>

          <%= for tag <- post.tags do %>
          <a class="ui  label" href="/tags/<%=tag%>">
            <%= format_tag(tag, @conn.assigns.lang) %>

          <% end %>

    <% end %>

      <%= for {v, i} <- generate_pagination_list(@current_page) do %>

      <a class="<%=if i == @current_page, do: "active" %> item"
        href="<%= @conn.request_path <> "?" <> URI.encode_query(%{"page"=> v}) %>">
        <%= v %>

      <% end %>

  <%= for post <- @posts do %>
  <% img_src = hd(post.json_metadata["image"]) %>

      <a href="/posts/<%= post.permlink %>"> <img src="<%= img_src %>">

<%= format_tag(post.category, @conn.assigns.lang) %>

      <a class="header" href="/posts/<%= post.permlink %>"> <%= post.title %>

           Author

          <%= for tag <- post.tags do %>
          <a class="ui  label" href="/tags/<%=tag%>">
            <%= format_tag(tag, @conn.assigns.lang) %>

          <% end %>

    <% end %>

      <%= for {v, i} <- generate_pagination_list(@current_page) do %>

      <a class="<%=if i == @current_page, do: "active" %> item"
        href="<%= @conn.request_path <> "?" <> URI.encode_query(%{"page"=> v}) %>">
        <%= v %>

      <% end %>


Restore disabled empty contest category option in registration form

Submitting an empty form with the selected option being disabled causes the "performance" form data to be omitted, which we prevent by adding a dummy hidden field containing no actual data.

  <%= gettext("Register") %>

  <%= name_with_flag(@contest) %>

    <%= form_for @changeset, performance_path(@conn, :create, @contest), fn _ -> %>

      <input type="hidden" name="performance[]" value="" />

      <%= render "_form_error_summary.html" %>

            <%= gettext("Category") %>

          <select
            id="performance_contest_category_id"
            name="performance[contest_category_id]"
            class="form-control"
            v-model="contest_category_id"
            v-on:change="contestCategoryChanged">
            <option disabled value=""><%= gettext("Please choose") %></option>
            <option
              v-for="option in contest_category_options"
              v-bind:value="option.id"
              v-text="option.name">
            </option>
          </select>
          <form-field-error v-bind:errors="errors.contest_category_id" />

<%= gettext("Participants") %>

        <%= render "_appearance_panels.html" %>

      <button type="button" class="btn btn-link" v-on:click="addAppearance()">
        <%= icon_tag("plus") %> <%= gettext("Add participant") %>
      </button>

<%= gettext("Pieces") %>

        <%= render "_piece_panels.html" %>

      <button type="button" class="btn btn-link" v-on:click="addPiece()">
        <%= icon_tag("plus") %> <%= gettext("Add piece") %>
      </button>

      <%= submit class: "btn btn-primary pull-right" do %>
        <%= gettext("Submit registration") %> <%= icon_tag("send") %>
      <% end %>
    <% end %>

  <%= gettext("Register") %>

  <%= name_with_flag(@contest) %>

    <%= form_for @changeset, performance_path(@conn, :create, @contest), fn _ -> %>
      <%= render "_form_error_summary.html" %>

            <%= gettext("Category") %>

          <select
            id="performance_contest_category_id"
            name="performance[contest_category_id]"
            class="form-control"
            v-model="contest_category_id"
            v-on:change="contestCategoryChanged">
            <option value=""><%= gettext("Please choose") %></option>
            <option
              v-for="option in contest_category_options"
              v-bind:value="option.id"
              v-text="option.name">
            </option>
          </select>
          <form-field-error v-bind:errors="errors.contest_category_id" />

<%= gettext("Participants") %>

        <%= render "_appearance_panels.html" %>

      <button type="button" class="btn btn-link" v-on:click="addAppearance()">
        <%= icon_tag("plus") %> <%= gettext("Add participant") %>
      </button>

<%= gettext("Pieces") %>

        <%= render "_piece_panels.html" %>

      <button type="button" class="btn btn-link" v-on:click="addPiece()">
        <%= icon_tag("plus") %> <%= gettext("Add piece") %>
      </button>

      <%= submit class: "btn btn-primary pull-right" do %>
        <%= gettext("Submit registration") %> <%= icon_tag("send") %>
      <% end %>
    <% end %>


Remove unclear sentence from FAQ

Remove unclear sentence from FAQ

    <%= gettext "Cookies" %>
    <%= anchor_link("cookies") %>

  <%= if @site.data.cookie_count.first_party > 0 do %>
    <%= render "_cookie_table.html", amount: @site.data.cookie_count.first_party, cookies: @site.data.cookies.first_party, label: gettext("First-party cookies"), id: "cookies-first" %>
  <% end %>

  <%= if @site.data.cookie_count.third_party > 0 do %>
    <%= render "_cookie_table.html", amount: @site.data.cookie_count.third_party , cookies: @site.data.cookies.third_party, label: gettext("Third-party cookies"), id: "cookies-third" %>
  <% end %>

  <%= if (@site.data.cookie_count.first_party + @site.data.cookie_count.third_party) > 0 do %>

<%= gettext(~s|HttpOnly means that the cookie can only be read by the server, and not by JavaScript on the client. This can mitigate XSS (cross-site scripting) attacks.|) |> raw() %>

<%= gettext(~s|Secure means that the cookie will only be sent over a secure channel (HTTPS). This can mitigate MITM (man-in-the-middle) attacks.|) |> raw() %>

<%= gettext(~s|SameSite can be used to instruct the browser to only send the cookie when the request is originating from the same site. This can mitigate CSRF (cross-site request forgery) attacks.|) |> raw() %>

  <% else %>

<%= gettext(~s|No cookies detected.|) %>

  <% end %>

<%= icon(:law) %> GDPR: <%= [~w|rec 60|, ~w|rec 61|, ~w|rec 69|, ~w|rec 70|, ~w|rec 75|, ~w|rec 78|, ~w|art 5 5.1.a|, ~w|art 5 5.1.c|, ~w|art 5 5.1.e|, ~w|art 21|, ~w|art 22|, ~w|art 32|] |> gdpr() |> raw() %>.

<%= link "e-PD (2002/58/EC)", to: "https://eur-lex.europa.eu/eli/dir/2002/58/oj" %>. Rec. 24, 25, Art. 5.2.

<%= link "e-PD revised (2009/136/EC)", to: "https://eur-lex.europa.eu/eli/dir/2009/136/oj" %>. Rec. 65, 66.

      <%= gettext("More information") %>

        <%= gettext(~s|First-party cookies are placed by the web site owner in some register on their visitors' device in order to be able to re-identify the visitor on subsequent page loads. First-party cookies can be related to technical features on a web site (such as remembering language settings or the contents of a shopping basket), or related to commercial features of the web site owners' activities (such as being able to trace a visitors' behaviour over the duration of their visit, or over much longer time periods, often for years, in order to be able to serve advertisements to the users or to get usage statistics to guide later changes to the web site that are envisaged to make the web site more attractive to recurring users). First-party cookies may come from services provided by the web site owner (language settings in a Content Management System) or from services used by the web site owner (analytics tools).|) |> raw() %>

        <%= gettext(~s|Third-party cookies are placed by a service affiliated with the web site owner on the devices of visitors to the web site in order to be able to re-identity the visitor on subsequent page loads, or across different web sites. Third-party cookies are typically related to commercial features of a web site owners' activities, usually advertising, but may also relate to technical features in scripts used by a web site (such as language settings).|) |> raw() %>

        <%= gettext(~s|Storing information or gaining access to information stored in the visitors' devices, for instance in the form of cookies, has been subject to sui generis legislation in the European Union (ePD, Art. 5.3). These sui generis laws have tried to make a distinction between information stored to support technical features and information stored to support commercial features. In practice, poor enforcement of these rules has made the legal landscape unclear. Because there exists no legal duty for citizens to receive better targeted advertisement, nor a legal duty for citizens to assist web developers in improving web sites, it's doubtful that a legal basis exists for storing information to support commercial features without the consent of the web visitor (GDPR %{gdpr_art_7}). It is argued that the legitimate interests of a web site owner (%{gdpr_art_6_1_f}, %{gdpr_art_6_4}) may nevertheless enable them to subject a visitor to targeted ads or cause a visitor to assist the web developers. In either case, if the legitimate interest legal basis for processing is invoked, adequate security measures must be undertaken (GDPR %{gdpr_art_32}).|,
        epd: "https://eur-lex.europa.eu/eli/dir/2002/58/oj",
        gdpr_art_7: gdpr(~w|art 7|),
        gdpr_art_6_1_f: gdpr(~w|art 6 6.1.f|),
        gdpr_art_6_4: gdpr(~w|art 6 6.4|),
        gdpr_rec_47: gdpr(~w|rec 46 47|),
        gdpr_art_32: gdpr(~w|art 32|)
        ) |> raw() %>

        <%= gettext(~s|Particular care must be taken with regards to the period of storage (GDPR %{gdpr_art_5_1_e}). While it is technically easy for a web site owner to set the duration of a information stored in the form of cookies to a long period time, the principle of storage limitation implies a balancing act between the interest of tracking a visitors' behaviour and the interest of the visitor to keep their behaviour private. It's been established that a reasonable storage period does not exceed one year.|,
        gdpr_art_5_1_e: gdpr(~w|art 5 5.1.e|),
        ec_cookies: "http://ec.europa.eu/ipg/basics/legal/cookies/index_en.htm"
        ) |> raw() %>

    <%= gettext "Cookies" %>
    <%= anchor_link("cookies") %>

  <%= if @site.data.cookie_count.first_party > 0 do %>
    <%= render "_cookie_table.html", amount: @site.data.cookie_count.first_party, cookies: @site.data.cookies.first_party, label: gettext("First-party cookies"), id: "cookies-first" %>
  <% end %>

  <%= if @site.data.cookie_count.third_party > 0 do %>
    <%= render "_cookie_table.html", amount: @site.data.cookie_count.third_party , cookies: @site.data.cookies.third_party, label: gettext("Third-party cookies"), id: "cookies-third" %>
  <% end %>

  <%= if (@site.data.cookie_count.first_party + @site.data.cookie_count.third_party) > 0 do %>

<%= gettext(~s|HttpOnly means that the cookie can only be read by the server, and not by JavaScript on the client. This can mitigate XSS (cross-site scripting) attacks.|) |> raw() %>

<%= gettext(~s|Secure means that the cookie will only be sent over a secure channel (HTTPS). This can mitigate MITM (man-in-the-middle) attacks.|) |> raw() %>

<%= gettext(~s|SameSite can be used to instruct the browser to only send the cookie when the request is originating from the same site. This can mitigate CSRF (cross-site request forgery) attacks.|) |> raw() %>

  <% else %>

<%= gettext(~s|No cookies detected.|) %>

  <% end %>

<%= icon(:law) %> GDPR: <%= [~w|rec 60|, ~w|rec 61|, ~w|rec 69|, ~w|rec 70|, ~w|rec 75|, ~w|rec 78|, ~w|art 5 5.1.a|, ~w|art 5 5.1.c|, ~w|art 5 5.1.e|, ~w|art 21|, ~w|art 22|, ~w|art 32|] |> gdpr() |> raw() %>.

<%= link "e-PD (2002/58/EC)", to: "https://eur-lex.europa.eu/eli/dir/2002/58/oj" %>. Rec. 24, 25, Art. 5.2.

<%= link "e-PD revised (2009/136/EC)", to: "https://eur-lex.europa.eu/eli/dir/2009/136/oj" %>. Rec. 65, 66.

      <%= gettext("More information") %>

        <%= gettext(~s|First-party cookies are placed by the web site owner in some register on their visitors' device in order to be able to re-identify the visitor on subsequent page loads. First-party cookies can be related to technical features on a web site (such as remembering language settings or the contents of a shopping basket), or related to commercial features of the web site owners' activities (such as being able to trace a visitors' behaviour over the duration of their visit, or over much longer time periods, often for years, in order to be able to serve advertisements to the users or to get usage statistics to guide later changes to the web site that are envisaged to make the web site more attractive to recurring users). First-party cookies may come from services provided by the web site owner (language settings in a Content Management System) or from services used by the web site owner (analytics tools).|) |> raw() %>

        <%= gettext(~s|Third-party cookies are placed by a service affiliated with the web site owner on the devices of visitors to the web site in order to be able to re-identity the visitor on subsequent page loads, or across different web sites. Third-party cookies are typically related to commercial features of a web site owners' activities, usually advertising, but may also relate to technical features in scripts used by a web site (such as language settings).|) |> raw() %>

        <%= gettext(~s|Storing information or gaining access to information stored in the visitors' devices, for instance in the form of cookies, has been subject to sui generis legislation in the European Union (ePD, Art. 5.3). These sui generis laws have tried to make a distinction between information stored to support technical features and information stored to support commercial features. In practice, poor enforcement of these rules has made the legal landscape unclear. Because there exists no legal duty for citizens to receive better targeted advertisement, nor a legal duty for citizens to assist web developers in improving web sites, it's doubtful that a legal basis exists for storing information to support commercial features without the consent of the web visitor (GDPR %{gdpr_art_7}). It is argued that the legitimate interests of a web site owner (%{gdpr_art_6_1_f}, %{gdpr_art_6_4}) may nevertheless enable them to subject a visitor to targeted ads or cause a visitor to assist the web developers. Then there must exist relevant and appropriate relationship between the web visitor and the web site owner in situations (GDPR %{gdpr_rec_47}), which calls into question the use of third-party service first-party cookies. In either case, if the legitimate interest legal basis for processing is invoked, adequate security measures must be undertaken (GDPR %{gdpr_art_32}).|,
        epd: "https://eur-lex.europa.eu/eli/dir/2002/58/oj",
        gdpr_art_7: gdpr(~w|art 7|),
        gdpr_art_6_1_f: gdpr(~w|art 6 6.1.f|),
        gdpr_art_6_4: gdpr(~w|art 6 6.4|),
        gdpr_rec_47: gdpr(~w|rec 46 47|),
        gdpr_art_32: gdpr(~w|art 32|)
        ) |> raw() %>

        <%= gettext(~s|Particular care must be taken with regards to the period of storage (GDPR %{gdpr_art_5_1_e}). While it is technically easy for a web site owner to set the duration of a information stored in the form of cookies to a long period time, the principle of storage limitation implies a balancing act between the interest of tracking a visitors' behaviour and the interest of the visitor to keep their behaviour private. It's been established that a reasonable storage period does not exceed one year.|,
        gdpr_art_5_1_e: gdpr(~w|art 5 5.1.e|),
        ec_cookies: "http://ec.europa.eu/ipg/basics/legal/cookies/index_en.htm"
        ) |> raw() %>


ref: added an rel=me link to chaos.social

<img src="<%= static_path(@conn, "/images/christian-kruse.jpg") %>" alt="" class="u-photo big">

Christian Kruse

      My name is Christian Kruse. I work as a software developer and
      system administator at <%= link "Termitel GmbH", to: "https://termitel.de/" %>.
      I live in Germany in a small town called
      <%= link "Steinfurt", to: "https://en.wikipedia.org/wiki/Steinfurt" %>.

      I am passionate about software development,
      <%= link "GNU/Linux", to: "https://en.wikipedia.org/wiki/Linux" %>,
      <%= link "FLOSS", to: "https://en.wikipedia.org/wiki/Free_and_open-source_software" %>
      as well as <%= link "OS X", to: "https://en.wikipedia.org/wiki/OS_X" %>.
      I am also a do-it-yourself apologetic: I did a lot of things in and
      around my house myself. I love the hacker culture. And last but not
      least I am a dog owner.

      This is my personal replacement for Twitter, Facebook and the other
      data silos. <%= link "My content is mine", to: "http://indiewebcamp.com/" %>
      — so if you are interested in my activity, just have a look at this
      page.

      All content on this site is available under
      CC BY-SA 3.0.

      <img src="<%= static_path(@conn, "/images/cc-commons-badge.png") %>" width="80" height="15" alt="IndieWebCamp" class="badge">
      <img src="<%= static_path(@conn, "/images/indieweb-badge.png") %>" width="80" height="15" alt="IndieWebCamp" class="badge">
      <img src="<%= static_path(@conn, "/images/webmention-badge.png") %>" width="80" height="15" alt="WebMentions" class="badge">
      <img src="<%= static_path(@conn, "/images/microformats-badge.png") %>" width="80" height="15" alt="Microformats" class="badge">

Personal information

Address

Christian Kruse

Friedenau 35

48565 Steinfurt

Germany

Email

<%= link "cjk@defunct.ch", to: "mailto:cjk@defunct.ch", class: "u-email" %>

Jabber

<%= link "cjk@defunct.ch", to: "xmpp:cjk@defunct.ch", class: "u-url" %>

PGP

A99A9D73

BC5D 9F4E F7FB 4382 6056  E834 B8E0 F342 A99A 9D73

<%= link "wwwtech.de/A99A9D73.asc", to: "/A99A9D73.asc" %>

Please send me encrypted mails if possible (see my public key above). Every
    bit of encrypted traffic increases the encrypted background noise
    and thus makes it harder to distinguish between important and
    unimportant traffic.

Social media

I also take part in several social services:

<%= link "forum.selfhtml.org/users/1", to: "http://forum.selfhtml.org/users/1", rel: "me" %> on SELFHTML

<%= link "https://chaos.social/@cjk101010", to: "https://chaos.social/@cjk101010", rel: "me" %> on Mastodon</>

<%= link "@cjk101010", to: "https://twitter.com/cjk101010", rel: "me" %> on Twitter

<%= link "github.com/ckruse", to: "https://github.com/ckruse", rel: "me" %> on Github

<%= link "flattr.com/profile/cjk", to: "https://flattr.com/profile/cjk", rel: "me" %> on Flattr

<%= link "www.reddit.com/user/cjk101010/", to: "https://www.reddit.com/user/cjk101010/", rel: "me" %> on Reddit

<%= link "news.ycombinator.com/user?id=cjk101010", to: "https://news.ycombinator.com/user?id=cjk101010", rel: "me" %> on Hackernews

<%= link "keybase.io/ckruse", to: "https://keybase.io/ckruse", rel: "me" %> on Keybase.io

<%= link "stackoverflow.com/users/785998/ckruse", to: "http://stackoverflow.com/users/785998/ckruse", rel: "me" %> on StackOverflow

<img src="<%= static_path(@conn, "/images/christian-kruse.jpg") %>" alt="" class="u-photo big">

Christian Kruse

      My name is Christian Kruse. I work as a software developer and
      system administator at <%= link "Termitel GmbH", to: "https://termitel.de/" %>.
      I live in Germany in a small town called
      <%= link "Steinfurt", to: "https://en.wikipedia.org/wiki/Steinfurt" %>.

      I am passionate about software development,
      <%= link "GNU/Linux", to: "https://en.wikipedia.org/wiki/Linux" %>,
      <%= link "FLOSS", to: "https://en.wikipedia.org/wiki/Free_and_open-source_software" %>
      as well as <%= link "OS X", to: "https://en.wikipedia.org/wiki/OS_X" %>.
      I am also a do-it-yourself apologetic: I did a lot of things in and
      around my house myself. I love the hacker culture. And last but not
      least I am a dog owner.

      This is my personal replacement for Twitter, Facebook and the other
      data silos. <%= link "My content is mine", to: "http://indiewebcamp.com/" %>
      — so if you are interested in my activity, just have a look at this
      page.

      All content on this site is available under
      CC BY-SA 3.0.

      <img src="<%= static_path(@conn, "/images/cc-commons-badge.png") %>" width="80" height="15" alt="IndieWebCamp" class="badge">
      <img src="<%= static_path(@conn, "/images/indieweb-badge.png") %>" width="80" height="15" alt="IndieWebCamp" class="badge">
      <img src="<%= static_path(@conn, "/images/webmention-badge.png") %>" width="80" height="15" alt="WebMentions" class="badge">
      <img src="<%= static_path(@conn, "/images/microformats-badge.png") %>" width="80" height="15" alt="Microformats" class="badge">

Personal information

Address

Christian Kruse

Friedenau 35

48565 Steinfurt

Germany

Email

<%= link "cjk@defunct.ch", to: "mailto:cjk@defunct.ch", class: "u-email" %>

Jabber

<%= link "cjk@defunct.ch", to: "xmpp:cjk@defunct.ch", class: "u-url" %>

PGP

A99A9D73

BC5D 9F4E F7FB 4382 6056  E834 B8E0 F342 A99A 9D73

<%= link "wwwtech.de/A99A9D73.asc", to: "/A99A9D73.asc" %>

Please send me encrypted mails if possible (see my public key above). Every
    bit of encrypted traffic increases the encrypted background noise
    and thus makes it harder to distinguish between important and
    unimportant traffic.

Social media

I also take part in several social services:

<%= link "forum.selfhtml.org/users/1", to: "http://forum.selfhtml.org/users/1", rel: "me" %> on SELFHTML

<%= link "@cjk101010", to: "https://twitter.com/cjk101010", rel: "me" %> on Twitter

<%= link "github.com/ckruse", to: "https://github.com/ckruse", rel: "me" %> on Github

<%= link "flattr.com/profile/cjk", to: "https://flattr.com/profile/cjk", rel: "me" %> on Flattr

<%= link "www.reddit.com/user/cjk101010/", to: "https://www.reddit.com/user/cjk101010/", rel: "me" %> on Reddit

<%= link "news.ycombinator.com/user?id=cjk101010", to: "https://news.ycombinator.com/user?id=cjk101010", rel: "me" %> on Hackernews

<%= link "keybase.io/ckruse", to: "https://keybase.io/ckruse", rel: "me" %> on Keybase.io

<%= link "stackoverflow.com/users/785998/ckruse", to: "http://stackoverflow.com/users/785998/ckruse", rel: "me" %> on StackOverflow


Added new web fonts

Added new web fonts

<!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="ricardo@codeloveandboards.com">

    <title>Hello Kairos!</title>
    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700|Open+Sans:400,700" rel="stylesheet" type="text/css">
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  </head>

  <body>
    <main id="main_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="">
    <meta name="author" content="ricardo@codeloveandboards.com">

    <title>Hello Kairos!</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  </head>

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


Changing title to tx portal

Changing title to tx portal

<!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>Tx Portal</title>
    <!--<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">-->
  </head>

  <body>
    <%= @inner %>
    <!--<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>-->
    <script src="<%= static_path(@conn, "/js/bundle.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="">
    <meta name="author" content="">

    <title>Hello Phoenix!</title>
    <!--<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">-->
  </head>

  <body>
    <%= @inner %>
    <!--<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>-->
    <script src="<%= static_path(@conn, "/js/bundle.js") %>"></script>
  </body>
</html>


Only send to channel when moving

Only send to channel when moving

<script src="//cdn.jsdelivr.net/phaser-ce/2.7.3/phaser.min.js"></script>

<script type="text/javascript">

window.onload = function() {

    var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });

    var player
    var cursors
    var player_id
    var player_id_int

    var other_players = []
    var world_state = {}

    function preload () {

        game.load.image('sheep_1', 'images/sheep_1.png');

    }

    function create () {

        game.stage.disableVisibilityChange = true;

        player = game.add.sprite(game.world.centerX, game.world.centerY, 'sheep_1');
        player.anchor.setTo(0.5, 0.5);

        cursors = game.input.keyboard.createCursorKeys();
        player_id_int = Math.floor(Math.random() * 1000)
        player_id = player_id_int.toString()

        channel.push("im_new_here", { player: player_id , position: { x: player.x, y: player.y }})

    }

    function update () {

        if (cursors.left.isDown) {
            player.x -= 4;
        }
        else if (cursors.right.isDown) {
            player.x += 4;
        }

        if (cursors.up.isDown) {
            player.y -= 4;
        }
        else if (cursors.down.isDown) {
           player.y += 4;
        }

        other_players.forEach(function(other_player) {
          var other_player_id = parseInt(other_player.player_id);

          if (other_player_id in world_state) {
            other_player.game_object.x = world_state[other_player_id].x
            other_player.game_object.y = world_state[other_player_id].y
          }
        })

        if (player_id_int in world_state) {
          if (world_state[player_id_int].x != player.x ||
                  world_state[player_id_int].y != player.y ) {
            channel.push("new_position", { player: player_id, position: { x: player.x, y: player.y }})
          }
        }
    }

    function render () {

      game.debug.spriteInfo(player, 32, 32);

    }

    channel.on("update_world", payload => {

      world_state = payload

    })

    channel.on("new_player_joined", payload => {

      var other_player_id = payload.player_id
      var position = payload.position

      var new_player = game.add.sprite(position.x, position.y, 'sheep_1')
      new_player.anchor.setTo(0.5, 0.5)

      other_players.push({player_id: other_player_id, game_object: new_player})

    })

    channel.on("hello_world", payload => {

      Object.keys(payload).forEach(function(key) {
        var new_player = game.add.sprite(payload[key].x, payload[key].y, 'sheep_1')
        new_player.anchor.setTo(0.5, 0.5);

        other_players.push({player_id: key, game_object: new_player})
      })

    })

};

</script>

<script src="//cdn.jsdelivr.net/phaser-ce/2.7.3/phaser.min.js"></script>

<script type="text/javascript">

window.onload = function() {

    var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update, render: render });

    var player
    var cursors
    var player_id

    var other_players = []
    var world_state = {}

    function preload () {

        game.load.image('sheep_1', 'images/sheep_1.png');

    }

    function create () {

        game.stage.disableVisibilityChange = true;

        player = game.add.sprite(game.world.centerX, game.world.centerY, 'sheep_1');
        player.anchor.setTo(0.5, 0.5);

        cursors = game.input.keyboard.createCursorKeys();
        player_id = Math.floor(Math.random() * 1000).toString();

        channel.push("im_new_here", { player: player_id , position: { x: player.x, y: player.y }})

    }

    function update () {

        if (cursors.left.isDown) {
            player.x -= 4;
        }
        else if (cursors.right.isDown) {
            player.x += 4;
        }

        if (cursors.up.isDown) {
            player.y -= 4;
        }
        else if (cursors.down.isDown) {
           player.y += 4;
        }

        other_players.forEach(function(other_player) {
          var other_player_id = parseInt(other_player.player_id);

          if (other_player_id in world_state) {
            other_player.game_object.x = world_state[other_player_id].x
            other_player.game_object.y = world_state[other_player_id].y
          }
        })

        channel.push("new_position", { player: player_id, position: { x: player.x, y: player.y }})

    }

    function render () {

      game.debug.spriteInfo(player, 32, 32);

    }

    channel.on("update_world", payload => {

      world_state = payload

    })

    channel.on("new_player_joined", payload => {

      var other_player_id = payload.player_id
      var position = payload.position

      var new_player = game.add.sprite(position.x, position.y, 'sheep_1')
      new_player.anchor.setTo(0.5, 0.5)

      other_players.push({player_id: other_player_id, game_object: new_player})

    })

    channel.on("hello_world", payload => {

      Object.keys(payload).forEach(function(key) {
        var new_player = game.add.sprite(payload[key].x, payload[key].y, 'sheep_1')
        new_player.anchor.setTo(0.5, 0.5);

        other_players.push({player_id: key, game_object: new_player})
      })

    })

};

</script>


Added MS site verify

Added MS site verify

<!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">

    <%= render_existing(@view_module, "meta." <> @view_template, assigns) || render(Ap.LayoutView, "meta.html", assigns) %>

    <link rel="stylesheet" href="<%= static_path(@conn, "/css/frontend.css") %>">
    <link rel="dns-prefetch" href="//res.cloudinary.com">

    <%= render Ap.LayoutView, "common_social_meta.html" %>
    <%= render_existing(@view_module, "social_meta." <> @view_template, assigns) || render(Ap.LayoutView, "social_meta.html", assigns) %>

    <link rel="icon" href="/favicon.ico" />
    <link rel="icon" href="/images/favicon.png" sizes="16x16" type="image/png">

    <meta name="msvalidate.01" content="3F3F0DA3D9FF8AE3DA64D767717C782B" />

    <%= render Ap.SharedView, "header.html", conn: @conn, product_categories: @product_categories %>

          <%= show_flash(@conn) %>
          <%= render @view_module, @view_template, assigns %>

    <%= render Ap.SharedView, "footer.html", conn: @conn %>

<!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">

    <%= render_existing(@view_module, "meta." <> @view_template, assigns) || render(Ap.LayoutView, "meta.html", assigns) %>

    <link rel="stylesheet" href="<%= static_path(@conn, "/css/frontend.css") %>">
    <link rel="dns-prefetch" href="//res.cloudinary.com">

    <%= render Ap.LayoutView, "common_social_meta.html" %>
    <%= render_existing(@view_module, "social_meta." <> @view_template, assigns) || render(Ap.LayoutView, "social_meta.html", assigns) %>

    <link rel="icon" href="/favicon.ico" />
    <link rel="icon" href="/images/favicon.png" sizes="16x16" type="image/png">

    <%= render Ap.SharedView, "header.html", conn: @conn, product_categories: @product_categories %>

          <%= show_flash(@conn) %>
          <%= render @view_module, @view_template, assigns %>

    <%= render Ap.SharedView, "footer.html", conn: @conn %>


Update new.html.eex (#77)

Update new.html.eex (#77)

h1 New <%= schema.human_singular %>

= render "form.html", Map.put(assigns, :action, Routes.<%= schema.route_helper %>_path(@conn, :create))

span= link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index)

h1 New <%= schema.human_singular %>

= render "form.html", Map.put(assigns, :action, Routes.<%= schema.singular %>_path(@conn, :create))

span= link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index)


update docker base image

update docker base image

<%= if @docker do %>FROM elixir:1.7.3

# NOTE the WORKDIR should not be the users home dir as the will copy container cookie into host machine
WORKDIR /opt/app

# Add tools needed for development
# inotify-tools: gives filesystem events that are used to trigger recompilation
<%= if @node_assets do %>RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -<% end %>
RUN apt-get update && apt-get install -y inotify-tools <%= if @node_assets do %>nodejs<% end %>

# Build hex and rebar as a separate Docker layer
RUN mix local.hex --force && mix local.rebar --force

# Build all dependencies separately to the application code
RUN mkdir config
COPY config/* config/
COPY mix.* ./
RUN mix do deps.get, deps.compile

# Add application code as final layer
COPY . .

CMD ["sh", "./bin/start.sh"]
<% end %>

<%= if @docker do %>FROM elixir:1.6.4

# NOTE the WORKDIR should not be the users home dir as the will copy container cookie into host machine
WORKDIR /opt/app

# Add tools needed for development
# inotify-tools: gives filesystem events that are used to trigger recompilation
<%= if @node_assets do %>RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -<% end %>
RUN apt-get update && apt-get install -y inotify-tools <%= if @node_assets do %>nodejs<% end %>

# Build hex and rebar as a separate Docker layer
RUN mix local.hex --force && mix local.rebar --force

# Build all dependencies separately to the application code
RUN mkdir config
COPY config/* config/
COPY mix.* ./
RUN mix do deps.get, deps.compile

# Add application code as final layer
COPY . .

CMD ["sh", "./bin/start.sh"]
<% end %>


Remove new line from core page/index template


fix link to post

fix link to post

  <%= for post <- @posts do %>
  <% img_src = hd(post.json_metadata["image"]) %>

        <a href="/posts/<%= post.permlink %>"> <img src="<%= img_src %>">

        <a class="header" href="/posts/<%= post.permlink %>"> <%= post.title %>

            <%= for tag <- post.tags do %>
              <a class="ui  label" href="/tags/<%=tag%>">
                <%= format_tag(tag, @conn.assigns.lang) %>

            <% end %>

  <% end %>

      <%= for {v, i} <- generate_pagination_list(@current_page) do %>

        <a class="<%=if i == @current_page, do: "active" %> item"
           href="<%= @conn.request_path <> "?" <> URI.encode_query(%{"page"=> v}) %>">
          <%= v %>

      <% end %>

  <%= for post <- @posts do %>
  <% img_src = hd(post.json_metadata["image"]) %>

        <a href="/post/<%= post.permlink %>"> <img src="<%= img_src %>">

        <a class="header" href="/posts/<%= post.permlink %>"> <%= post.title %>

            <%= for tag <- post.tags do %>
              <a class="ui  label" href="/tags/<%=tag%>">
                <%= format_tag(tag, @conn.assigns.lang) %>

            <% end %>

  <% end %>

      <%= for {v, i} <- generate_pagination_list(@current_page) do %>

        <a class="<%=if i == @current_page, do: "active" %> item"
           href="<%= @conn.request_path <> "?" <> URI.encode_query(%{"page"=> v}) %>">
          <%= v %>

      <% end %>


:put_litter_in_its_place: (#120)

:put_litter_in_its_place: (#120)

<script src="<%= static_path(@conn, "/js/app.js") %>"></script>
<script>
<%= @javascript %>
require("web/static/js/app").Experiment("<%= @topic %>", "<%= @token %>", _root)
</script>


Use correct path for link to logo

Use correct path for link to logo

<!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="Teaching animal reservation system">
    <meta name="author" content="Brian Marick">

    <title>Critter4Us</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">

          <a class="nav-item" href="<%= assigns.layout_data.left_picture_path %>">

            <%= assigns.layout_data.user  %>

          <%= Enum.map(assigns.layout_data.links, &raw/1) %>

      <%= v2_flash(@conn) %>
      <%= render @view_module, @view_template, assigns %>

            Copyright © 2016 Brian Marick

          <%= Eecrit.Version.version %>

          <a href="<%= unfinished_path(@conn, :index)%>">
            Terms and Disclaimer

  <%= @eecrit_spa_launcher %>


Remove old sponsorship page

Remove old sponsorship page

Erlang Ecosystem Foundation – Sponsorship Working Group Proposal

Working Group Name

Sponsorship

Mission Statement

Approve sponsors candidacy

Main Objectives

Approve sponsors according to the policy defined by the board and approved by the members…

Encourage foundation outreach to potential sponsors…

Benefits to the community

Ensure that the sponsors adhere to the Foundation Values.

Validate the sponsorship tiers

Provide sponsor information to the secretary for the billing and administrative tasks

Provide sponsor information to the marketing group for communication purposes

Short term deliverables

Approve Founder sponsors

Long term deliverables

Approve sponsors.

Maintain institutional memory of outreach to potential, current and historical sponsors.

Why does this group require the Foundation

Sponsorships help the Erlang Ecosystem worldwide by supporting sprints, meetups, community events and projects, and of course, software development and open source projects. All of these initiatives help improve the Erlang Ecosystem community and Erlang Ecosystem tools that are used daily. This work can’t be done without the generous financial support that sponsor organizations provide to the foundation.

Initial list of volunteers

Francesco Cesarini

Benoît Chesneau

Miriam Pena

Peer Stritzinger

Sebastian Strollo

Alistair Woodman


Better local preview for text-only emails (#622)

When viewing an email message in the Bamboo.LocalAdapter's SentEmailViewerPlug, an iframe for the HTML preview is always shown and always configured to take up the whole available screen height.

This is nice in most cases. But for some internal email notifications we are happy with only the text variant. For these messages, the HTML preview is always empty and the real content is only available after scrolling down.

This commit makes the local preview more compact for messages that have no HTML body.

It also adds color to the headings "HTML body" and "Text body" so they're more clearly visible.

Co-authored-by: Raffael Krebs <0bac591ce70b53e11f3aa7b3781fa05661187013@protonmail.ch>

<!DOCTYPE html>

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

    <title>Sent Email</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.0.0/normalize.css" charset="utf-8">

        <%= for email <- @emails do %>
          <a
            class="email-summary <%= Bamboo.SentEmailViewerPlug.Helper.selected_email_class(email, @selected_email) %>"
            href="<%= "#{@base_path}/#{Bamboo.SentEmail.get_id(email)}" %>">
            <span class="email-summary-subject truncate" title="<%= Bamboo.SentEmailViewerPlug.Helper.format_subject(email.subject) %>">
              <%= Bamboo.SentEmailViewerPlug.Helper.format_subject(email.subject) %>

              <%= Bamboo.SentEmailViewerPlug.Helper.format_email_address(email.from) %>
              to <%= Bamboo.SentEmailViewerPlug.Helper.email_addresses(email) %>

              <%= if Enum.count(email.attachments) > 0 do %><% end %>
              <%= Bamboo.SentEmailViewerPlug.Helper.format_text_body(email.text_body) %>

        <% end %>

          <%= Bamboo.SentEmailViewerPlug.Helper.format_subject(@selected_email.subject) %>

            From <%= Bamboo.SentEmailViewerPlug.Helper.format_email_address(@selected_email.from) %>
            to <%= Bamboo.SentEmailViewerPlug.Helper.email_addresses(@selected_email) %>

            <%= for {header, value} <- @selected_email.headers do %>

                <%= header %> <%= Bamboo.SentEmailViewerPlug.Helper.format_headers(value) %>

            <% end %>

          <% attachment_count = Enum.count(@selected_email.attachments) %>
          <%= if  attachment_count > 0 do %>

              <%= for index <- 0..attachment_count - 1 do %>
                <%
                  attachment = Enum.at(@selected_email.attachments, index)
                  href = "#{@base_path}/#{Bamboo.SentEmail.get_id(@selected_email)}/attachments/#{index}"
                %>

<a href="<%= href %>"><%= Bamboo.SentEmailViewerPlug.Helper.format_attachment(attachment) %>

              <% end %>

          <% end %>

          <%= if @selected_email.html_body do %>

HTML body

              <iframe onload="adjustFrameHeight(this)" src="<%= "#{@base_path}/#{Bamboo.SentEmail.get_id(@selected_email)}/html" %>">

          <% else %>

No HTML body

          <% end %>

          <%= if @selected_email.text_body do %>

Text body

<%= Bamboo.SentEmailViewerPlug.Helper.format_text_body(@selected_email.text_body) %>

          <% else %>

No text body

          <% end %>

<!DOCTYPE html>

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

    <title>Sent Email</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.0.0/normalize.css" charset="utf-8">

        <%= for email <- @emails do %>
          <a
            class="email-summary <%= Bamboo.SentEmailViewerPlug.Helper.selected_email_class(email, @selected_email) %>"
            href="<%= "#{@base_path}/#{Bamboo.SentEmail.get_id(email)}" %>">
            <span class="email-summary-subject truncate" title="<%= Bamboo.SentEmailViewerPlug.Helper.format_subject(email.subject) %>">
              <%= Bamboo.SentEmailViewerPlug.Helper.format_subject(email.subject) %>

              <%= Bamboo.SentEmailViewerPlug.Helper.format_email_address(email.from) %>
              to <%= Bamboo.SentEmailViewerPlug.Helper.email_addresses(email) %>

              <%= if Enum.count(email.attachments) > 0 do %><% end %>
              <%= Bamboo.SentEmailViewerPlug.Helper.format_text_body(email.text_body) %>

        <% end %>

          <%= Bamboo.SentEmailViewerPlug.Helper.format_subject(@selected_email.subject) %>

            From <%= Bamboo.SentEmailViewerPlug.Helper.format_email_address(@selected_email.from) %>
            to <%= Bamboo.SentEmailViewerPlug.Helper.email_addresses(@selected_email) %>

            <%= for {header, value} <- @selected_email.headers do %>

                <%= header %> <%= Bamboo.SentEmailViewerPlug.Helper.format_headers(value) %>

            <% end %>

          <% attachment_count = Enum.count(@selected_email.attachments) %>
          <%= if  attachment_count > 0 do %>

              <%= for index <- 0..attachment_count - 1 do %>
                <%
                  attachment = Enum.at(@selected_email.attachments, index)
                  href = "#{@base_path}/#{Bamboo.SentEmail.get_id(@selected_email)}/attachments/#{index}"
                %>

<a href="<%= href %>"><%= Bamboo.SentEmailViewerPlug.Helper.format_attachment(attachment) %>

              <% end %>

          <% end %>

HTML body

            <iframe onload="adjustFrameHeight(this)" src="<%= "#{@base_path}/#{Bamboo.SentEmail.get_id(@selected_email)}/html" %>">

Text Body

<%= Bamboo.SentEmailViewerPlug.Helper.format_text_body(@selected_email.text_body) %>


open board in a new tab by default

open board in a new tab by default

  Welcome,
  <%= if String.length(@user[:first]) > 0 do %>
    <%= @user[:first] %>!
  <% else %>
    <%= @user[:email] %>!
  <% end %>

        Whiteboards are ephemeral. There is no guarantee that they'll
        stick around for long periods of time. If they go away, that's
        why.

        Future versions of Whiteboard will not have this limitation.

Boards

    <%= if length(@whiteboards) == 0 do %>

          You have no boards configured.
          Create one using the form on the right →

    <% else %>

      <%= Enum.map @whiteboards, fn(whiteboard) -> %>

          <a href="/whiteboards/<%= whiteboard[:key] %>" target="_blank">
            <%= whiteboard[:name] %>

      <% end %>

    <% end %>

Create Board

    <%= render "create_board_form.html" %>

  Welcome,
  <%= if String.length(@user[:first]) > 0 do %>
    <%= @user[:first] %>!
  <% else %>
    <%= @user[:email] %>!
  <% end %>

        Whiteboards are ephemeral. There is no guarantee that they'll
        stick around for long periods of time. If they go away, that's
        why.

        Future versions of Whiteboard will not have this limitation.

Boards

    <%= if length(@whiteboards) == 0 do %>

          You have no boards configured.
          Create one using the form on the right →

    <% else %>

      <%= Enum.map @whiteboards, fn(whiteboard) -> %>

          <a href="/whiteboards/<%= whiteboard[:key] %>">
            <%= whiteboard[:name] %>

      <% end %>

    <% end %>

Create Board

    <%= render "create_board_form.html" %>


ref: „read more“ link, to indicate that there is more to read

<article class="article h-entry<%= if assigns[:index], do: " index" %><%= unless @article.published, do: " unpublished" %>" lang="<%= @article.lang %>">
  <%= unless assigns[:atom] do %>

<%= link @article.title, to: show_article_path(@conn, @article) %>

      <%= link to: Routes.page_path(@conn, :about), rel: "me" do %><img src="<%= Routes.static_path(@conn, "/images/" <> @article.author.avatar) %>" class="avatar u-photo" alt="">
      <%= @article.author.name %><% end %>
      <time class="dt-published" datetime="<%= Timex.format!(@article.inserted_at, "%FT%T%:z", :strftime) %>">
        <%= link WwwtechWeb.LayoutView.time_ago_in_words(@article.inserted_at), to: show_article_path(@conn, @article), class: "u-url" %></time>

  <% end %>

  <%= if @article.in_reply_to != "" and @article.in_reply_to != nil do %>

      In reply to <%= link @article.in_reply_to, to: @article.in_reply_to, class: "u-in-reply-to", rel: "in-reply-to" %>

  <% end %>

  <%= if @article.posse && !assigns[:index] do %>

  <% end %>

  <%= if !assigns[:atom] && present?(@article.excerpt) do %>

      <%= WwwtechWeb.Converter.to_html(@article, :excerpt) %>

  <% end %>

  <%= if assigns[:index] do %>
    <%= link "Read more…", to: show_article_path(@conn, @article) %>
  <% else %>

      <%= WwwtechWeb.Converter.to_html(@article) %>

  <% end %>

<article class="article h-entry<%= if assigns[:index], do: " index" %><%= unless @article.published, do: " unpublished" %>" lang="<%= @article.lang %>">
  <%= unless assigns[:atom] do %>

<%= link @article.title, to: show_article_path(@conn, @article) %>

      <%= link to: Routes.page_path(@conn, :about), rel: "me" do %><img src="<%= Routes.static_path(@conn, "/images/" <> @article.author.avatar) %>" class="avatar u-photo" alt="">
      <%= @article.author.name %><% end %>
      <time class="dt-published" datetime="<%= Timex.format!(@article.inserted_at, "%FT%T%:z", :strftime) %>">
        <%= link WwwtechWeb.LayoutView.time_ago_in_words(@article.inserted_at), to: show_article_path(@conn, @article), class: "u-url" %></time>

  <% end %>

  <%= if @article.in_reply_to != "" and @article.in_reply_to != nil do %>

      In reply to <%= link @article.in_reply_to, to: @article.in_reply_to, class: "u-in-reply-to", rel: "in-reply-to" %>

  <% end %>

  <%= if @article.posse && !assigns[:index] do %>

  <% end %>

  <%= if !assigns[:atom] && present?(@article.excerpt) do %>

      <%= WwwtechWeb.Converter.to_html(@article, :excerpt) %>

  <% end %>

  <%= unless assigns[:index] do %>

      <%= WwwtechWeb.Converter.to_html(@article) %>

  <% end %>