text:
---
layout: post
title: Pretty Good Setup (PGS)
---

  See original post with 23k views on Medium

For a while I had this security guide written for myself and finally decided to share it with everyone. This post will be a semi-detailed guide on what, why and how to secure your machine. Hope you enjoy it :)

### Full manual
The reason why I called it Pretty Good Setup is that the security of this setup is pretty good for many situations, it’s good for the vast-majority of people and covers a good amount of threats.

#### Table of contents

1. Securing the BIOS
2. Move to user friendly GNU/Linux OS
3. Enable automatic security updates
4. Firewall
5. Browser extensions and settings
6. Cover your camera
7. Install a VPN
8. Use a password manager
9. Use a Virtual Machine
10. Encrypt important files

#### Securing the BIOS
You can’t have a secure setup [1] without a secure core/part of it. The first thing when you make a new system should be securing your BIOS (basic input/output system):

![Example BIOS]({{ site.url }}/public/images/2017/bios-example.jpeg)

First you must set an admin password in your BIOS. As shown above it will stop an attacker [2] from modifying settings, restrict booting from external devices, which protects against modifying the root password. The next step must be to disable booting from external devices to stop the attack mentioned above.

![Example BIOS]({{ site.url }}/public/images/2017/bios-password.png) Now when your PC turns on you might see something like this.

#### Move to user friendly GNU/Linux OS

Move to Ubuntu or any other user friendly GNU/Linux OS

![Example BIOS]({{ site.url }}/public/images/2017/ubuntu.png)

There are fewer malwares written for GNU/Linux Operating systems compared to Windows and by simply switching your OS to Ubuntu you greatly decrease your chances of getting a virus. Also, malware written for Windows generally don’t work on GNU/Linux. For most the switch shouldn’t cause any problems(in my personal opinion) since Ubuntu offers the same functionality as Windows and even looks similar. My mother, who isn't a techie is using Ubuntu on day-to-day basis :)

Whilst installing a new OS (in my example I will use Ubuntu) choose the option to use the full disk encryption:

Full disk encryption ensures that if we lose our machine, the attacker will not be able to read any data from it. More info here. Next follow the steps and create a new account. After it’s done you will have access to a user with sudo rights. You should not use this account for everyday use but create an additional account without any sudo rights:
Search for system settings ->
![Ubuntu settings]({{ site.url }}/public/images/2017/ubuntu-settings.png)
Click on user accounts
![Ubuntu settings]({{ site.url }}/public/images/2017/ubuntu-user.png)
You will see the list of users on your machine

2) Then add another non-Administrative user. It can be done by pressing the + in the lower left corner of the image 1. This is done to protect you from accidentally downloading and executing files, since the user has no sudo right it will be much harder for a virus to get installed.[3] You should use this user on an everyday basis. Before you start using this account on everyday basis it would be a good idea to give this account sudo rights, install all needed programs first, and then switch the account back to standard type. A good practice would be not to install programs from PPA, unless you know what you are doing.

#### Enable automatic security updates
From System Settings open Update Manager. Click the ‘Settings…’ button, then on the ‘Updates’ tab, select the radio button ‘Install security updates without confirmation.’
More at :[https://askubuntu.com/questions/9/how-do-i-enable-automatic-updates](https://askubuntu.com/questions/9/how-do-i-enable-automatic-updates)
![Ubuntu updates]({{ site.url }}/public/images/2017/ubuntu-updates.png)

#### Firewall
In this guide we will be using UFW (Uncomplicated Firewall). It’s a simple to use firewall, which doesn’t require vast knowledge in iptables. The goal of the firewall is to monitor traffic and block unwanted (also malicious) traffic. UFW should be installed by default in the Ubuntu OS and is disabled by default. If it is not installed you can install it by typing this command into the terminal:
sudo apt-get install ufw
One of the things that will make setting up any firewall easier is to define some default rules for allowing and denying connections. UFW’s defaults are to deny all incoming connections and allow all outgoing connections. This means anyone trying to reach your machine would not be able to connect, while any application within the machine would be able to reach the outside world. To set the defaults used by UFW, you would use the following commands:

{% highlight js %}
sudo ufw default deny incoming
sudo ufw default allow outgoing
{% endhighlight %}

Next we need to enable the firewall and can achieve that by typing:

{% highlight js %}
sudo ufw enable
{% endhighlight %}
You should see the command prompt again if all went well. You can check the status of your rules now by typing:
{% highlight js %}
sudo ufw status
{% endhighlight %}
Now you have a working, uncomplicated firewall, which blocks incoming connections and allows outgoing ones. [4]

#### Browser extansions and settings
Most of the current browsers are pretty secure by default, considering your threat is not coming from state agencies. You can make it even more secure by changing settings in the browser and installing security extensions.
1. Install browser plugins
##### uBlock Origin
[https://github.com/gorhill/uBlock/](https://github.com/gorhill/uBlock/) uBlock Origin blocks ads, trackers and malware sites. There are a number of reasons why you would choose uBlock Origin over Adblock Plus, which some might say is more known, some of which are: Adblock Plus sells ads, performance and efficiency.
![uBlock origin]({{ site.url }}/public/images/2017/uBlock.png)

###### uMatrix
https://github.com/gorhill/uMatrix [https://github.com/gorhill/uMatrix](https://github.com/gorhill/uMatrix)
uMatrix allows you to configure how your browser interacts with websites, what those can load etc.
![uMatrix 1]({{ site.url }}/public/images/2017/umatrix_1.png)
Set the setting as follows by clicking on the top part of the block to make a block green and by clicking at the bottom part to make it red. The “\*” in the left corner means that these rules will apply to all websites, unless you have specific rules for particular ones. On the image 1, generally all websites are allowed to load images and css files. When you visit webpages they load Javascript(JS) to enhance its functionality and look. While generally JS loaded is not malicious it could be used to harm your machine. Malicious websites could load bad JS when users visit it, this malicious code infects the users computer with malware or performs unwanted actions on behalf of user \*[5] So it’s better not to allow websites to load JS, and whitelist whitelist the websites you trust so that they can load JS.

![uMatrix 2]({{ site.url }}/public/images/2017/umatrix_2.png)
Explanation of image 2 : Since I trust Medium I allow it to read cookies, allow it to load and run scripts, XHR. Another explanation on how to configure uMatrix: https://github.com/gorhill/uMatrix/wiki/Very-bare-walkthrough-for-first-time-users

2. In your browser set the setting to the following (example shown uses Google Chrome browser):
![Chrome setting 1]({{ site.url }}/public/images/2017/chrome_settings.png)
By blocking sites from setting cookies you improve your privacy
![Chrome setting 2]({{ site.url }}/public/images/2017/chrome_flash.png)
Block Flash and pop-ups (those can still come up without a plugin)
![Chrome setting 3]({{ site.url }}/public/images/2017/chrome_camera.png)
What is happening above: We blocked websites from setting any data, which increases our privacy since websites will not be able to track us, block Flash from being run, which stops many Flash security holes. Even though we block cookies from being set we will need to manage exceptions, ie allow certain websites you trust to set cookies. You can do that by pressing “Manage exceptions” button.
![Chrome setting 4]({{ site.url }}/public/images/2017/chrome_cookies.png)
This what you will see when you click manage exceptions for cookies.
I allowed websites you can see on Image 3 to set cookies and also made exception on uMatrix.

##### Cover your camera

Cover your camera with something e.g. tape. Certain viruses can get access to your machines camera and see what you are doing.

![Camera]({{ site.url }}/public/images/2017/camera_fb.jpeg)

Picture taken from the Guardian article: https://www.theguardian.com/technology/2016/jun/22/mark-zuckerberg-tape-webcam-microphone-facebook

Even though it’s not likely that you will get a virus on your machine, which will be able to access the camera, its better be safe than sorry.

##### Install a VPN

Install a VPN (Virtual private network) In short it secures your traffic from your Internet Service Provider(ISP) by not letting them know what websites you visit and what you do on the Web, bad person on the same network as you in a cafe, on any open access wifi hotspot etc. I will not go into the details how to install one but rather suggest to choose VPN which doesn’t log, though its difficult to check if they do and don’t. One of the main ways to check if your provider logs is to have a look if your VPN provider has received any court orders to release data and what have they provided. If your VPN provider didn’t give any data it’s very likely that their no log policy is real. I personally would support Private Internet Access(PIA). Only get a paid VPN as most free VPN services are probably selling your data, so they’re not worth using.
![VPN]({{ site.url }}/public/images/2017/vpn.png)

How VPN works. Credits: http://blog.flashkirby.com/
Below you can find reviews of VPN providers.

Note that, I am not paid nor connected to any of those providers nor tested them all.
https://torrentfreak.com/best-vpn-anonymous-no-logging/

##### Use a password manager

A password manager is a software application or hardware that helps a user store and organize passwords. Instead of using a simple password like qwerty123 you have a complex unique password for different services. I suggest to use KeePassX  for a number of reasons some of which are: your password database is stored locally, meaning that there is no threat from online service leaking your passwords, saves many different information, whole database is encrypted with the AES (aka Rijndael) encryption algorithm using a 256 bit key.
![Camera]({{ site.url }}/public/images/2017/keepassx.png)
KeePassX logo
![KeePassX]({{ site.url }}/public/images/2017/keepassx_1.png)
Creating a new database
![KeePassX]({{ site.url }}/public/images/2017/keepassx_2.png)
KeePassX allows to generate unique passwords, containing letters, numbers and special characters.

If KeePassX is not installed by default you can install it by running the following command:
{% highlight js %}
sudo apt-get install keepassx
{% endhighlight %}

What it protects from: dictionary attacks, you don’t reuse the same password meaning if a service gets compromised and your password gets leaked an attacker can’t use it to access a different service.

##### Use a Virtual Machine (VM)

In computing, a virtual machine (VM) is an emulation of a computer system. What it means is that you can run another OS on your machine without the need to purchase the additional hardware. In terms of security it provides you an option to run programs, open files you don’t trust and which can contain malicious files without infecting your machine. [6]

![VirtualBox]({{ site.url }}/public/images/2017/vm_1.png)
This is how VirtualBox looks like

You can use VM when you receive emails with attachments, which you were not expecting, ie emails comes from known email but unusual attachment. This attachment could possibly be infected. If you open this attachment in the VM, even if VM OS gets infected, your base OS and all files will be fine. There are many different VM software solutions and you are free to choose the one that you find the best. I personally use VirtualBox.
You can install VirtualBox by running this command:

{% highlight js %}
sudo apt-get install virtualbox-qt
{% endhighlight %}

##### Encrypt important files

It would be a good practice to encrypt your important personal files, which you don’t use on everyday basis, so that even if someone knows your password and steals your machine the attacker would not be able to access those files. To explain: when you use full disk encryption all your files are encrypted and an attacked wouldn’t be able to read files without correct password. But if an attacked finds out your password he/she would be able to access all files. Now say you have some important files you don’t want anyone to access, if you encrypt them and don’t use on everyday basis an attacker who finds your password would not be able to access those files since they require another password. I’d personally recommend using Veracrypt.

![Veracrypt]({{ site.url }}/public/images/2017/veracrypt.png)

I would like to end this guide on explaining what this guide protects from and doesn’t protect from. It protects you when you visit websites on the internet, since even if the website is infected it will not be able to infect your machine. It protects you from data loss through theft, it protects you when you receive malicious files in the emails, it protects you from websites spying on you.

It doesn’t protect you from APT, NSA, someone who saw your password and has access to your machine when you are not present, 0day exploits, if your machine was already infected, bad practices.

[1] In this guide I am not mentioning the threat agent for a number of reasons. For the most users who will be using this guide the threat will likely be coming from random viruses and hackers of a medium skill. It also does not cover a number of things such as compiling your own kernel; securing machine from RAM attacks, Evil maid attack etc since those are not often used in the wild. This guide was not written to secure your machine from APT actors, organised criminal groups and state actors.
[2] You can reset the BIOS passwords in some scenarios: http://www.computerhope.com/issues/ch000235.htm
[3] An attacker can still gain higher level rights from working under non-sudo user.https://en.wikipedia.org/wiki/Privilege_escalation. Also if you are running Wine you can catch viruses written for Windows.
[4] This text about ufw was taken from DO tutorial: https://www.digitalocean.com/community/tutorials/how-to-setup-a-firewall-with-ufw-on-an-ubuntu-and-debian-cloud-server#conclusion
[5] https://heimdalsecurity.com/blog/javascript-malware-explained/
[6] There are exceptions and there were some cases of exploits escaping from VM. Those are very rare, technically compand not used in the wild, since that drops their value. I would not expect an average user to get pwned by a 0day exploit, allowing to escape a VM environment.

The material and information contained in this guide is for educational purposes only. You should not rely upon the material or information provided here as a basis for making any business, legal or any other decisions. I make no representations or warranties of any kind, express or implied about the completeness, accuracy, reliability, suitability or availability with respect to the websites or the information, products, services or related graphics contained in this guide for any purpose. Any reliance you place on such material is therefore strictly at your own risk. I take no responsibility for issues caused by this project or misuse of information given.


text:
# CFPB API Standards

This document captures **CFPB's view of API best practices and standards**. We
aim to incorporate as many of them as possible into our work. This document is based on [18F's API Standards](https://github.com/18F/api-standards).

This document provides a mix of:

* **High level design guidance** that individual APIs interpret to meet their
needs.
* **Low level web practices** that most modern HTTP APIs use.

### Design for common use cases

For APIs that syndicate data, consider several common client use cases:

* **Bulk data.** Clients often wish to establish their own copy of the API's
dataset in its entirety. For example, someone might like to build their own
search engine on top of the dataset, using different parameters and technology
than the "official" API allows. If the API can't easily act as a bulk data
provider, provide a separate mechanism for acquiring the backing dataset in
bulk.
* **Staying up to date.** Especially for large datasets, clients may want to
keep their dataset up to date without downloading the data set after every
change. If this is a use case for the API, prioritize it in the design.
* **Driving expensive actions.** What would happen if a client wanted to
automatically send text messages to thousands of people or light up the side of
a skyscraper every time a new record appears? Consider whether the API's
records will always be in a reliable unchanging order, and whether they tend to
appear in clumps or in a steady stream. Generally speaking, consider the
"entropy" an API client would experience.

### Using one's own API

The #1 best way to understand and address the weaknesses in an API's design and
implementation is to use it in a production system.

Whenever feasible, design an API in parallel with an accompanying integration
of that API.

### Point of contact

Have an obvious mechanism for clients to report issues and ask questions about
the API.

When using GitHub for an API's code, use the associated issue tracker. In
addition, publish an email address for direct, non-public inquiries.

### Notifications of updates

Have a simple mechanism for clients to follow changes to the API.

Common ways to do this include a mailing list, or a
[dedicated developer blog](https://developer.github.com/changes/) with an RSS feed.

### API Endpoints

An "endpoint" is a combination of two things:

* The verb (e.g. `GET` or `POST`)
* The URL path (e.g. `/articles`)

Information can be passed to an endpoint in either of two ways:

* The URL query string (e.g. `?year=2014`)
* HTTP headers (e.g. `X-Api-Key: my-key`)

When people say "RESTful" nowadays, they really mean designing simple,
intuitive endpoints that represent unique functions in the API.

Generally speaking:

* **Avoid single-endpoint APIs.** Don't jam multiple operations into the same
endpoint with the same HTTP verb.
* **Prioritize simplicity.** It should be easy to guess what an endpoint does
by looking at the URL and HTTP verb, without needing to see a query string.
* Endpoint URLs should advertise resources, and **avoid verbs**.

Some examples of these principles in action:

* [CFPB's HMDA API](https://cfpb.github.io/api/hmda/)
* [FBOpen API documentation](https://18f.github.io/fbopen/)
* [OpenFDA example query](https://open.fda.gov/api/reference/#example-query)
* [Sunlight Congress API methods](https://sunlightlabs.github.io/congress/#using-the-api)

### Media Types

#### Use JSON

[JSON](https://en.wikipedia.org/wiki/JSON) is an excellent, widely supported
transport format, suitable for many web APIs.

Supporting JSON and only JSON is a practical default for APIs, and generally
reduces complexity for both the API provider and consumer.

General JSON guidelines:

* Responses should be **a JSON object** (not an array). Using an array to
return results limits the ability to include metadata about results, and limits
the API's ability to add additional top-level keys in the future.
* **Don't use unpredictable keys**. Parsing a JSON response where keys are
unpredictable (e.g. derived from data) is difficult, and adds friction for
clients.
* **Use consistent case for keys**. Whether you use `under_score` or
`CamelCase` for your API keys, make sure you are consistent.

#### Use UTF-8

Always [use UTF-8](http://utf8everywhere.org).

Expect accented characters or "smart quotes" in API output, even if they're not
expected.

An API should tell clients to expect UTF-8 by including a charset notation in
the `Content-Type` header for responses.

An API that returns JSON should use:

```
Content-Type: application/json; charset=utf-8
```

#### Use a consistent date format

And specifically, [use ISO 8601](https://xkcd.com/1179/), in UTC.

For just dates, that looks like `2013-02-27`. For full times, that's of the
form `2013-02-27T10:00:00Z`.

This date format is used all over the web, and puts each field in consistent
order -- from least granular to most granular.

### API Keys

These standards do not take a position on whether or not to use API keys.

But _if_ keys are used to manage and authenticate API access, the API should
allow some sort of unauthenticated access, without keys.

This allows newcomers to use and experiment with the API in demo environments
and with simple `curl`/`wget`/etc. requests.

Consider whether one of your product goals is to allow a certain level of
normal production use of the API without enforcing advanced registration by
clients.

### Error handling

Errors should always respond with the appropriate  HTTP status code. Responses
with error details should use a `4XX` status code to indicate a client-side
failure (such as invalid authorization, or an invalid parameter), and a `5XX`
status code to indicate server-side failure (such as an uncaught exception).

Handle all errors (including otherwise uncaught exceptions) and return a data
structure in the same format as the rest of the API.

For example, a JSON API might provide the following when a bad request is made:

```json
{
  "code": 400,
  "message": "Bad Request"
}
```

### Pagination

If pagination is required to navigate datasets, use the method that makes the
most sense for the API's data.

Some general recommendations around pagination:

1. Allow the API consumer to specify page sizes/limits and the offset/starting
point for a page.
2. Provide a link in a paginated response to the next page with a similar
size/limit.
3. Allow API consumers to assume that a paginated response without a link to
the next page is the last page.

### Always use HTTPS

Any new API should use and require [HTTPS encryption](https://en.wikipedia.org/wiki/HTTP_Secure) (using TLS/SSL). HTTPS
provides:

* **Security**. The contents of the request are encrypted across the Internet.
* **Authenticity**. A stronger guarantee that a client is communicating with
the real API.
* **Privacy**. Enhanced privacy for apps and users using the API. HTTP headers
and query string parameters (among other things) will be encrypted.
* **Compatibility**. Broader client-side compatibility. For CORS requests to
the API to work on HTTPS websites -- to not be blocked as mixed content --
those requests must be over HTTPS.

HTTPS should be configured using modern best practices, including ciphers that
support [forward secrecy](https://en.wikipedia.org/wiki/Forward_secrecy), and [HTTP Strict Transport Security](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security). **This is not exhaustive**:
use tools like [SSL Labs](https://www.ssllabs.com/ssltest/analyze.html) to evaluate an API's HTTPS
configuration.

### CORS

For an API to be used from a website hosted at a different domain, the API must
[enable CORS](http://enable-cors.org).

For read-only and unauthenticated use cases, where the entire API should be
accessible from inside the browser, enabling CORS can be accomplished by
including this HTTP header in all responses:

```
Access-Control-Allow-Origin: *
```

It's supported by [every modern browser](http://enable-cors.org/client.html),
and will Just Work in many JavaScript clients, like
[jQuery](https://jquery.com).

For more advanced configuration, see the [W3C spec](http://www.w3.org/TR/cors/)
or [Mozilla's guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).

**What about JSONP?**

JSONP is [not secure or performant](https://gist.github.com/tmcw/6244497). If
IE8 or IE9 must be supported, use Microsoft's
[XDomainRequest](http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx?Redirected=true) object
instead of JSONP. There are [libraries](https://github.com/mapbox/corslite) to
help with this.

## Public domain

This project is in the public domain within the United States, and
copyright and related rights in the work worldwide are waived through
the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/).

All contributions to this project will be released under the CC0
dedication. By submitting a pull request, you are agreeing to comply
with this waiver of copyright interest.

repository: cfpb/development

branch_name: refs/heads/main

extension: md

gha_language: Shell

license_type: permissive

repo_name: cfpb/development


text:
# Contributing

Contributions are welcome, and they are greatly appreciated!
Every little bit helps, and credit will always be given.

The latest information about how to contribute to MemCNN can be found here:
<https://memcnn.readthedocs.io/en/latest/contributing.html>

license: MIT

repository: silvandeleemput/memcnn

branch_name: refs/heads/master

gha_language: Python

gha_license_id: MIT

repo_name: silvandeleemput/memcnn


text:
---
layout: post
post_author: ''
current_gaslighter: true
categories: []
tags: []
permalink: "/blog/:slug"
post_title: Welcome Michelle Taute!!
publish_date: 2014-07-22T14:11:00.000+00:00
feature_post_image: ''
post_images: []
slug: welcome-michelle-taute

---
![](https://gaslight-blog.s3.amazonaws.com/welcome-michelle-taute/michelle.jpg)

### What do you consider the most overrated virtue?

Following the rules.

### Which words or phrases do you most overuse?
Sadly, I say the word "like" way, way too often. When I'm excited, I'll yell out "kerpow" and do a fake ninja kick.

### What is your most treasured possession?
Probably the giant washer on my keychain that my dad, who is an industrial mechanic, gave me when I went to college. Fingers crossed that I don't jinx myself and lose it now.

### What is your motto?

 Everything is invented.

### What do you consider your greatest achievement?

No clue. Hopefully, it hasn't happened yet.

repository: katibest/rhythmdogsports

gha_language: HTML

repo_name: katibest/rhythmdogsports


text:
---
template: BlogPost
title: 'Learning Elixir and Building a SaaS with Phoenix Framework'
description: Podopi is a SaaS that was built in Elixir, using the Phoenix Framework. This article outlines my path to learning Elixir and the steps I took to get from n00b to launching my own product in less than 4 months.
date: 2021-11-25T14:46:39.888Z
isFeatured: false
featuredImage: /img/phoenix-framework.png
colors:
  - '#FA98B4'
  - '#550C1E'
tags:
  - Elixir
  - Erlang
  - Phoenix Framework
  - Phoenix LiveView
  - Programming
  - Entrepreneurship
  - SaaS
  - B2B
  - Podopi
---

Learning new languages is not necessary in order to improve as a programmer.
You can focus on one langauge and still not find enough time to learn everything about it.
Programming languages, not unlike spoken languages, use nothing but building blocks.
We use words to build sentences, sentences to build paragraphs and paragraphs to build meaning.
Letters and words can be chained together in an infinite number of combinations.
Same goes for programming language syntax.

## Why Learn a New Programming Language?

If you're an engineer with 10+ years of experience in a language, you have the power to create anything within your imagination.
So why would you ever want to learn a new language?

For me, it's part curiosity, FOMO and "grass is greener"-syndrome.
But mostly, it's the combination of two things I'm passionate about: learning and creating.

Most of my professional life has revolved around JavaScript in some form or another.
Before Node.js, we used clicks of JS to add interactivity to otherwise mostly static web pages.
Today, JavaScript is a hydra behemoth monster capable of pretty much anything.
It's a bit messy, but also beautiful in a wicked way.

During my career, I've also written software in ASP, .NET (C#), Java, Pascal, PHP, GO, Rust, Flutter, Haskell and a few more.

Only one of those languages is a functional language; namely Haskell.

Haskell never clicked for me.
I can look at code someone else has written and clearly see it's beautiful, but I've always had a hard time writing it myself.
It could be because Haskell is too much of a precise/mathematically correct language, and my brain is leaning more towards the chaotic/creative.

At a first glance, Elixir seemed like a friendlier functional programming language than Haskell to me.
Even though we never clicked, I value many of the concepts adopted by the language.
Elixir seemed like a good middle-ground between useful and strict.
Sort of Haskell and Python (or Ruby) combined.

Elixir has received a lot of buzz lately.
Big tech companies, like Heroku, Discord and WhatsApp, have adopted it successfully at scale.

I made it my goal to learn Elixir in 2021.

## Learning Elixir

The official Elixir website describes the language beautifully:

> "Elixir is a dynamic, functional language for building scalable and maintainable applications.
> Elixir leverages the Erlang VM, known for running low-latency, distributed, and fault-tolerant systems.
> Elixir is successfully used in web development, embedded software, data ingestion, and multimedia processing, across a wide range of industries."

How we learn best varies from person to person.
Normally I learn best by doing.
But this time I happened to be tired of "doing", which is why I decided to start slowly by mostly reading:

- The official documentation over at [elixir-lang.org](https://elixir-lang.org/).
- [Programming Phoenix](https://pragprog.com/titles/phoenix14/programming-phoenix-1-4/), by Chris McCord, Bruce Tate and José Valim.
- [Test-Driven Development with Phoenix](https://www.tddphoenix.com/), by German Velasco.

These resources gave me the confidence to start working on a project of my own.

## Building a SaaS in Elixir

Since launching [TAYL](https://www.tayl.app) in 2019, I've been testing several ideas of what A.I. can do for audio.
TAYL lets you turn any text, be it a website, a document or something else, into audio.
Audio you can listen to on iOS, Android, as a Podcast or online via the web application.
Thousands of users word-wide have seen the benefits of listening instead of reading.

To test the waters with my newfound Elixir-skills, I decided to build upon my learnings from TAYL.
That way I could fall back to my existing solutions written in Node.js, if I ever were to get stuck.

This project entailed building a SaaS that would help website owners convert their written words into audio.
My initial ideas only involved audio, but I later also included video.
The application would then distribute the audio and video on to platforms such as Apple Podcasts, Spotify and YouTube.

The project involved many moving parts that would need to be orchestrated order to work good together:

- User accounts and authentication.
- Support subscription payments and one-time purchases.
- Request and scrape web pages.
  - Handle broken and invalid HTML markup.
  - Extract metadata, such as title, author, article body, featured image, publish date, categories and so on.
  - Produce a simplified version of the website, with just the content of the article.
- Convert articles written in HTML into SSML (Speech Synthesis Markup Language).
- Request and parse RSS feeds.
  - There are 3 primary RSS specifications, but many websites do not even cohere to those.
- Periodically fetch new content from RSS feeds.
- Audio processing:
  - Concatenation of multiple files.
  - Cross-fading clips.
  - Encode audio to strike a balance between quality and file size.
- Video processing:
  - Generate video frames from a template created with HTML and CSS with metadata from the article.
  - Encode video with embedded audio from before.
- Download and upload to cloud storage.
- Generate podcast RSS feed from episode data.
- Publish video files to YouTube.
- Search and browse sound tracks from a partner library.

Initially the project scope was much smaller.
The realization how quickly I was able to iterate and get things done made me confident in adding more and more features.

## Test-Driven Development in Elixir

As a good student of German's book, I did my best to use test-driven development throughout.
Unit tests in Elixir are usually written in ExUnit.
For the best experience, I recommend looking into how to integrate the test environment with your editor or IDE.
In my case, [vim-test](https://github.com/vim-test/vim-test) did the trick!

If you do TDD properly, you should be able to build an entire working web application without ever having to launch a web browser.
This project was built with [Phoenix Framework](https://phoenixframework.org), which has great support for testing.

In the example below, you can see how we're able to do assertions based on HTML-like selectors.
This should look familiar to you if you've ever done testing in a modern UI library before, like Vue or React.

```Elixir
  describe "PodcastLive :index" do
    test "displays podcast title and description", %{conn: conn, user: user} do
      podcast = insert(:podcast, user: user)

      {:ok, view, _html} = live(conn, Routes.podcast_path(conn, :index, podcast.id))

      assert has_element?(view, "h2", podcast.title)
      assert has_element?(view, "div", podcast.description)
    end

    test "lists podcast episodes", %{conn: conn, user: user} do
      episodes = insert_list(3, :episode)
      podcast = insert(:podcast, user: user, episodes: episodes)

      {:ok, view, _html} = live(conn, Routes.podcast_path(conn, :index, podcast.id))

      for episode <- episodes do
        assert has_element?(view, "[data-test=episode_title]", episode.title)
      end
    end

    test "lists podcast feeds", %{conn: conn, user: user} do
      feeds = insert_list(3, :feed)
      podcast = insert(:podcast, user: user, feeds: feeds)

      {:ok, view, _html} = live(conn, Routes.podcast_path(conn, :index, podcast.id))

      for feed <- feeds do
        assert has_element?(view, "[data-test=feed_title]", feed.title)
      end
    end
  end
```

We start out with the end in mind when doing test-driven development.
In the example above, we test that this page displays a podcast title and description.
It should also list podcast episodes and feeds.

## Results

The application was deployed to Google Cloud.
It could have been deployed elsewhere, but since I settled for Google Cloud Storage, I figured the app could run there just as well.
I'm planning to move parts of the app over to [fly.io](https://fly.io) in the future, to leverage their edge network for improved performance.

Only a couple of customers have registered an account so far.
We've only done a little marketing, so it's too early to say if it's a hit or miss.
Either way, I'm happy with the result.

[![Podopi](/img/podopi/podopi-landing.png)](https://www.podopi.com)

Visit [podopi.com](https://www.podopi.com) to check it out.
The landing page was built with Next.js and TailwindCSS.
Sign up for a free trail if you have a website and would like to provide your readers with audio.

`youtube: https://youtu.be/yYbBVCo0BVw`

This video was created using a couple of screen recordings and code.
I didn't have any good video editing software, so why not use code?
The voice over was created by using some of the AI voices available in Podopi.
It worked surprisingly well!

## Conclusion

Creating the project took me about 3 months, while also working on other things and trading the stock market to earn a living.
It took me a couple of weeks to warm up to Elixir, and functional programming.
But after that I felt as efficient, if not even more efficient, as I can be with JavaScript and Node.js.
Having a test-driven approach helped me iterate and learn quickly.
There were many times when I was unsure how to best accomplish a specific task in Elixir, when ExUnit helped me test multiple solutions to select the best fit.

Elixir, and Phoenix Framework in particular, is the "batteries included"-solution I've been looking for.
Together with Oban, a task queue built on top of Postgres, I feel empowered to build scalable applications quickly.

Elixir is not a silver bullet of course, but a valuable addition to my toolbox that I'm sure I'll use again in the future.

repository: miickel/ultimate-machine-web

gha_language: JavaScript

repo_name: miickel/ultimate-machine-web


text:
---
layout: home
title: Americans for Representation
permalink: /
section: home
intro_paragraph: >
  The Americans for Representation is a cooperatively owned public advocacy group
  that seeks to empower voters and achieve democratic electoral reform.

---

### Broken American Government

We all know something is wrong with government. The Economist calls our government a “flawed democracy”. According to Gallup, “Only 28% of Americans have a positive overall view of the US federal government… That was the lowest rating for any business or industry sector”. Mechanisms such as money in politics, the electoral college, and gerrymandering have corrupted our democracy. But what can we do to fix America?

The **Americans for Representation (AFR)** is a nonprofit, cooperatively owned advocacy group that seeks to empower American voters by organizing people into collective power that our politicians cannot afford to ignore. With this power we seek to reform our democracy and repair America. We believe that:

1. We should strive for political equality for all Americans.
2. The barriers to democratic participation should be as low as possible.
3. We can make American government better - more responsive, more representative, and more satisfactory for everyone.

## Grassroots Driven Advocacy

### Trustworthy Advocacy

We have the ability to make a difference by voting and talking with our congressmen. But our individual efforts are not enough. To win battles, allies must organize into a cohesive, united coalition. To win in politics, we must:

1. **Organize together to strategically vote in unison at all levels of local, state, and federal government.**
2. **Send our true representatives to speak to politicians and extract tit-for-tat exchanges in favor of our desired policy, using our collective votes and donations as leverage.**

This is the same strategy special interests use to lobby our government. It’s time for ordinary Americans to harness this power. However in order to create this power, we need a new political organization that Americans can trust. We need a cooperatively owned political group.

### Cooperative Ownership

The Americans for Representation (AFR) is a cooperatively owned political group that seeks to be a trustworthy advocate for all Americans. In order to create trust, the AFR gives its members **democratic ownership** of the organization.

This means that you and other members legally own the AFR rather than some private benefactor. This means that all members elect, hire, and fire the leadership at will. Electoral power ensures that your interests will be advocated for rather than the interests of the leadership. Membership will also be open to all citizens who wish to participate. With cooperative ownership, you will drive the organization’s goals from the bottom up.

### AFR Member Services

The AFR will provide several services for its members. It will:

1. **Provide true democratic representation.** Through democratic ownership, AFR members will elect representative leadership - leaders that can be trusted - leaders with a much shorter leash than the politicians in Washington.

2. **Become a lobbying firm.** The AFR will fight fire-with-fire and arm Americans with the same tools that special interests have used to corrupt our government.

3. **Provide members actionable news & information** on issues and strategic voting in order to maximize voter influence.

4. **Nominate our members as candidates** in Republican and Democratic primaries.

The AFR will not exclusively support one party. The AFR will choose its support strategically with the goal of maximizing our members’ political power and influence.

## Reforming Government

### Disrupting the Two Party System

Americans are dissatisfied with both parties and must resort to picking the lesser of two evils for every election. Gerrymandering, convoluted party primaries, and the exorbitant cost of political campaigning all work to disempower the working and professional class. The AFR will work to eliminate these barriers to participation.

The two-party system has also produced decades of political stalemate, polarization and voter dissatisfaction. Many political scientists believe that this stalemate is an inevitable consequence of our winner-takes-all election system. However, solutions have already been developed to fix these problems.

### Electoral Reform

Political scientists have devised many innovative ideas that could be used to repair our democracy and advance 3rd party participation. These include:

1. **Proportional representation** - Representatives are elected to congress based on vote proportion rather than arbitrary district boundaries.

2. **Score based voting** - an alternative voting system where voters score each candidate, and the candidate with the greatest score wins.

3. **Delegative “liquid” democracy** - A mode of governance where voters can choose to delegate out their votes to representatives. Or, voters can choose to directly vote. In other words, you can choose whether you want to directly participate or you want to delegate out your authority.

The AFR seeks to create the best possible American democracy. The AFR shall test and validate potential reforms on its own internal election system. After experimentation, validation, and approval by our members, the AFR will then lobby government to implement these new reforms.

### Creating a New Consensus

We believe that special interests are largely to blame for the fracture of American society. Americans are not so different from one another. Yet mass media and partisan talking heads pit father against son, mother against daughter, and neighbor against neighbor.

The AFR seeks to construct a new political forum where people can come together to rationally discuss our interests and make the necessary compromises to make a better society. At the very least, we all need to reach a new understanding and trust of each other, even if we cannot agree to the details of policy and ideology.

Only with a new consensus can we can finally enact the necessary reforms that our current politicians cannot.

### A Call for Membership

We want liberals. We want conservatives. We want libertarians. We want socialists. We want the selfish and the selfless. We want to empower everyone as a rising tide lifts all boats. We want your **active participation**. If you think America can do better, please join our group!


text:
## Knative prow

This directory contains prow configs hosted for Knative. This prow is bumped by
[`bump.sh`](../bump.sh) script

### Prow Clusters

- [Prow control plane cluster(default prow cluster)](https://pantheon.corp.google.com/kubernetes/clusters/details/us-central1-f/prow?project=knative-tests)
  - Prow deployments, core configs, and plugins are hosted in this repo
  - Prow job configs are hosted in knative/test-infra repo
- [Build cluster](https://pantheon.corp.google.com/kubernetes/clusters/details/us-central1-f/knative-prow-build-cluster)
  - Build cluster deployments are hosted in this repo
  - Boskos resources are hosted in knative/test-infra repo
- [Trusted cluster](https://pantheon.corp.google.com/kubernetes/clusters/details/us-central1-a/prow-trusted)
  - This is a very basic cluster with important secrets

### Manually Deploy

Manual deployments are defined as in [Makefile](./Makefile), specifically:

- `make -C prow/knative deploy`: deploys all yamls under [cluster](./cluster)
- `make -C prow/knative deploy-build`: deploys all yamls under [cluster/build](./cluster/build)

## Prow Secrets

Some of the prow secrets are managed by kubernetes external secrets, which
allows prow cluster creating secrets based on values from google secret manager
(Not necessarily the same GCP project where prow is located). Secrets are
declared in this repositories:

- Secrets for prow
service cluster are stored under [`/prow/knative/cluster`](/prow/knative/cluster)
- Secrets for prow build cluster are stored under [`/prow/knative/cluster/build`](/prow/knative/cluster/build)

Please make sure
granting service account
<EMAIL_ADDRESS>permission for accessing secret manager in the project(GCP allows setting
permission on individual secret level) see more detailed instruction on how to
do so at [Prow
Secret](https://github.com/kubernetes/test-infra/blob/master/prow/prow_secrets.md).

repository: jaimehisao/oss-test-infra

repo_name: jaimehisao/oss-test-infra


text:
# comment-tree

[![CircleCI](https://circleci.com/gh/denyago/comment-tree.svg?style=svg)](https://app.circleci.com/github/denyago/comment-tree/pipelines)

Learning Kotlin by implementing a simple comments tree with HTTP client calls. Inspired by https://habr.com/ru/post/469441/

The task is following:

- Given a tree with an Integer IDs in each node
- Fetch the comments by IDs from an API asynchronously
- And display the new tree with comments

It is supposed to be an "expressiveness test" of *your* favourite language.

To me it's a way to learn something new.

repository: denyago/comment-tree

repo_name: denyago/comment-tree


text:
# Raven

[![Latest GitHub release](https://img.shields.io/github/release/lbcb-sci/raven.svg)](https://github.com/lbcb-sci/raven/releases/latest)
![Build status for gcc/clang](https://github.com/lbcb-sci/raven/actions/workflows/raven.yml/badge.svg)
[![Published in Nature Computational Science](https://img.shields.io/badge/published%20in-Nature%20Computational%20Science-blue)](https://www.nature.com/articles/s43588-021-00073-4)

Raven is a de novo genome assembler for long uncorrected reads.

## Usage
To build raven executable run the following commands:

```bash
git clone https://github.com/lbcb-sci/raven && cd raven
cmake -S ./ -B./build -DRAVEN_BUILD_EXE=1 -DCMAKE_BUILD_TYPE=Release
cmake --build build
```

For faster build times optionally use [ninja](https://ninja-build.org/) and enable threading in cmake.
Eg.
```bash
git clone https://github.com/lbcb-sci/raven && cd raven
cmake -S ./ -B ./build -DRAVEN_BUILD_EXE=1 -DCMAKE_BUILD_TYPE=Release -G Ninja
cmake --build build -j 4
```

To install the raven executable after build run:

```bash
cmake --install ./build
```

To install python bindings run the following:
```bash
pip install git+git://github.com/lbcb-sci/raven.git@master
```

Python example can be found at `PythonLib/example.py`

```bash
usage: raven [options ...] <sequences> [<sequences> ...]

  # default output is to stdout in FASTA format
  <sequences>
    input file in FASTA/FASTQ format (can be compressed with gzip)

  options:
    -k, --kmer-len <int>
      default: 15
      length of minimizers used to find overlaps
    -w, --window-len <int>
      default: 5
      length of sliding window from which minimizers are sampled
    -f, --frequency <double>
      default: 0.001
      threshold for ignoring most frequent minimizers
    -i, --identity <double>
      default: 0
      threshold for overlap between two reads in order to construct an edge between them
      if set to zero, this functionality is disabled
    -o, --kMaxNumOverlaps <long unsigned int>
      default: 32
      maximum number of overlaps that will be taken during FindOverlapsAndCreatePiles stage
    -p, --polishing-rounds <int>
      default: 2
      number of times racon is invoked
    -m, --match <int>
      default: 3
      score for matching bases
    -n, --mismatch <int>
      default: -5
      score for mismatching bases
    -g, --gap <int>
      default: -4
      gap penalty (must be negative)
    -u, --min-unitig-size <int>
      default: 9999
      minimal unitig size
    --graphical-fragment-assembly <string>
      prints the assembly graph in GFA format
    --resume
      resume previous run from last checkpoint
    --disable-checkpoints
      disable checkpoint file creation
    -t, --threads <int>
      default: 1
      number of threads
    --version
      prints the version number
    -h, --help
      prints the usage

  only available when built with CUDA:
    -c, --cuda-poa-batches <int>
      default: 0
      number of batches for CUDA accelerated polishing
    -b, --cuda-banded-alignment
      use banding approximation for polishing on GPU
      (only applicable when -c is used)
    -a, --cuda-alignment-batches <int>
      default: 0
      number of batches for CUDA accelerated alignment
```

To use raven library component in your project, add the following to your cmake file:
```cmake
include(FetchContent)

FetchContent_Declare(
        raven
        GIT_REPOSITORY https://github.com/lbcb-sci/raven
        GIT_TAG v1.8.1)

FetchContent_GetProperties(raven)
if (NOT raven_POPULATED)
    FetchContent_Populate(raven)
    add_subdirectory(
            ${raven_SOURCE_DIR}
            ${raven_BINARY_DIR}
            EXCLUDE_FROM_ALL)
endif ()

target_link_libraries(<YourTarget> <PRIVATE|PUBLIC|INTERFACE> raven)
```

#### Build options
- `RAVEN_BUILD_TESTS`: build unit tests
- `RAVEN_BUILD_PYTHON`: builds python module
- `RAVEN_BUILD_SHARED_LIBS: build raven lib and it's dependencies as shared libraries`
- `RAVEN_BUILD_EXE`: build raven executable
- `racon_enable_cuda`: build with NVIDIA CUDA support

#### Dependencies
- gcc 7.5+ | clang 8.0+
- cmake 3.11+
- zlib 1.2.8+

###### Hidden
- [pybind11](git@github.com:pybind/pybind11.git)
- lbcb-sci/racon/tree/library 3.0.2
- rvaser/bioparser 3.0.13
- (raven_test) google/googletest 1.10.0

### Other options

**NOTE**: not updated for 1.8 release

#### Brew
Install [Linuxbrew](https://docs.brew.sh/Homebrew-on-Linux) and run the following command:

```bash
brew install brewsci/bio/raven-assembler
```

#### Conda
Install [conda](https://conda.io/en/latest/miniconda.html) and run the following command:
```bash
conda install -c bioconda raven-assembler
```

## Acknowledgment
This work has been supported in part by the Genome Institute of Singapore (A\*STAR), by the Croatian Science Foundation under projects Algorithms for genome sequence analysis (UIP-11-2013-7353) and Single genome and metagenome assembly (IP-2018-01-5886), and in part by the European Regional Development Fund under grant KK.<IP_ADDRESS>.0009 (DATACROSS).

repository: lbcb-sci/raven

repo_name: lbcb-sci/raven


text:
# Introduction

The library is based on a publication / subscription model and topics. Messages are always sent to an specific topic and subscriptions are performed over an specific topic as well.

The publication is "broadcast", a message published for a topic will arrive to any subscriber that is subscribed to it.

**Important**: Publication is broadcast, there is no way to publish a message only to an specific subscriber unless it is the only subscriber connected to the topic.

The process of auto-discovery ensures that the Topic Publishers and Topic Subscribers knows about each other to ensure this broadcast behaviour. This process is transparent to the user of the library.

In the case of Unicast Transport, the library will create the required connections to reach all the subscribers that are listening to the same topic.

# Creating a subscriber and receiving messages

There are 2 ways to subscribe to receive messages and requests. Both follows a listener model in which the user provides a listener interface to receive incoming messages:

## Subscribe to topic

Calling the method _subscribeToTopic_ in the IVegaInstance interface would perform an specific topic subscription for a topic name.

The topic has match one of the configured patterns in the instance XML configuration, if there is no configuration match an exception will be thrown.

You cannot subscribe to the same topic twice unless the first subscription is removed first.

**Important**: The subscription is asynchronous, it will be performed in the background and will trigger the auto-discovery process.

## Subscribe to pattern

The method _subscribeToPattern_ in the IVegaInstance interface will perform a pattern topic subscription. This means that it will receive messages from any topic publisher that match the provided topic pattern.

A topic pattern is just a java regular expression that used to match every time there is a new topic in the network. If there is a match the proper transport connections will be created internally to get messages from the topic.

**Important**: If a topic match the pattern it is check also against the instance configuration, if it doesn't match any configuration it will be ignored.

You cannot subscribe to the same topic pattern twice on the same way that you cannot subscribe to the same topic twice.

## The listener interface

For both topic and pattern subscriptions is necessary to provide an object that implements the interface ITopicSubListener. This object will receive the incoming messages and requests for the subscribed topic.

Here is how the interface looks like:

    /**
    * Implement in order to receive messages on a subscribed topic
    */
    public interface ITopicSubListener
    {
        /**
        * Method called when a message is received.
        *
        * IMPORTANT: If the received message contents are going to be accessed from a separate thread the message should be promoted!!
        *
        * @param receivedMessage the received message
        */
        void onMessageReceived(final IRcvMessage receivedMessage);

        /**
        * Method called when a request message is received.
        *
        * IMPORTANT: If the received message contents are going to be accessed from a separate thread the message should be promoted!!
        *
        * @param receivedRequest the received request
        */
        void onRequestReceived(final IRcvRequest receivedRequest);

        /**
        * The method is invoked when a gap in the sequence number of the last two messages received from the same topicPublisherId is detected
        * This sequence number is located at the message data header of Vega {@link com.bbva.kyof.vega.msg.MsgDataHeader }
        *
        * Vega is implemented over Aeron, that provides a reliable connection for unreliable protocols.
        * Even so, there may be messages that Aeron can not recover. For this reason, this functionality has been implemented,
        * allowing the user to know when a message is lost.
        *
        * The sequence numbers are shared by messages and requests and therefore this callback applies to any of both cases.
        *
        * Message loss is not check for responses.
        *
        * Default implementation does nothing with the loss report
        *
        * @param lostReport a report of the lost messages
        */
        default void onMessageLost(final IMsgLostReport lostReport)
        {
            // By default there is no action to take
        }
    }

You have to implement the method onMessageReceived to process incoming messages. The requests will be reviewed in the Req / Resp section.

For each new message received a call to onMessageReceived will be performed by the library.

The call contains a reference to the received message.

### How to detect message loss?

The interface contains a default method since version 1.4 that notifies when there is a message loss on reception.

Each topic publisher contains it's own sequence number that is user by the receiver to detect message loss coming from an specific publisher.

It is possible to query the topic name that has caused the loss, the sender instance unique id, the topic publisher unique id and the number of loss messages.

This is only triggered in very rare occasions when the message recovery of Aeron cannot recover from a loss. This means there are serious problems on the network or the applications.

Even if the method of the interface is not implemented the loss will be logged as a Warning.

    /**
    * Interface that represents the information about the lost messages.
    */
    public interface IMsgLostReport
    {
        /** @return the topic name of the received message */
        String getTopicName();

        /** @return  the instance id of the message sender */
        UUID getInstanceId();

        /** @return the topic publisher id of the message sender*/
        UUID getTopicPublisherId();

        /** @return the number of messages that have been lost */
        long getNumberLostMessages();
    }

## The IRcvMessage interface

The received message implements an interface. This interface allows to extract the binary contents of the message and additional information like the topic name the message belongs to.

    /**
    * Interface that represents received message.

    *
    * The contents of the message comes in the form of an UnsafeBuffer

    *
    * It is also possible to get the contents as a ByteBuffer

    *
    * The message object and contents are reused by the library to avoid memory allocation, always promote the message
    * if the message contents are going to be accessed on separate user thread!
    */
    public interface IRcvMessage
    {
        /** @return the topic name of the received message */
        String getTopicName();

        /** @return  the instance id of the message sender */
        UUID getInstanceId();

        /**
        * Return the offset in the message contents where the user msg starts
        *
        * @return the content message offset
        */
        int getContentOffset();

        /**
        * Return the lenght of the user message
        *
        * @return the length of the message
        */

        int getContentLength();

        /**
        * Return an UnsafeBuffer with the user contents of the message. This is the most optimal way to deal with the message contents.
        *
        * The offset in the buffer and total user msg length can be retrieved using the respective methods, getContentOffset() and getContentLenght()
        *
        * @return the UnsafeBuffer with the message contents
        */
        UnsafeBuffer getContents();

        /**
        * Promote the message by cloning all internal fields into a new message, including the content
        *
        * Since the library will try to reuse internal buffers you have to promote the message if it's contents are going
        * to be accessed from a separate thread.
        *
        * @return the new created promoted message
        */
        IRcvMessage promote();
    }

The Instance ID is a unique identifier that is created every time a new instance of the library is instantiated. The value belongs to the instance that sent the message.

The topic name is the topic the message has bent sent into.

### How to process the binary contents?

The contents of the message always comes in binary form.

The contents are provided as an **UnsafeBuffer** for máximum performance. The offset in the buffer and the length of the contents can be retrieved with the methods getContentOffset() and getContentLength().

UnsafeBuffer implements a direct access buffer designed for ultra low latency and is the optimal way to process the contents of the message.

If we want to use a more traditional approach, it is possible to process the content of the message as a ByteBuffer. In this case there are 2 options:

**Create a new ByteBuffer and copy the message contents into the buffer.** Here is a simple example code:

    @Override
    public void onMessageReceived(final IRcvMessage receivedMessage){
        // Get the binary length of the message
        int messageLentgh = receivedMessage.getContentLength();
        // Get the offset of the message in the buffer
        int msgOffset = receivedMessage.getContentOffset();
        // Create a new byte buffer to copy the contents into
        ByteBuffer byteBufferContents = ByteBuffer.allocate(messageLentgh);
        // Copy the contents into the created buffer
        receivedMessage.getContents().getBytes(msgOffset, byteBufferContents, messageLentgh);
        // Process the contents, it can be processes on a separate thread also without promotions
    }

**Important**: This may not be the best solution since new memory has to be created every time we create a new ByteBuffer.

**Important**: If the contents are copied there is no need to promote the message to use it in a separate thread as soon we don't access any message information directly.

**Create a reusable ByteBuffer and copy the message contents into the buffer and reuse it for each message.**

**Important**: This solution is more memory efficient but you should be careful to avoid space problems if the reusable buffer is too small.

### Process the message on a separate thread: Message Promotion

The library try to optimise the usage of memory as much as possible. This means it will reuse the Message object provided in the callback for the next callback in order to prevent unnecessary memory allocation.

The message is "safe" while the code of the listener callback is being executed but as soon as the callback end the object will be reused.

**If the message is going to be processes on a separate thread you need to call promote() and process the "promoted" message in the separate thread instead of the original one.**

**Tip:** Promoting messages requires a copy of the fields and the binary contents and is not very efficient. Try to "deserialise" the message contents inside the callback and process the deserialised contents in a separate thread to avoid the promote() call.

## Full example

    `// Create the instance parameters
    VegaInstanceParams params = VegaInstanceParams.builder().
                    instanceName("TestInstance").
                    configurationFile("config.xml").build();

    // Create the library instance
    IVegaInstance instance = VegaInstance.createNewInstance(params);

    // Create a listener
    ITopicSubListener listener = new ITopicSubListener()
    {
        @Override
        public void onMessageReceived(IRcvMessage receivedMessage)
        {
            // Process the received message
        }

        @Override
        public void onRequestReceived(IRcvRequest receivedRequest) {}
    };

    // Subscribe to topic
    instance.subscribeToTopic("Topic1", listener);

    // Unsubscribe from topic
    instance.unsubscribeFromTopic("Topic1", listener);

    // Subscribe to topic pattern
    instance.subscribeToPattern("Topic.*", listener);

    // Unsubscribe from topic pattern
    instance.unsubscribeFromPattern("Topic*", listener);

## Important considerations

### Transports should match configuration

It is not possible to subscribe to a topic that has a different transport than the one configured in the instance. For example if we configure the topic "a" to be multicast and there is a publisher that publish into the topic "a" in unicast, the connection between them won't be performed.

**Important**: All the publishers and subscribers on the same auto-discovery domain should share the same transport type configurations for the same topics!

### Messages duplicated due to pattern subscriptions

If you subscribe to a topic pattern and also to a topic and the topic match both the topic name and the topic pattern, the messages will arrive twice. Once due to the patter subscription and once due to the topic subscription.

If the listener object is different this may not be a problem, but if the same object is used it will look as if 2 messages have been received, but is actually the same message.

The same problem happens if there are multiple topic pattern subscription and a topic match more than one.

**Important**: Make sure there are not multiple matches for a topic between the topic subscriptions and the pattern subscriptions in your application.

### Do not block the callbacks of the poller

The pollers are used to poll for new messages for topic subscriptions, pattern subscriptions and responses.

Each poller is a single thread, what means that if the same poller is used for all the instance, you can only receive one message at a time from any topic or any response.

If you block the poller by doing too much work in the callback, it will prevent more messages from arriving and they will be accumulated in the internal buffers. This will eventually cause loss, retransmissions and degradation of performance.

**Important**: Try to spend less time as possible in the callback. Never perform a full thread block. If you need to perform a long operation on response to a received message, decouple the operation and perform it on a separate thread.

# Creating a publisher and sending messages

The process to create a publisher is very similar than the one followed to create a subscriber. In this case is simple since there is a single type of publishers.

There is no concept of "pattern publisher", each publisher is created for a single specific topic.

To create a new publisher you can use the method _createPublisher()_ with the name of the topic you want to publish into.

The method return an object of type ITopicPublisher, this object is used to send messages into the topic.

**Important**: You cannot create to publishers for the same topic unless the first one has been destroyed first.

**Important**: You cannot create a topic publisher for a topic that is not configured in the instance xml configuration, it will cause an exception to be launch.

## Using ITopicPublisher to send messages

The object returned in the _createPublisher()_ call can be used to send messages into the topic or requests.

Here is the full interface:

    /**
    * Interface for a topic publisher with the functionality available for a user
    */
    public interface ITopicPublisher{
        /**
        * This method sendM a normal message
        *
        * Try to reuse buffers if possible to reduce memory usage!
        *
        * It will send the provided offset and length to get the contents in the buffer to send
        *
        * @param message the binary message to send
        * @param offset Offset for the message start in the buffer
        * @param length Length of the message starting in the given offset
        * @return the enum with the result of the publication
        */
        PublishResult sendMsg(final DirectBuffer message, final int offset, final int length);

        /**
        * Send a request on the topic.
        *
        * It will send the provided offset and length to get the contents in the buffer to send
        *
        * Try to reuse buffers if possible to reduce memory allocation.
        *
        * @param message The request message to send
        * @param offset Offset for the message start in the buffer
        * @param length Length of the message starting in the given offset
        * @param timeout the timeout of the request in milliseconds
        * @param respListener Listener for responses on the request. If null no responses will be processed.
        *
        * @return an object that represent the sent request, containing the request ID and other useful information like the publish result
        */
        ISentRequest sendRequest(final DirectBuffer message, final int offset, final int length, final long timeout, final IResponseListener respListener);

        /** @return the topic associated to this topic publisher */
        String getTopicName();

        /** @return topic unique Id associated to this topic publisher */
        UUID getUniqueId();
    }

Each created topic publisher has a unique topic id that can be retrieved by the method _getTopicId()_, the method _getTopicName()_ returns the topic name for the created TopicPublisher.

The method to send messages is _sendMsg()_ and has a single argument with the _DirectBuffer_ to send, the offset of the contents in the buffer and the length of the message.

**Important**: The send process is almost instantaneously, the message is internally stored in a buffer and will be sent in the background.

The method returns a result of type _PublishResult_ that should be check to know if the message has been sent correctly or not.

The possible values are:

* OK -> The message has been sent correctly.
* * If there are no subscribers it will also return an OK.
* BACK_PRESSURE -> One of the subscribers for the topic cannot handle the data rate and therefor the message has not been sent to the subscriber.
* * The library user should decide to wait a bit and resend, or assume the loss.
* * The message may have arrive to some subscribers and not others.

**Important**: Resending after back pressure may result in duplicated messages in some subscribers.

## Sending messages with ByteBuffer

If you need to use a "normal" ByteBuffer instead of a DirectBuffer to send messages you can do it also.

There are 4 options here:

* "Wrap" the ByteBuffer to send into a new UnsafeBuffer every time a send is going to be made. The UnsafeBuffer is just a wrapper over the original one.
* Create a new UnsafeBuffer and always reuse the same object.
* * You can wrap the ByteBuffer only once if the ByteBuffer is going to be reused.
* * Or you can just wrap a new buffer with the same UnsafeBuffer object prior to send every time.

Let's see the three options with an example:

    Use ByteBuffer to send
    // This is the message we want to send
    ByteBuffer message = ByteBuffer.allocate(4);
    message.putInt(33);
    message.flip();

    // Option 1: Create a new UnsafeBuffer every time, wrapping the original buffer
    UnsafeBuffer option1 = new UnsafeBuffer(message);
    publisher.sendMsg(option1, message.position(), message.limit());

    // Option 2: Wrap the ByteBuffer only once if the ByteBuffer is being reused
    UnsafeBuffer option2 = new UnsafeBuffer(message);
    publisher.sendMsg(option2, message.position(), message.limit());

    // Create other message that reuses the buffer
    message.clear();
    message.putInt(44);
    message.flip();

    // Send again, the ByteBuffer is already wrapped
    publisher.sendMsg(option2, message.position(), message.limit());

    // Option 3: Wrap the ByteBuffer every time but reuse it

    // Create the unsafe buffer that will be reused
    UnsafeBuffer option3 = new UnsafeBuffer(ByteBuffer.allocate(0));

    // Craete a message
    ByteBuffer message = ByteBuffer.allocate(4);
    message.putInt(33);
    message.flip();

    // Wrap the mesasge and send
    option3.wrap(message);
    publisher.sendMsg(option3, message.position(), message.limit());

    // Craete another message
    ByteBuffer message2 = ByteBuffer.allocate(4);
    message.putInt(44);
    message.flip();

    // Wrap the mesasge and send
    option3.wrap(message2);
    publisher.sendMsg(option3, message.position(), message.limit());

# Full example

This is a simple example in which a message is sent with some content and the content is retrieved and displayed on the screen.

    // Create the instance parameters
    VegaInstanceParams params = VegaInstanceParams.builder().
            instanceName("TestInstance").
            configurationFile("config.xml").build();

    // Create the library instance
    IVegaInstance instance = VegaInstance.createNewInstance(params);

    // Create a listener
    ITopicSubListener listener = new ITopicSubListener()
    {
        @Override
        public void onMessageReceived(IRcvMessage receivedMessage)
        {
            int deserializedValue = byteBufferContents.getInt(receivedMessage.getContentOffset());
            System.out.println(deserializedValue);
        }

        @Override
        public void onRequestReceived(IRcvRequest receivedRequest) {}
    };

    // Subscribe to topic
    instance.subscribeToTopic("Topic1", listener);

    // Create a topic publisher
    ITopicPublisher topicPublisher = instance.createPublisher("Topic1");

    // Create the message to send
    UnsafeBuffer sendBuffer = new UnsafeBuffer(ByteBuffer.allocate(128));
    sendBuffer.putInt(0, 77);

    PublishResult result = topicPublisher.sendMsg(sendBuffer, 0, 4);

    if (result == PublishResult.BACK_PRESSURED)
    {
        // Resend the message?
    }

# Performance tips

**Always reuse buffers if possible.**

* The buffer to send messages is very easy to reuse and the performance is greatly improved.
* To receive messages is faster to use the internal _UnsafeBuffer_ of the message.
* If a _ByteBuffer_ is required to process the received message, try to provide a buffer to fill instead of creating a new one every time.

**Try not to block the events callback and don't perform long operations in them**
* Received messages, requests and events are notified through callbacks in the provided listeners.
* The polling thread is blocked until the callback returns.
* It will prevent new messages to be retrieved by that poller until the callback finishes.
* The same problem happens if a long operation is performed in the callback.
* For this cases try to process the message in the background on a separate thread.
* * You can promote the message and process it in another thread.
* * Even better, you can decode it and process the decoded message in another thread without having to promote it.

**Considering using more than one poller and distribute them correctly on the topics**

* If several topics have a high flow of messages it can be desirable to have a poller for each one in order to process the messages in parallel.

**Spend some effort defining the topic space and the transport relations in the configuration**

* The configuration can have a great impact on the library performance.
* Try not to use the same transport for topics with very high flows.
* Separate topics for prices and messages to prevent increase of latency on important messages.
* Use the StreamIDs for multiplexing/demultiplexing to reduce the number of "sockets" between peers.

**Be careful with the IdleStrategies selected and the Media Driver Type**

* The BusySpin idle strategies for media driver and pollers is very aggressive. Each thread in BusySpin is going to use a full CPU core.
* Unless there are extremely low latency requirements or no core limits it may be better to use Back Off strategy.

repository: BBVA-CIB/Vega-Messaging

gha_language: Java

repo_name: BBVA-CIB/Vega-Messaging


text:
# Join URI QR Code

This component displays the current Flow's JoinURI on a page as a QR code.

## Setup

- Grab the files from the /build folder and import into your tenant.

- Add the files to your player code like this: -

        requires: ['core', 'bootstrap3'],
        customResources: [
                'https://s3.amazonaws.com/files-manywho-com/tenant-id/JoinQRCode.js',
                ],

- Add a component to your page, any type, save it then change it's "componentType" to "JoinQRCode" in the metadata editor and save it.
e.g.
            "componentType": "JoinQRCode",

-Set the "width" of the component to control the QR Code's size in pixels.

## Extra Configuration

You can add attributes to the component to control it's appearance: -

- logo          - the url of an image to use as the QR background.
- logoWidth     - the pixel width of the logo - default is size * 0.2
- logoHeight    - the pixel height of the logo - default is size * 0.2
- logoOpacity   - the opacity of the logo between 0 & 1.

repository: MarkWattsBoomi/ui-component-JoinQRCode

repo_name: MarkWattsBoomi/ui-component-JoinQRCode


text:
# Property Grid

- [Overview](#Overview)
- [Installation](#Installation)
- [Usage](#Usage)
  - [Import](#Import)
  - [Getting Started](#Getting-Started)
    - [Basic](#Basic)
    - [Advanced](#Advanced)
- [API](#API)
  - [Properties](#Properties)
  - [Methods](#Methods)
  - [Events](#Events)
  - [Hooks](#Hooks)
  - [Styling](#Styling)

## Overview

A small and simple property grid, written in pure Vanilla JavaScript (web components), inspired by [jqPropertyGrid](https://github.com/ValYouW/jqPropertyGrid).

With this PropertyGrid control you can pass object and allow users to edit the properties with the data type-specific editors. The component offers the ability to group and sort its items, use custom editors per data type, work with and without configuration...etc.

![Property Grid](docs/images/pg.jpg?raw=true 'Property Grid')

## Installation

Install with npm:

`npm i clean-web-ui-property-grid --save`

## Usage

### Import

If you are using typescript:

`import {PropertyGrid} from 'clean-web-ui-property-grid';`

With JavaScript, just import the script in the html body:

`<script src="clean-web-ui-property-grid.js"></script>`

### Getting Started

#### Basic

You can use by inserting web component in html:

```html
<property-grid id="pg1"></property-grid>
```

With JS:

```JS
const pg1 = document.getElementById('pg1');
pg1.selectedObject = pgData;
```

#### Advanced

More complex example would be to pass config and options to the grid.

In HTML:

```html
<div id="propertyGridWithConfig"></div>
```

In Js/Typescript:

```JS
//If using Typescript
import {createPropertyGrid} from 'clean-web-ui-property-grid';

var pgOptions = {
  hasGroups: true,
  propertySort: true
};

var pgConfig = {
  filter: { group: 'Behavior', name: 'Filter', type: 'boolean' },
  filterSize: {
    group: 'Behavior',
    name: 'Filter size',
    type: 'number',
    options: { min: 0, max: 500, step: 10 },
  }
};

var pgData = {
  filter: true,
  filterSize: 200
};

createPropertyGrid('propertyGridWithConfig', pgConfig, pgOptions, pgData);

// To listen for events emmited from grid
 document.getElementById('pgpropertyGridWithConfig').addEventListener('valueChange', (v) => console.log(v));
```

## API

### Properties

**_config_** - PropertyGridConfig | null
This is the metadata object that describes the target object properties.
Here you can pass and configure how the property grid editors will work like: control type, min/max values...etc.

```JS
{
"browsable": boolean //  Whether this property should be included in the grid, default is true (can be omitted),
"group": string // The group this property belongs to
"name": string // The display name of the property in the grid
"type": 'text' | 'number' | 'boolean' | 'color' | 'options' | 'label' // The type of the property
"description": string // A description of the property, will be used as tooltip on an hint element (a span with text "[?]")
"showHelp": boolean // If set to false, will disable showing description's span with text "[?]" on property name.
"items": string[] // List of Dropdown Items used for select control
"options": Object // An extra options object per type (attributes per control)
}
```

**_options_** - PropertyGridOptions | null
The options that are passed to the property grid control to configure how the grid will work. Here you pass options that configure the grid itself, not the individual controls. You can pass options like: show/hide groups, sort method...etc.

```JS
{
"hasGroups": boolean //Gets or sets a value indicating whether controls are groupped and if groups are visible
"propertySort": boolean | Function //If and how to sort properties in the grid. Optionally you can pass callback functiom
"onValueChange": FormControl // Hook that is called before value is changed
"controls": Function // Set custom controls that will be used for rendering
"enabled": boolean // Gets or sets a value indicating whether the control can respond to user interaction.
"toolbarVisible": boolean // Gets or sets a value indicating whether the toolbar is visible.
}
```

**_selectedObject_** - Object
The is the object that you want to edit in the grid. If no config is passed to the grid, the grid will try to create config based on object properties and value type.

**_disabled_** - boolean
Gets or sets a value indicating whether the control can respond to user interaction.

### Methods

**_render()_** - void
Build the config for the grid, render controls on UI and attach event listeners. Called internally by the grid when selectedObject is changed.

**_getValues()_** - Object
Returns the current values for all properties in the grid.

**_destroy()_** - void
Destroys all elements and removes all event listners from elements.
Called internally by the grid when the component is about to be destroyed.

## Events

**_valueChanged_** - CustomEvent
Fired when the value is changed for some of controls in the property grid.

Event payload:

`{name: 'controlname', value: 'new value'}`

## Hooks

**_onValueChange(event)_** - Object | boolean | void
Hook that is called before value is changed. Usefull if you want to intercept the original valueChange event.

## Styling

Available CSS variables

```JS
--property-grid-header-background: #E0ECFF;
--property-grid-header-border: 1px dotted #95B8E7;
--property-grid-table-row-group-background: #E0ECFF;
--property-grid-table-row-group-font-weight: bold;
--property-grid-table-row-hover: #f0f5fd;
--property-grid-cell-border: 1px dotted #ccc;
```

repository: MassMessage/clean-web-ui-property-grid

repo_name: MassMessage/clean-web-ui-property-grid


text:
# taojiashu-reused
###### \java\seedu\address\logic\commands\ExitCommandTest.java
``` java
    /**
     * Asserts that the result message from the execution of {@code historyCommand} equals to {@code expectedMessage}
     */
    private void assertCommandResult(ExitCommand exitCommand, String expectedMessage) {
        assertEquals(expectedMessage, exitCommand.execute().feedbackToUser);
    }
}
```
###### \java\seedu\address\logic\commands\ShowFavouriteCommandTest.java
``` java
    /**
     * Asserts that {@code command} is successfully executed, and<br>
     *     - the command feedback is equal to {@code expectedMessage}<br>
     *     - the {@code FilteredList<ReadOnlyPerson>} is equal to {@code expectedList}<br>
     *     - the {@code AddressBook} in model remains the same after executing the {@code command}
     */
    private void assertCommandSuccess(ShowFavouriteCommand command, String expectedMessage,
                                      List<ReadOnlyPerson> expectedList) {
        AddressBook expectedAddressBook = new AddressBook(model.getAddressBook());
        CommandResult commandResult = command.execute();

        assertEquals(expectedMessage, commandResult.feedbackToUser);
        assertEquals(expectedList, model.getFilteredPersonList());
        assertEquals(expectedAddressBook, model.getAddressBook());
    }

}
```


text:
# PartDataPiece

A part Data piece can be added to a [PartType](/Mods/ContentTweaker/Materials/Parts/PartType/) to be able to add some [MaterialPartData](/Mods/ContentTweaker/Materials/Materials/MaterialPartData/) to [MaterialParts](/Mods/ContentTweaker/Materials/Materials/MaterialPart/) created with [Parts](/Mods/ContentTweaker/Materials/Parts/Part/) that are of this [PartType](/Mods/ContentTweaker/Materials/Parts/PartType/).

## Importing the package
It might be required for you to import the package if you encounter any issues, so better be safe than sorry and add the import.
`import mods.contenttweaker.PartDataPiece;`

## Retrieving such an object

You can get a List of a [Parts](/Mods/ContentTweaker/Materials/Parts/Part/) DataPieces using `getData()` on a [Part](/Mods/ContentTweaker/Materials/Parts/Part/).

Alternatively, you can register a new PartDataPiece using the [MaterialSystem](/Mods/ContentTweaker/Materials/MaterialSystem/):

```zenscript
mods.contenttweaker.MaterialSystem.createPartDataPiece(String name, boolean required)
```

Parameters:

- String name: The new PartDataPiece's name
- boolean required: Is the PartDataPiece required to be present on a [MaterialParts](/Mods/ContentTweaker/Materials/Materials/MaterialPart/) in order to register it?

## ZenMethods
You can retrieve the following information from a PartType:

| ZenMethod    | Return Type |
|--------------|-------------|
| getName()    | string      |
| isRequired() | string      |

repository: kindlich/CraftTweaker-Documentation

gha_language: CSS

repo_name: kindlich/CraftTweaker-Documentation


text:
# Pixel Perfect Website

I built this project during week 1 at The Iron Yard Academy to utilize common HTML and CSS techniques to build a functioning, pixel-perfect website recreation of a PSD mockup.

## Live Demo:
* http://jjhampton.github.io/1.4-pixel-perfect

## Tools & Techniques:

* Semantic HTML elements for sectioning
* CSS properties for styling
* CSS layout techniques such as float, display inline-block, & absolute/relative/fixed positioning
* Google Fonts
* Font Awesome
* CSS3 Transitions for button and link hover states

### Installation:
* Other than a modern web browser, no additional requirements


text:
# Group Wallet

This website is part my _Group Wallet_ project.

You can find other part of this project in following links:
- [protobuf](https://github.com/chai-weijian/group-wallet.protobuf)
- [user-service](https://github.com/chai-weijian/group-wallet.user-service)
- [group-service](https://github.com/chai-weijian/group-wallet.group-service)
- [rest-api](https://github.com/chai-weijian/group-wallet.rest-api)

## Project Status - work in progress

I will progressively implement my ideas to this project. As I learn more and more technologies, the list of ideas are also expanding.

This project will be mark as completed only when I stop learning any new technologies, which probably wouldn't happen.

## Technologies

This website is build with some of my favourite front-end technologies:
- [React](https://reactjs.org/)
- [Next.js](https://nextjs.org/)
- [Typescript](https://www.typescriptlang.org/)
- [Firebase](https://firebase.google.com/)
- [Chakra UI](https://chakra-ui.com/)
- [SWR](https://swr.vercel.app/)


text:
# gem_rbs_collection: A collection of RBS for gems

**Naming note:** This repository was called `gem_rbs` before. We have renamed the repository to make it more clear that this is a collection of RBS files for gems.

RBS is a standard type signature syntax for Ruby programs.
This is a community managed collection of RBS files for gems which ships without RBS.

## Loading RBS from the repository

`git submodule` is the easiest way to import this collection to your project.

```
# Add new submodule inside your project
$ git submodule add https://github.com/ruby/gem_rbs_collection.git vendor/rbs/gem_rbs_collection
```

### Using gem RBS from `rbs` command

Specify the path with `--repo` option and use `-r` option to require RBS of a library.

```
$ rbs --repo vendor/rbs/gem_rbs_collection/gems -r redis list
```

### Using gem RBS from Steep

Steep uses `Steepfile` to configure library RBSs to load.

```rb
target(:lib) do
  repo_path "vendor/rbs/gem_rbs_collection/gems"
  library "redis"
end
```

### Loading RBS directory from the repository directory

> This is not recommended, but I'm writing this section to load RBS files for other tools which doesn't support this feature yet.

You can load RBS files through directory path.

```
$ rbs -I vendor/rbs/gem_rbs_collection/gems/redis/4.2 list
```

If you load RBS files with directory path, it loads everything in the directory.
This is different from when loading RBS files with lbrary name that ignores directories starting with `_` (underscore).

## Adding RBS of a gem

[A doc](https://github.com/ruby/rbs/blob/master/docs/repo.md) is available for this feature.

Adding RBS files for a gem can be done with 4 steps.

1. Set up environment
2. Generate a boilerplate
3. Write RBS files
4. Write tests

(And you can open a pull request to get your code published.)

### Set up environment

Run `bin/setup`.
It runs `bundle install` with `--gemfile` option for the case the working copy is at under a directory for your application.

`bin/rbs` would also help to run the commands with correct `--gemfile` option.

### Generate a boilerplate

Execute `bin/init_new_gem GEM_NAME`.
This script generates an empty RBS to `gems/GEM_NAME/VERSION/GEM_NAME.rbs`, and makes `_test` directory to test the gem.

Specify the _major_ and _minor_ version you are using would be great for most cases.

We recommend adding `_scripts`, `_test`, and `_src` directories.
We assume `_scripts/test` script runs test of the gem, `_test` directory contains files for testing, and `_src` is a git submodule for the source code of the version of the gem.

### Write RBS files

You can write RBS files.

#### Focus on the most important part of the API

You may want to write everything of a gem.
We don't recommend doing it especially when you are starting.

Writing high-quality type definitions are difficult.

Focus on examples available through the `README` or docs of the gem.
Focus on the APIs your app is using.

#### Avoid adding top-level type aliases and interfaces

We don't recommend adding top-level type aliases and interfaces.

```
# Don't do this.

type redis_config = { host: String?, port: Integer? }

# Define the type inside ::Redis namespace

class Redis
  type config = { host: String?, port: Integer? }
end
```

#### Documents are optional

RBS supports writing docs of methods and classes.
If you want, you can copy the docs of the methods from Ruby code written in RDoc or YARD.

We don't require the docs.
It definitely helps, but keeping the docs up-to-date is not easy enough.

### Write tests

We recommend writing some tests to confirm your RBS works well with application code.
It is important that the testing is to confirm the relationship between RBS and application code, not the consistency with RBS and the implementation.

You can test your code with the following steps.

1. Write a Ruby program which uses the gem code
2. Confirm the consistency between the program and RBS

#### Using Steep

I have been testing with [Steep](https://github.com/soutaro/steep).

Add a `Steepfile` in `_test` directory and write test scripts.
Then you can run `steep check` to type check the test scripts.

See existing gems for examples, like [redis/4.2](https://github.com/ruby/gem_rbs_collection/tree/main/gems/redis/4.2/_test) or [listen/3.2](https://github.com/ruby/gem_rbs_collection/tree/main/gems/listen/3.2/_test).


text:
# flask-mysql-employee-database-app

This repo provides a simple app which is based on flask and mysql database. Using this app, we can create employee database.

## Requirements

* Install MySQL from https://dev.mysql.com/downloads/installer/
* Refer employee.sql to create required database and table in MySQL
* Install requirements using following command
```bash
pip install -r requirements.txt
```

## Run application with python
Use following command to run the application:
```bash
python3 app.py
```


text:
# d3-charts

## Install

After cloning the repo, several Node.js modules will need to be installed in the `/src` directory using the `npm install` command:

```
$ npm install connect serve-static
```

## Run

Next, start the server:

```
$ node chart-server.js
```

## View

In your favorite browser, type the following URL in the address bar:

```
<IP_ADDRESS>:8080
```

Or, you can serve up a specific d3 chart:

```
<IP_ADDRESS>:8080/d3-multi-line.html
```

## TBD

Add a legend and tooltips.


text:
[![Travis build status](https://travis-ci.org/bboyle/form-validation.svg?branch=master)](https://travis-ci.org/bboyle/form-validation)
[![devDependencies](https://david-dm.org/bboyle/form-validation/dev-status.png)](https://david-dm.org/bboyle/form-validation#info=devDependencies)

This is a form validation package I have developed to deliver the UX I want in web forms
that use the HTML5 constraint validation API.

You're welcome to reuse, fork, modify etc. and chances are you will need to
(unless you like my markup and don't need any language other than English).

You may want to check out @jzaefferer's [jquery-validation](https://github.com/jzaefferer/jquery-validation)

## Notes

### Traversal

* find a `label` for a form field
* find a `group` containing a form field

### Attributes

* find the current `validationMessage` for a form field

### UI

* `.active` indicates user last interacted with this question or group
* display list of validation alerts in a box `.status`

### Validation
* validate html5 `@required`
* validate html5 `@type=email`

## TODO

* documentation!!
* separate submit suppression into a separate repo?
* html5 validation for test pages
* acceptance tests in multiple browsers

repository: bboyle/form-validation

repo_name: bboyle/form-validation


text:
---
layout: post
published: true
title: "Beekman 1802 - Orange Fudge Sauce"
featured: false
comments: true
type: photo
description: Yumm
headline: "Beekman 1802 - Orange Fudge Sauce"
categories:
  - Products
tags: [Products]
imagefeature: BeekmanOrangeFudge.jpg
---

Product: [Beekman 1802 Orange Fudge Sauce](http://www.littlelacebox.com/products/beekman-1802-goat-milk-hot-fudge-sauce)

Price: $12.99

So I received this fudge sauce in my February [Little Lace Box](http://littlelacebox.com?rfsn=93842.4b16b) and fell chocolaty in love that I just had to try the Orange flavor. I'm glad I did. I've always loved the combo of orange and chocolate, so I knew it was love at first sight.

![BeekmanOrangeFudgeBox.jpg](/images/BeekmanOrangeFudgeBox.jpg)
The box it came in from [Little Lace Box](http://littlelacebox.com?rfsn=93842.4b16b).

![BeekmanOrangeFudgeOpenBox.jpg](/images/BeekmanOrangeFudgeOpenBox.jpg)
They packed it safe alright, I had to dig through to find the fudge.

![BeekmanOrangeFudgeOpenBox.jpg](/images/BeekmanOrangeFudgePackaging.jpg)
Finally, fudge is found safely in bubble wrap.

![BeekmanOrangeFudgeOpenBox.jpg](/images/BeekmanOrangeFudgeBack.jpg)
I love what they said about their fudge, it was funny and.. well.. true. If you can't figure out how to eat this fudge, then yes, please put it back in the box and send it my way #NotKidding

![BeekmanOrangeFudgeOpenBox.jpg](/images/BeekmanOrangeFudgeIngredients.jpg)
I'm actually not a big fan of goats milk, but you can't really taste it. You can only taste chocolate orange awesomeness. And looking at the ingredients, I can see why. All natural whole ingredients - que applause.

**VERDICT:** I never knew I liked fudge and goats milk until I found Beekman 1802. And if you like orange flavor, try this version but make sure to also try their original flavor as that is a must. I'm more than comfortable paying the $12.99 price for this fudge awesomeness, and the jar size is quite big too. I always have a soft spot for good food and natural ingredients, so this fudge knocked it out of the park for me.


text:
MicronaxProwlBundle
================

This bundle provides a simple integration of the "[Prowl Library](https://github.com/xenji/ProwlPHP)" from Mario Mueller into Symfony2.

    <?php

    $prowl = $this->container->get('prowl');

The bundle provides a new `prowl` service.

## Installation

You need an prowlapp.com API-Key to use this software!

Installing the bundle via packagist is the quickest and simplest method of installing the bundle. Here are the steps:

### Step 1: Composer require

    $ php composer.phar require "micronax/prowl-bundle":"dev-master"

### Step 2: Enable the bundle in the kernel

    <?php
    // app/AppKernel.php

    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Micronax\ProwlBundle\MicronaxProwlBundle(),
            // ...
        );
    }

### Step 3: Configure your parameters

Just add the following to your config.yml

    micronax_prowl:
        debug: false
        provider_key: <your provider key>
        api_key: <your api key>
        app_name: <Applicatio Name>

## Usage
Usage is as simple as possible. Just call the following line of code everywhere in your application where you want to send prowl messages:

    $this->get('prowl')->notify('MESSAGE SUBJECT', 'MESSSAGE TEXT', 2);
    // where "3" represents an integer priority in between -2 (very low) and 2 (emergency)

repository: micronax/prowl-bundle

repo_name: micronax/prowl-bundle