text:
# IMESample
This is a simple project for C# IME(Input Method Editor) Application, which lets you create your own IME.
SampleIME is mainly designed for Tizen Mobile profile.

![PortraitPage](./Screenshots/portrait_ime.png)
![LandscapePage](./Screenshots/landscape_ime.png)

### Verified Version
* Xamarin.Forms : <IP_ADDRESS>934
* Xamarin.Forms.Platform.Tizen : <IP_ADDRESS>107
* Tizen.NET : 4.0.1-preview1-00043
* Tizen.NET.SDK : 1.0.0

### Supported Profile
* Mobile

### Author
* Sungwook Park<EMAIL_ADDRESS>


text:
# TweetBot
A Java tweet bot made by Horrgs.

## Goals
Add an AI (Artificial Intelligence) aspect to it.

### Goals of the AI Aspect
Have it be able to gather information such as news using the Google News API, Reddit threads that may appeal to me using jReddit and implementing Jabberwacky which is just a conversation with a bot.

## Commands
All commands will start with % as it's a rare character to Twitter. Right now the only commands are "%help" "%coinflip" and "%theydsaywhat".

license: MIT

repository: Horrgs/TweetBot

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: Horrgs/TweetBot


text:
---
title: 'Postgresql: Run on Docker'
date: 2020-04-06T17:33:59.511Z
tags:
  - til
---
So this midnight I tried to run postgresql 10 on docker. Few notes I get so far:

1. Use official image or build from official [Dockerfile](https://github.com/docker-library/postgres)
2. Provide postgres password using environment variable `POSTGRES_PASSWORD`
3. Never forget to store in persistence volume on host, use `-v /host/path/data:/var/lib/postgresql/data`
4. On default config pg_hba.conf, it will use MD5 auth-method. [(read for more here)](https://www.postgresql.org/docs/10/auth-pg-hba-conf.html)
5. I can't use .pgpass if auth-method is `MD5` or `password`
6. To use .pgpass, I need to change auth-method to `trust`

repository: wahyuoi/notes

gha_language: HTML

gha_license_id: MIT

repo_name: wahyuoi/notes


text:
[![IssuesCount](https://img.shields.io/github/issues-raw/FedeClaudi/pyinspect.svg)](https://img.shields.io/github/issues-raw/FedeClaudi/pyinspect)
[![license](https://img.shields.io/github/license/FedeClaudi/pyinspect.svg)](https://img.shields.io/github/license/FedeClaudi/pyinspect)
[![language](https://img.shields.io/github/languages/top/FedeClaudi/pyinspect.svg)](https://img.shields.io/github/languages/top/FedeClaudi/pyinspect)
[![language](https://img.shields.io/github/last-commit/FedeClaudi/pyinspect/master.svg)](https://img.shields.io/github/last-commit/FedeClaudi/pyinspect/master)
[![language](https://img.shields.io/github/stars/FedeClaudi/pyinspect?style=social.svg)](https://img.shields.io/github/stars/FedeClaudi/pyinspect?style=social)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

[![Twitter Follow](https://img.shields.io/twitter/follow/Federico_claudi.svg?style=social)](https://twitter.com/Federico_claudi)

# pyinspect - the python package for lazy programmers
**Don't remember a function's name?** Use `pyinspect` to look for it. \
**Don't remember what a function does?** Use `pyinspect` to print its source code directly to your terminal. \
**Can't figure out why you keep getting an error?** Use `pyinspect`'s fancy tracebacks to figure it out\
**Still can't figure it out, but too lazy to google it?** Use `pyinspect` to print Stack Overflow's top answer for your error message directly to your terminal!

... and a bunch of other features to make your life easier when coding.

[![gif](media/intro_cut.gif)](https://github.com/FedeClaudi/pyinspect/blob/master/media/intro_cut.gif)

An example of how `pyinspect` can be used to find and inspect functions lazily.

# Table of Contents
1. [Installing pyinspect](https://github.com/FedeClaudi/pyinspect#installing-pyinspect)
2. [When you can't remember a variable's name...](https://github.com/FedeClaudi/pyinspect#when-you-cant-remember-a-variables-name)
3. [When you can't remember a function's name...](https://github.com/FedeClaudi/pyinspect#when-you-cant-remember-a-functions-name)
4. [When you can't remember what a function does](https://github.com/FedeClaudi/pyinspect#when-you-cant-remember-what-a-function-does)
5. [When you can't fix that bug...](https://github.com/FedeClaudi/pyinspect#when-you-cant-fix-that-bug)
6. [When you **still** can't fix that bug...](https://github.com/FedeClaudi/pyinspect#tracebacks)
7. [When you got a question, ask Google](https://github.com/FedeClaudi/pyinspect#when-you-got-a-question-ask-google)
8. [When you... ](https://github.com/FedeClaudi/pyinspect#when-you)

## Installing pyinspect
It's as simple as:
``` shell
pip install pyinspect
```

## When you can't remember a variable's name..
 Fear not, becuse you can use `pyinspect` to print all variables in your local scope:

``` python

    import pyinspect as pi

    a = 'my variable'
    b = 'another variable'

    pi.what()  # print all local variables
```

or to look at a single variable in detail with:
``` python

    my_favourite_number = 21
    pi.what(a)
```

This will show you the variable content, where it has been defined and some of its attributes and methods. Something like:

## When you can't remember a function's name...
That's okay! You can use `pyinspect` to search for a function by its name!
E.g. to look for functions with `searc` in their name in `pyinspect`:

``` python
# import pyinspect
import pyinspect as pi

# Find the functions you're looking for
pi.search(pi, name='what')
```

This results in a table with all the function's matching your search `name`:

>**note**: search also looks for functions in sub-modules of the module given.
e.g.  `search(matplotlib, 'plot')` will look for methods across the entire `matplotlib` library!

`pyinspect.find` can also be used to find class methods. For example to look for a method with `export` in the name in `rich.console.Console`:
``` python
pi.search(Console, 'export')
```

>**note**: `search` also looks for methods matching your query
among the parents of the `class` you passed. Use `include_parents=False`
when calling `search` to restrict the search to just the class you've passed.
Methods of the parent class are highlighted in a different color!

>**PRO TIP:** if you don't pass a search name to `pyinspect.search` (e.g. `pyinspect.find(Console)`), `pyinspect.search` will print **all** functions and methods.

## When you can't remember what a function does
Okay, you've found the function you need, that's great. *But how does it work?*
You could openthe file where it's defined, scroll down to it etc... but this `pyinspect`, the package for lazy programmers! Instead of going thruogh that hastle why not printing the function's code directly to your terminal with a simple command:

``` python
# import pyinspect
import pyinspect as pi

# Look at how pyinspect.search works
pi.showme(pi.search)
```

which yields:

## When you can't fix that bug...
Sometimes you know what's causing an error, sometimes you don't. When you don't, it helps to know what the variables involved in the error are, possibly without having to go through the extra work of debugging stuff!

Once again `pyinspect` has a labour-saving solution: an advanced `traceback` functionality that gives you all the information you need to fix your bug (hopefully!). Just install `pyinspect`'s `traceback` at the start of your script: when get an error you'll get a helpful summary of what's going on with your code!

E.g.:
``` python
# import pyinspect and install the traceback handler
import pyinspect as pi

pi.install_traceback()  # use hide_locals=True to hide locals panels from your traceback

# make some buggy code
import numpy as np

a = np.ones(5)
b = "ignore this"  # a local variable not being used
c = np.zeros(4)  # ooops, wrong size

a + c  # this will give an error
```

and this is the traceback:

> **note**: although we defined three variables (`a`, `b`, `c`) only two where in the line causing the error (`a + c`). `pyinspect` then highlights `a` and `c` in the traceback as this is what you need to know to fix your bug. If you want `pyinspect` to **only** show the variables in the error line pass `relevant_only=True` to `pi.install_traceback()`

**pro tips**:
* if you want to show **all** items in the `local` scope (e.g. also imported modules, not just variables) then you can use `all_locals=True` in `pi.install_traceback()`
* if you don't want the locals to be shown at all, then use `hide_locals=True`
* if you want more or less extensive tracebacks, you can use `keep_frames` to decide how many `frames` to shown in nested tracebacks (i.e when a function `a` calls a function `b` and the error comes up in `b`, do you want to see only the locals in `b` or in `a` *and* `b`?)

## When you **still** can't fix that bug...
Time to do what any real programmer does in this situation... google it / copy-paste an answer from Stack Overflow. But that involves pulling up your browser, opening a new tab, typing stuf... too much work!

When an error comes up, `pyinspect` gives you the opportunity to automate this work away by doing the googling for you.
You can do that in two ways:

1. passing `enable_prompt=True` to `install_traceback`: after the error traceback a prompt will come up asking if you want to look for solutions online, type `y`.
2. In a terminal window use the `why` command and `pyinspect` will automatically lookup solutions to the last error you've had [note you need to have installed `pyinspect`'s tracebacks for it to record errors].

Either way, you get 3 things:
* A description of your error
* Links to the top 3 results on Google
* A neat render of a Stack Overflow question and answer related to your error.

Check it out:

## When you got a question, ask Google
Ever found yourself googling the same basic command over and over because you keep forgetting what the syntax is?
If you do (and I know you do), or if you have any other question, now you can look for answers directly in python with `pynspect.ask`.
Using it is fairly simple:

```python
pi.ask("python Concatenate two lists?")
```

>**note**: you can also use `ask` in your terminal to lookup answers to your questions. E.g.:
```
ask "Python how to concatenate strings"
```

## When you...
`pyinspect` has a few more useful little features you might find yourself using from time to time. One of our favourites is `panels`: a simple why to print neat messages to terminal, for when you need to communicate with your users.

```python

import pyinspect as pi

pi.warn('This is a warning', 'Ooops, something might be wrong!')

pi.ok('You got this!', 'Panels are simple, but nice. Checkout `pyinspect.panels` to see what other kind of panels there are!')
```

You can also use `Report`, a more advanced panel which allows you to create a more structured and detailed panel (see `pi.whats_pi()`):

As an example, see how I've used `Report` to render [my CV](https://github.com/FedeClaudi/My_CV)

## Contributing
Contributions are welcome! Start a pull request if you have a change you'd like to submit or open an issue to report a bug or request a new feature to be added to `pyinspect`

## Aknowledgements
`pyinspect` is mostly a thin wrapper on top of the **awesome** [`rich`](https://github.com/willmcgugan/rich) library, so a huge thank you goes to @willmcgugan for the great job done with `rich`.


text:
# animated_bubblebottom_nav

Animated Bubble  Bottom Navigation

![Fancy Gif](https://github.com/Urvish123/Animated_bubble_bottom_navigation/blob/main/bottom_vidg.gif "Fancy Gif")

## Getting Started

Add the plugin (pub coming soon):

```yaml
dependencies:
  ...
  animated_bubblebottom_nav: ^0.0.3
```

## Basic Usage

Adding the widget
```dart
  @override
  Widget build(BuildContext context) {
    return BottomBar(
     //Array of icon which you want in bottom item.   #Required
      iconArray: [ 'assets/images/icons/icon-home.png', 'assets/images/icons/icon-category.png',
        'assets/images/icons/icon-search.png', 'assets/images/icons/icon-cart.png','assets/images/icons/icon-user.png'],
      //Array of Screen which you want open when bottom item clicked   #Required
      screenArray: [Home(),Category_(),Search(),Cart(),Profile()]
    );
  }
```

Change BottomItem color
there are two types of color we have one is bottomItemActiveColor & second is bottomItemInactiveColor
```dart
  @override
  Widget build(BuildContext context) {
    return BottomBar(
      iconArray: [ 'assets/images/icons/icon-home.png', 'assets/images/icons/icon-category.png',
        'assets/images/icons/icon-search.png', 'assets/images/icons/icon-cart.png','assets/images/icons/icon-user.png'],
      screenArray: [Home(),Category_(),Search(),Cart(),Profile()],
      bottomItemActiveColor: Colors.lightBlue,
      bottomItemInactiveColor: Colors.blueGrey.withOpacity(0.5),
    );
  }
```

Change color of bubble
there are two types of bubble we have that why we should put two color one is bubblePrimaryColor & second is bubbleSecondaryColor
```dart
  @override
  Widget build(BuildContext context) {
    return BottomBar(
      iconArray: [ 'assets/images/icons/icon-home.png', 'assets/images/icons/icon-category.png',
             'assets/images/icons/icon-search.png', 'assets/images/icons/icon-cart.png','assets/images/icons/icon-user.png'],
           screenArray: [Home(),Category_(),Search(),Cart(),Profile()],
           bubblePrimaryColor: Colors.black87,
           bubbleSecondaryColor: Colors.deepOrange,
    );
  }
```

Change color of circle
there are two types of circle we have that why we should put two color one is circleStartColor & second is circleEndColor
```dart
  @override
  Widget build(BuildContext context) {
    return BottomBar(
      iconArray: [ 'assets/images/icons/icon-home.png', 'assets/images/icons/icon-category.png',
        'assets/images/icons/icon-search.png', 'assets/images/icons/icon-cart.png','assets/images/icons/icon-user.png'],
      screenArray: [Home(),Category_(),Search(),Cart(),Profile()],
      circleEndColor: Colors.deepPurple,
      circleStartColor: Colors.green,
    );
  }
```

branch_name: refs/heads/main


text:
# exchange-rate-converter
A simple JavaScript exchange rate converter with options to swap currencies

## Motivation

This was a quick test at my ability to use the Fetch API and manipulate JSON objects.

## Tech used
HTML, CSS and JavaScript. No frameworks were harmed in the making of this project.

This also uses the [free Exchange Rate API](https://www.exchangerate-api.com/). Although the free tier only allows you to use USD or EUR as your base currency, the code that I've written calculates "synthesised" rates by using the US dollar as a go between to ensure that there aren't any errors.

For example, if you wanted to convert from GBP to EUR, it first converts from USD to GBP,= and then from USD to EUR before finally dividing the latter by the former to get the GBP to EUR rate.

## Features
There is a swap button which allows you to swap the currencies around quickly if you want the inverse of the currency conversion. That means you can switch to calculating how many US dollars you'd get for one Euro and how many Euros you'd get for one US dollar quickly and easily.

## Credits
I got inspired to build this after seeing [Brad Traversy's Exchange Rate Converter from his Vanilla Web Projects](https://github.com/bradtraversy/vanillawebprojects/tree/master/exchange-rate), so I've been heavily influenced by that.

I looked at his code, recreated it exactly, wrote down the project specifications, and then created this mini web app from scratch based solely on those project specifications without looking at Brad's code. Any similarities are purely coincidental.

I've also been influenced by the UI used by [Transferwise](https://transferwise.com/) so you might see some similarities between my project and that too.

## License
This is under an MIT licence. You can do whatever you want wth the code as long as you include the original copyright and license notice in any copy of the software/source.

MIT © [Nathan Ifill](https://www.nathanifill.com)

repository: nathanifill/exchange-rate-converter

repo_name: nathanifill/exchange-rate-converter


text:
---
title: "Dealing with MySQL nulls and unique constraint"
path: "/mysql-nulls"
tags: ["databases", "mysql"]
excerpt: If you have a database system with soft deletes and unique indexes you might have faced some problems. Imagine that a user deleted some record and wants to add another one with the same unique value. He can’t do that since unique constraint would be violated...
created: 2019-03-29
updated: 2019-03-29
---

# What’s the problem?

If you have a database system with soft deletes and unique indexes you might have faced some problems. Imagine that a user deleted some record and wants to add another one with the same unique value. He can’t do that since unique constraint would be violated. As a developer, you may understand what just happened, but let’s picture a frustrated user that wants to add another contact to his address book, but an app keeps telling him that it already exists. It would be kind of:

Unique constraints are important. I hope it’s obvious. You don’t want to check if some record exists every time a user adds something through your app. Firstly making two queries instead of one sounds like a bad idea, secondly, let’s allow the database to do its job. Not to mention that you can face some problems with asynchronous processes that would want to insert the same record at the same time.

## How to solve the problem?

Let’s say you have some database table consisting of articles. And there can be only one article with a given name, so you have a unique constraint on `articles.name` and because of _reasons_ you don’t want to do hard deletes. What you want is to have soft deletes to keep all the data in the database and a user that is only supposed to see non-deleted articles and that is allowed to add another one with the same name as an article that was already deleted. In other words, you don’t care about the unique index for deleted records — you can have as many as possible deleted articles with the same name. But you do care that unique constraint should not be violated for not deleted ones.

### Some intuitive solution

The first solution that would come to my mind is to add a _deleted_at_ column with type _TIMESTAMP_ and extend a constraint to `(name, deleted_at)`. Let’s try it!

```sql
    ALTER TABLE articles
        ADD deleted_at TIMESTAMP NULL DEFAULT NULL,
        DROP INDEX name,
        ADD CONSTRAINT UNIQUE (name, deleted_at);
```

And then let’s try to add a record and then soft delete it:

```sql
    INSERT INTO articles (id, name, author, text)
        VALUES ("How to finish university?", "Jon Doe", "");

    UPDATE articles SET deleted_at = now() WHERE name = "How to finish university?";
```

Great! Worked. Let’s see if I can add the same record again.

I can! Actually, I can do it many times. Inserting the same article again and again. Oops 🙊 The unique constraint doesn't work anymore.

Why is that? It’s because for all not deleted articles we have a unique constraint on `(<name>, NULL)` and for MySQL every null is unique. With this solution we can, in fact, have many items with the same unique key soft deleted but we also end up with our main goal of having articles names unique not working. Too bad.

To deal with this problem I have three working solutions.

### Solution #1

In the first solution I’m going to add a new column similar as earlier but this time I will store the time of deletion in Unix format. So that with a unique constraint on `(name, deleted_at_unix)` I’m allowed to still have unique articles names since all not deleted record would have the column _deleted_at_unix_ set to 0 and `(<name>, 0)` is a unique value.

```sql
    ALTER TABLE articles
        ADD deleted_at_unix int (10) DEFAULT 0;

    ALTER TABLE articles
        DROP INDEX name,
        ADD CONSTRAINT UNIQUE (name, deleted_at_unix);
```

So, every time I want to soft-delete an item I set _`delete_at_unix_ as current Unix time.

### Solution #2

Now I’m going back to my not working solution and I’ll try to fix it. I’ll use _TIMESTAMP_ for a _deleted_at_ column again but then I’ll add some magic. Be cautious.

```sql
    ALTER TABLE articles
        ADD COLUMN deleted_at TIMESTAMP NULL DEFAULT NULL,
        DROP INDEX name;
```

The difference is that I won’t create a unique constraint on `(name, deleted_at)` as previously but I’ll add yet another column. It’ll be a virtual column with value either **NULL** in case if the article was deleted or **1** if not.

```sql
    ALTER TABLE articles
        ADD not_archived int (1) GENERATED ALWAYS AS (IF(deleted_at IS NULL,  1, NULL)) VIRTUAL;
```

And the unique constraint will be for `(name, not_archived)`:

```sql
    ALTER TABLE articles
        ADD CONSTRAINT UNIQUE (name, not_archived);
```

Similar as in the **0#** solution (not working one) to delete a record I need to fill _deleted_at_ column with the current timestamp.

### Solution #3

The third solution is kind of similar to the second but now I think about each record as it can be in two states — active or not.

```sql
    ALTER TABLE articles
        ADD COLUMN active BIT NULL DEFAULT 1,
        ADD CONSTRAINT UNIQUE (name, active);
```

In this case, all not deleted articles would have _active_ column set to **1**. _But, deleted ones won’t be set to 0_. In order to soft delete a record, I need to set _active_ column to **NULL**. Thanks to this and due to the fact that nulls are unique in MySQL I will be able to have many deleted articles with the same name.

## Wrapping up

If I was about to choose one of these solutions I’d say I prefer the **#1 solution** (with Unix time) the most. But I guess it’s good to have some alternatives, be able to compare them and choose the one that fits the most to your system.

repository: beerose/blog

gha_language: TypeScript

repo_name: beerose/blog


text:
# async-pipeline

async-pipeline allows you to build a complex conditional flow from loosely coupled components.

[![Build Status](https://travis-ci.org/yavorskiy/async-pipeline.svg?branch=master)](https://travis-ci.org/yavorskiy/async-pipeline)

```
npm install async-pipeline
```

Imagine you have set of processing operations that might be applied in different order based on input and intermediate results.

![Processing graph](https://cdn.rawgit.com/yavorskiy/async-pipeline/04a50bbe/docs/graph.svg)

Of course you can build it as `Promise` chain(s) but it will look hard to read at least. And over time, after more additions, you have a good chance it to turn into unreadable code mess.

Another much easier approach would be to build the flow based on PubSub, and let processing functions listen and emit messages with payloads. This would let you split the flow into easily tested atomic stages doing one thing at a time, not coupled to other components. Plus, you can have multiple functions listening to the same events and build parallel secondary flows like logging and tracking aside from the main logic.

`async-pipeline` is helping to build such message hub by adding few generic features on top of `EventEmitter`:

- optionally apply transition constraint map
- catch errors and route them to one place
- track and log all transitions
- provide flow control events: `@end`, `@error`
- track execution time in milliseconds using `process.hrtime`

## Example

```js
new Pipeline({
  transitions: {
    'start': ['stage-1:progress', 'stage-1:done'],
    'stage-1:done': ['stage-2:done']
  }
})
  .on('@error', console.error.bind('ERROR:'))
  .on('@end', dump => {
    console.log('END:', inspect(dump, {depth: 10}))
  })
  .on('start', function (count) {
    let i = 0
    while (i++ < count) setTimeout(this.emit, i * 100, 'stage-1:progress', i)
    setTimeout(this.emit, (count + 1) * 100, 'stage-1:done')
  })
  .on('stage-1:done', function () {
    setTimeout(this.emit, 200, 'stage-2:done', 'hello', 'there')
  })
  .on('stage-2:done', function(...args) {
    console.log('after stage-2', ...args)
    this.end()
  })
  .on('stage-1:progress', console.log.bind(console, 'stage1'))
  .start('start', 5)
```

the code would output following:

```
stage1 1
stage1 2
stage1 3
stage1 4
stage1 5
after stage-2 hello there
END: [ { event: 'start',
    payload: [ 5 ],
    routes:
     [ { event: 'stage-1:progress',
         payload: [ 1 ],
         routes: [],
         time: 107 },
       { event: 'stage-1:progress',
         payload: [ 2 ],
         routes: [],
         time: 200 },
       { event: 'stage-1:progress',
         payload: [ 3 ],
         routes: [],
         time: 305 },
       { event: 'stage-1:progress',
         payload: [ 4 ],
         routes: [],
         time: 402 },
       { event: 'stage-1:progress',
         payload: [ 5 ],
         routes: [],
         time: 503 },
       { event: 'stage-1:done',
         payload: [],
         routes:
          [ { event: 'stage-2:done',
              payload: [ 'hello', 'there' ],
              routes: [],
              time: 806 } ],
         time: 604 } ],
    time: 0 } ]
```

## API

Call `new Pipeline(options)` or just `Pipeline(options)` to get a pipeline instance. Where `options` are:

- `debug` - optional function to print internal logs, easiest way to get debugging output is to pass `{debug: console.log}`
- `contextAPI` – `true` by default, expose API controls to the handlers through `this`, otherwise pass as a first argument
- `transitions` - optional mapping defining allowed transitions and entry points. Example:

```js
{
  'from-event-0': ['to-event-1', 'to-event-2'],
  'from-event-2': ['to-event-3']
}
```

### Pipeline methods

- `this.start('event', ...payload)` - start the flow with event `event` and optional payload. This will throw if `options.constraints` is set and has no `event` key

- `this.context(dataObject)` - defines data object available to all handlers through `this.context()`

### Internal events and their payloads

- `@all (event, ...payload)` - catches all events, emitted right before normal event. Useful mainly for testing
- `@end (trace)` - fired once any handler calls `this.end()`. Also automatically triggered on unexpected errors
- `@error (error, trace)` - fired if any handler has thrown or explicitly called `this.end(error)`. This will cause an uncaught exception bubbling to the `process` level if no handler registered

### Handler context methods

Each handler except ones for internal events has access to following methods exposed though call context. Keep in mind that handlers should be defined as `function() {}`, arrow functions would forcefully override the context

- `this.end([error])` - end the flow and void all eventual events. If `error` passed that it's considered an emergency shutdown. In either case if will end up triggering `@end` event

- `this.emit('event', ...payload)` - cast an event with arbitrary payload. This will throw if emitted event is violating `options.constraints`

- `this.context([dataObject])` - getter/setter for context data kept shared for all handler. This should be used wisely though to keep handlers uncoupled

- `this.safe(fn)` - decorator for async calls that may throw within handler. Following would throw to the top level unless wrapped into `safe()`:

```js
  pipeline.on('event', () => {
    const later = this.safe(() => { throw new Error() })
    setTimeout(later, 0)
  })
```

## Error handling

Errors thrown from within event handlers will be caught and routed as `@error` event payload. However those would bubble up to the top if no handler defined

Errors thrown from within internal events (`@end`, `@error`) are always bypassing `@error` and propagate to the top to avoid recursive failures. Same for the failures in `start()` and `on()` calls

## Alternative EventEmitter

If you Node's `EventEmitter` doesn't work for you for whatever reason then you can inject the alternative

```js
Pipeline = Pipeline.di({EventEmitter: EventEmitterClass})
```

license: ISC

repository: syavorsky/async-pipeline

repo_name: syavorsky/async-pipeline


text:
# CliOne

This library helps to create command line (CLI) operator for PHP in Windows, Mac and Linux

[![Packagist](https://img.shields.io/packagist/v/eftec/CliOne.svg)](https://packagist.org/packages/eftec/CliOne)
[![Total Downloads](https://poser.pugx.org/eftec/CliOne/downloads)](https://packagist.org/packages/eftec/CliOne)
[![Maintenance](https://img.shields.io/maintenance/yes/2023.svg)]()
[![composer](https://img.shields.io/badge/composer-%3E1.6-blue.svg)]()
[![php](https://img.shields.io/badge/php-7.1-green.svg)]()
[![php](https://img.shields.io/badge/php-8.x-green.svg)]()
[![CocoaPods](https://img.shields.io/badge/docs-70%25-yellow.svg)]()

## Features

✅ Windows, Linux and Mac Compatible.

✅ This library truly minimalist and simple, it only consists of 2 classes and nothing more and no external dependency.

✅ Arguments & user input

✅ This library was aimed to (optionally) fallback to user-input if the argument is missing.

✅ Colors available

✅ The design is mostly fluent (it adjusts to the width of the screen)

✅ Validation of values

✅ Support NO_COLOR environment variable. See https://no-color.org/

![](docs/examplecomplete.jpg)

## Getting started

Add the library using composer:

> composer require eftec/clione

And create a new instance of the library

```php
$cli=new CliOne(); // instance of the library
```

## Usage

For example, let's say we need to create a CLI code to read an information and save into a file.

```shell
>php basic.php read -o result.json
```

We have two arguments, the first (read) is in the first position, and it doesn't have any "-". The second is "-o" that
it is our flag with a value.

So we could create our arguments.

```php
$cli=new CliOne();
$cli->createParam('read',[],'first')->add(); // a positional argument (the first one) value-less
$cli->createParam('o',[],'flag')->add(); // a simple flag "-o"
```

And we could evaluate as

```php
$cli->evalParam('read');
$cli->evalParam('o');
// So we could obtain our values as:
var_dump($cli->getParameter('read')->value);
var_dump($cli->getParameter('o')->value);
// or as
var_dump($cli->getValue('read'));
var_dump($cli->getValue('o'));
```

It will return **false** if we don't set a value, and it will return the value it we set it.

```shell
>php basic.php read -o result.json
string(4) "read"
string(11) "result.json"
```

> **The parameters are created and evaluated separately because it allows to do more powerful operations with it.**
>
> For example, sometimes we want to show the help (the list of parameters available) without evaluating the parameters.

Ok, but now what if we want to create an alias of "-o"

```php
var_dump($cli->getParameter('o',['output','outputresult'])->value);
```

So we could call using this line

```shell
php basic.php read --output result.json
# or also
php basic.php read --outputresult result.json
# or also
php basic.php read -o=result.json
```

> **If the parameter is a flag, then the alias is a longflag ("--"). If the parameter is a longflag then the alias is a
flag.**

But let's say we need to ask for a password, however we want to be entered interactively.

```php
$cli->createParam('pwd',[],'flag') // we create the parameter
    ->setInput(true,'password') // and we ask (if the parameter is not entered as flag)
                                //for user input of the type password (however the password is not hidden visually)
    ->add();
$cli->evalParam('pwd');   // and don't forget to evaluate the parameter
```

So it will look like:

```shell
> php .\basic.php read -o result.json
Select the value of pwd [*****] :123
```

Now, let's say something more advanced, multiple options, we want to select the type of file: json, csv, html and xml

Our code

```php
$cli->createParam('type',[],'flag')
    ->setInput(true,'option',['json','csv','xml','html'])
    ->add();
```

And the result:

```shell
PS > php .\basic.php read -o result.json
Select the value of pwd [*****] :111
[1] json
[2] csv
[3] xml
[4] html
Select the value of type [] :2 #you could use TAB key for autocomplete, cool!
```

> **List of values are divided in two values, the visual value (simply called value), and the key-value.**. In this
> example, "csv" is a value and its key-value is "2".
>
> The list of values allows associative arrays and indexed arrays. Indexed arrays are renumbered to start in 1.

You could also enter

> php .\basic.php read -o result.json -pwd 123 -type json

Now, you can show the parameters ("show the syntax help") as follows:

```php
$cli->showParamSyntax2('parameters:');
```

But it will look plain.

It is because you can add a description, change the question and add more help information

```php
$cli->createParam('type',[],'flag')
    ->setDescription('it is the type of output','what is the option?',['it is the help1','example: -option xml'])
    ->setInput(true,'option',['json','csv','xml','html'])
    ->add();
```

So it will look like: (in colors)

```shell
parameters:
read                         The command [read]
-o, --output, --outputresult The output file without extension [result.json]
                             example: -o file
-pwd                         It is the password [*****]
-type                        it is the type of output [csv]
                             it is the help1
                             example: -option xml
```

There are more operations available but the basic is there.

# Table of contents

<!-- TOC -->
* [CliOne](#clione)
  * [Features](#features)
  * [Getting started](#getting-started)
  * [Usage](#usage)
* [Table of contents](#table-of-contents)
  * [Flow](#flow)
  * [Input as arguments](#input-as-arguments)
  * [Input interactive](#input-interactive)
    * [User input (interactive)](#user-input-interactive)
    * [Customize user input](#customize-user-input)
  * [menu](#menu)
    * [addMenu()](#addmenu)
    * [addMenuItem()](#addmenuitem)
    * [addMenuItems()](#addmenuitems)
    * [evalMenu()](#evalmenu)
    * [clearMenu()](#clearmenu)
    * [example](#example)
  * [Examples](#examples)
    * [Example using arguments](#example-using-arguments)
    * [Example using user input](#example-using-user-input)
    * [Example with a game](#example-with-a-game)
    * [Example colors](#example-colors)
    * [Example tables](#example-tables)
  * [Types of user input](#types-of-user-input)
  * [Types of colors](#types-of-colors)
  * [Definitions](#definitions)
  * [debug](#debug)
  * [Compatibility](#compatibility)
  * [Changelog](#changelog)
<!-- TOC -->

## Flow

* (optional) you can set the current value using the method setParam()
* If the type of parameter is not "onlyinput" and "none", then it reads the parameter
    * Example: php program.php -param1 value --param2 -param3="hello world" parampositional
* If the parameter is found, then it is returned, **end of the flow**.
* If the parameter is not found then
    * If setCurrentAsDefault() is set, and the current value is not null, then the default value is the current value.
    * Otherwise, the default value is the value set using the method setDefault(). If none, then it uses null.
* if input is true setInput(true) then it asks to user-input the value
    * if the user doesn't fill the information, then it returns the default value (if any), **end of the flow**
    * if the user fills the information, but it is incorrect, then it asks again and again.
    * if the user fills the right information, then it returns this value, **end of the flow**
* if input is true setInput(false) then
    * Note: we were unable to read the values of the argument, and we don't want to read from user input.
    * it returns the default value, and it could raise an error, **end of the flow**

Note:

* isRequired() if the value is missing, then it shows an error.
* setAllowEmpty() if the value is empty (not missing), then it allows to enter an empty value

## Input as arguments

```shell
php mycli.php subcommandfirst subcommandsecond -flag valueflag --longflag valueflag2 subcommandlatest
```

The system allows reading multiple types of arguments

* **first**: this argument does not have value, and it is position (in the very first position),
  it must be not be prefixed with a "-", otherwise it would be considered a flag instead of a positional argument.

```shell
cliprogram.php first # the value obtained is "first".
```

* **command**: it is similar to **first,** but it does not compare the name of the argument.

```shell
cliprogram.php com -flag # first returns "com" if the argument is named first.  command returns "com" regardless of its name.
```

* **second**: this argument is also positional (second position) and does not have any value

```shell
cliprogram.php first second -someflag # the value obtained is "second"
```

* **last**: this argument is also positional, and it is always at the latest argument

```shell
cliprogram.php first second  last # the value obtained is "last"
```

* **flag**: the argument is prefixed with a single "-". This argument not need to be a single character.

```shell
cliprogram.php -flag hello # the value of the flag called "flag" is "hello"
```

* **longflag**: the argument is prefixed with a double "--"

```shell
cliprogram.php --flag hello # the value of the doubleflag called "flag" is "hello"
```

* **onlyinput/none**: the system never read it as argument, so it could be user-input.
    * none means that the argument is only user-input, and it must not be stored.

```shell
cliprogram.php  # "onlyinput/none" could not be obtained via command line
```

The argument could be created as:

```php
// program.php -f hello
// or
// program.php -f=hello
// or
// program.php -f "hello world"
$cli->createParam('f','flag')->add();  // add() is important otherwise the parameter will not be create.
```

And it could be read as:

```php
$result=$cli->evalParam('name'); // $result->value will return "hello"
```

Now, what if you want to create multiples alias for the same parameter.

```php
// program.php -h
// or
// program.php --help
$cli->createParam('h','flag',['help'])->add();  // it adds an alias longflag called "help"
```

## Input interactive

There are several configuration to set an input interactively.

By default, every parameter is read as argument. If the value is read as argument, then it is not asked interactively.

However, if the parameter is of the type "**none**" or "**onlyinput**", then they are only obtained by user input (
interactively).

Example:

```php
$cli->$t->createParam('paramname',[],'none');
```

### User input (interactive)

With the method setInput() we set that this parameter could also be read interactively.

```php
$cli->$t->createParam('paramname',[],'none')->setInput();
```

Example, let's say the next example:

```php
$cli=new CliOne();
$cli->createParam('p1',[],'none')
    ->setInput()
    ->add(); // we create the param
$cli->evalParam('p1'); // and we evaluated the parameter
```

![](docs/basic1.jpg)

Now, this input accepts any kind of text. But there is many kind of user input.

| type        | description                                                           | argument                            | example                                                        |
|-------------|-----------------------------------------------------------------------|-------------------------------------|----------------------------------------------------------------|
| number      | It allows any kind of number                                          |                                     | setInput(true,"number")                                        |
| range       | it only allow number between a range of values                        | [1,20]                              | setInput(true,"range",[1,10])                                  |
| string      | It allows any type of value                                           | (used for auto complete)            | setInput(true,"string")                                        |
| password    | It allows any type of value but the  default value is never displayed | setInput(true,"password")           |                                                                |
| multiple    | it allows to check one or multiple values using 1 column              | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"multiple",['key1'=>'value1','key2'=>'value2'])  |
| multiple2   | it allows to check one or multiple values using 2 columns             | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"multiple2",['key1'=>'value1','key2'=>'value2']) |
| multiple3   | it allows to check one or multiple values using 3 columns             | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"multiple3",['key1'=>'value1','key2'=>'value2']) |
| multiple4   | it allows to check one or multiple values using 4 columns             | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"multiple4",['key1'=>'value1','key2'=>'value2']) |
| option      | it allows to select a value from a list using 1 column                | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"option",['key1'=>'value1','key2'=>'value2'])    |
| option2     | it allows to select a value from a list using 2 columns               | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"option2",['key1'=>'value1','key2'=>'value2'])   |
| option3     | it allows to select a value from a list using 3 columns               | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"option3",['key1'=>'value1','key2'=>'value2'])   |
| option4     | it allows to select a value from a list using 4 columns               | ['key1'=>'value1','key2'=>'value2'] | setInput(true,"option4",['key1'=>'value1','key2'=>'value2'])   |
| optionshort | It allows a selection of values                                       | ["yes","no"]                        | setInput(true,"multiple4",['key1'=>'value1','key2'=>'value2']) |

Option returns a value and a value-key. Value is the content visible. And value-key, is the content selected by the
user.

**Example Option:**

```php
$cli=new CliOne();
$cli->createParam('p1',[],'none')
    ->setInput(true,'option2',['key1'=>'value1','key2'=>'value2','key3'=>'value3','key4'=>'value4'])
    ->add(); // we create the param
$cli->evalParam('p1');
$cli->showLine("value :".$cli->getValue('p1'));
$cli->showLine("valuekey :".$cli->getValueKey('p1'));
```

![](docs/basic2.jpg)

**Example Multiple:**

```php
$cli=new CliOne();
$cli->createParam('p1',[],'none')
    ->setInput(true,'option2',['key1'=>'value1','key2'=>'value2','key3'=>'value3','key4'=>'value4'])
    ->add();
$cli->evalParam('p1'); // value returns an associative array with the values selected, example: ["value1","value3"]
```

![](docs/basic3.jpg)

### Customize user input

It is possible to customize the input by changing the help description, changing the question, showing an example or
showing a value to the argument

```php
$cli=new CliOne();
$cli->createParam('p1',[],'none')
    ->setInput()
    ->setDescription('it is for help','what is the value of p1?',['help line1','help line 2'],'the argument is called p1')
    ->add();
$cli->evalParam('p1');
```

## menu

You can create a menu using the next methods

### addMenu()
It creates a new menu

### addMenuItem()
It adds an option to a menu

### addMenuItems()
It adds multiple options to a menu

### evalMenu()
It executes a menu

### clearMenu()
It clears a menu.

### example
```php
class ClassService {
  public function menuHeader(CliOne $cli) { /* todo: add header code */ }
  public function menuFooter(CliOne $cli) { /* todo: add footer code */ }
  public function menuOption1(CliOne $cli) { /* todo: add menu option 1 code */ }
  public function menuOption2(CliOne $cli) { /* todo: add menu option 2 code */ }
}
$obj=new ClassService();

$cli = new CliOne();
$cli->addMenu('menu1', 'header','footer');
$cli->addMenuItem('menu1','option1', 'option #1'
  ,function($cli) {$cli->showLine('calling action1');$this->assertTrue(true, true);});
$cli->addMenuItem('menu1','option2', 'option #2');
$cli->addMenuItem('menu1','option3', 'option #3','navigate:menu1.1');
$cli->addMenuItems('menu1',['option4'=>'option #4','option5'=> 'option #5']); // adding multiples options

$cli->addMenu('menu1.1', 'header2','footer2');
$cli->addMenuItem('menu1.1','option1', 'option #1.1');
$cli->addMenuItem('menu1.1','option2', 'option #2.1');
$cli->addMenuItem('menu1.1','option3', 'option #3.1');
$cli->addMenuItem('menu1.1','option4', 'option #4.1');
$cli->addMenuItem('menu1.1','option5', 'option #5.1');
$cli->evalMenu('menu1',$obj); // runs the menu.
$cli->showLine('exit ok');
$cli->clearMenu();
```

## Examples

### Example using arguments

[example/example1.php](example/example1.php)

And create the next code

```php
// example1.php
// don't forget to add autoloader, namespace, etc.
$cli=new CliOne(); // instance of the library
if($cli->isCli()) { // we validate if we are running a CLI or not.
  $cli->createParam('param1') // the name of the parameter
        ->setDescription('Some description','question?') // description and question
        ->setRequired(true) // if the field is required
        ->setDefault('param1') // the default value If the value is not found
        ->add(); // it adds a parameter to the cli
  $param1=$cli->evalParam('param1'); // then we evaluate the parameter.
  var_dump($param1->value);
}
```

So you can run as:

![](docs/example1.jpg)

### Example using user input

You can ask for user input of the user.

[example/example2.php](example/example2.php)

```php
$cli=new CliOne();
if($cli->isCli()) {
    $cli->createParam('param1')
        ->setDescription('This field is called param1 and it is required')
        ->setInput(true,'string')
        ->setRequired(true)
        ->setDefault('param1')
        ->add();
    $param1 = $cli->evalParam('param1');
    var_dump($param1->value);
}
```

It will show the next result

![](docs/example2.jpg)

### Example with a game

[example/examplegame.php](example/examplegame.php)

![docs/guess.jpg](docs/guess.jpg)
Image (c) George Beker

![docs/examplegame.jpg](docs/examplegame.jpg)

### Example colors

You can see the tags available in [Types of colors](#types-of-colors)

[example/examplecolor.php](example/examplecolor.php)

```php
$cli->showLine("<bold>bold</bold>");
$cli->showLine("<dim>dim</dim>");
$cli->showLine("<bred>background red</bred>");
$cli->showLine("<bblue>background red</bblue>");
$cli->showLine("<bwhite><black>background white</black> </bwhite>");
$cli->showLine("<byellow><blue>background yellow</blue></byellow>");
$cli->showLine("<red>error</red> (color red)");
$cli->showLine("<yellow>warning</yellow> (color yellow)");
$cli->showLine("<blue>information</blue> (blue)");
$cli->showLine("<yellow>yellow</yellow> (yellow)");
$cli->showLine("<green>green</green> (color green)");
$cli->showLine("<italic>italic</italic>");
$cli->showLine("<bold>bold</bold>");
$cli->showLine("<bold><yellow>bold yellow</yellow></bold>");
$cli->showLine("<strikethrough>stike</strikethrough>");
$cli->showLine("<underline>underline</underline>");
$cli->showLine("<cyan>cyan</cyan> (color cyan)");
$cli->showLine("<magenta>magenta</magenta> (color magenta)");
$cli->showLine("<bold><cyan>bold cyan</cyan></bold> (color cyan)");
$cli->showLine("<bold><magenta>bold magenta</magenta></bold> (color magenta)");
$cli->showLine("<bblue><col0/> col0</bblue>");
$cli->showLine("<bblue><col1/> col1</bblue>");
$cli->showLine("<bblue><col2/> col2</bblue>");
$cli->showLine("<bblue><col3/> col3</bblue>");
$cli->showLine("<bblue><col4/> col4</bblue>");
$cli->showLine("<bblue><col1/> col1 <col3/> col3 <col5/> col5</bblue>");
$cli->showLine("The parameters of option are: <option/>",$cli->getParameter('test'));
```

![](docs/examplecolor.jpg)

### Example tables

[example/exampletables.php](example/exampletables.php)

![docs/exampletable.jpg](docs/exampletable.jpg)

## Types of user input

| userinput    | description                                                             |
|--------------|-------------------------------------------------------------------------|
| number       | the value must be a number                                              |
| range        | the value must be a number between a range of values                    |
| string       | the value must be a string (by default, nulls are not string)           |
| password     | the value must be a string (and if it is displayed, then it shows ****) |
| multiple     | It allows to select one or many values displated in 1 column            |
| multiple2    | The same than multiple but displayed in 2 columns                       |
| multiple3    | The same than multiple but displayed in 3 columns                       |
| multiple4    | The same than multiple but displayed in 4 columns                       |
| option       | It allows to select one from many values displayed in a column          |
| option2      | The same than option but displayed in 2 columns                         |
| option3      | The same than option but displayed in 3 columns                         |
| option4      | The same than option but displayed in 4 columns                         |
| optionsimple | It allows to select one from many values. It doesn't use columns        |

## Types of colors

| tag                                        | description                   |
|--------------------------------------------|-------------------------------|
| <red>error</red>                           | color red                     |
| <yellow>warning</yellow>                   | color yellow                  |
| <blue>information</blue>                   | blue                          |
| <black>black</black>                       | black                         |
| <white>white</white>                       | white                         |
| <green>success</green>                     | color green                   |
| <italic>italic</italic>                    | italic                        |
| <bold>bold</body>                          | bold                          |
| <underline>underline</underline>           | underline                     |
| <cyan>cyan</cyan>                          | color light cyan              |
| <magenta>magenta</magenta>                 | color magenta                 |
| <col0/><col1/><col2/><col3/><col4/><col5/> | col0 leftmost column          |
| <option/>                                  | if the input has some options |
| <bred>red</bred>                           | background color red          |
| <byellow><bblue>..                         | background color              |

## Definitions

You can find the definition of the classes, methods and fields at:

[definitions.md](definitions.md)

## debug
To activate the debug mode, you must set the debug field as true:
```
$cli=new CliOne();
$cli->debug=true;
```
In debug mode, every user input is recored in the field $debugHistory

You can also see the history running the input ??history

![](docs/help1.jpg)

And you can clear the history using the input ??clear

The goal is we could store a session and replace it using testUserInput()

You can also load and save the user input
* **??history** it shows the history
* **??clear** it clears the history
* **??load** it load the user input and runs it.
* **??save** it saves the user input in a file called _save.json
* **??load:file** **??save:file** you can also specify the filename where it will be saved

```php
$cli = new CliOne();
CliOne::testUserInput([...]); // put your story here.
```

## Compatibility

* It must support all moderns interface that are compatibles with Virtual Terminal.
* Since Windows TH2 (v1511, 2015), cmd.exe and powershell.exe has supports or VT, but it must be enabled.
    * REG ADD HKCU\CONSOLE /f /v VirtualTerminalLevel /t REG_DWORD /d 1
* Since Windows 10 Anniversary Edition (v1607, 2016), cmd.exe and powershell.exe has default supports of VT (AFAIK)
* Windows 2019 (LTS, 2018) supports this library by default.
* Windows Terminal supports all features.
* The screen size width is -1 column less in older version of Windows. C'mon, Microsoft!

## Changelog
* 1.29.1 (23-04-06)
  * Fixed a bug with addMenuService()
* 1.29 (23-04-06)
  * In the debug mode, you can ??load, ??save the operations.
* 1.28 (2023-04-05)
  * the $debug field, so you can debug and store the user input history.
  * PHP_FAKE_READLINE constant or global variable now is a static field $fakeReadLine
* 1.27 (2023-04-02)
  * new method instance() so you can get or create a new singleton instance.
  * new method hasInstance()
  * new method hasMenu()
  * new method addMenuService()
  * fixed a bug with showHelp() and the help is an array or the help is missing.
* 1.26.1 (2023-03-21)
  * cleaned some code.
* 1.26 (2023-03-21)
  * addMenu() and addMenuItem() allow to use callable arguments.
* 1.25.1 (2023-03-20)
  * Fixed a small bug with evalMenu()
  * Added option to addMenu() ($size)
* 1.25 (2023-03-20)
  * Added method clearMenu(),addMenu(),addMenuItem(),addMenuItems(),evalMenu()
  * Added method setVariable(),getVariable() and addVariableCallBack().  $variable field is now private.
* 1.24 (2023-03-11)
  * Added new method createOrReplaceParam(),setParamUsingArray(),getValueAsArray()
  * setParam() has a new argument to create the parameter if it is not defined.
  * Added variables that could be displayed when the text contains "{{namevar}}"
* 1.23 (2023-03-05)
    * Added new methods readDataPHPFormat() and saveDataPHPFormat()
    * readDate() and saveData() generate a file that includes the version and the date of generation. It does not impact
      older files.
* 1.22.3 (2023-03-04)
    * fixed a small bug when some value is null. It could throw a warning in PHP
* 1.22.2 (2023-02-17)
    * some cleanups
* 1.22.1 (2022-7-30)
    * fix a small typo in the code.
* 1.22 (2022-07-30)
    * setInput() added format wide to use 1 column (if the screen is equal or less than 80 columns) or two columns
    * "option" ignore cases.
* 1.21 (2022-06-27)
    * showMessageBox() now support colors and line carriage.
* 1.20 (2022-06-21)
    * showMessageBox() added wrap lines
    * updated the way to find if an array is associative or not.
* 1.19 (2022-06-18)
    * Update the creation of table
* 1.18.1 (2022-06-17)
    * Fixed a bug when we use setCurrentAsDefault() but the type of value is an option (we set the default the valuekey
      instead of the value)
* 1.18 (2022-06-11)
    * Added the method addExtensionFile()
* 1.17 (2022-06-09)
    * fixed many problems with Linux (number of rows, autocomplete, etc.)
* 1.16 (2022-03-25)
    * setParam() allows to set the value or the value-key
* 1.15 (2022-03-15)
    * showHelp() shows more information.
    * colorText() now correct some missing tags.
* 1.14 (2022-03-04)
    * method showTable() allows to show or hide the top, sides and bottom borders.
* 1.13 (2022-02-28)
    * Changed silentError to errorType
* 1.12 (2022-02-26)
    * CliOne:
        * added a memory stream
        * set the default stream
        * set the current stream to use stdout,stderr or memory (stdin is not used for in)
        * added a new parameter type "command" that it is equals than first, but it ignores the name and considers the
          position.
        * added the method showHelp()
        * added the method makeBigWords()
        * added fontZnaki()
        * added fontaatr()
            * both fonts use a lot of space in code, but they are only an array of bits, so they use only 2KB.
        * new method alignLinesVertically()
        * new method maxWidth()
        * renamed field cmdMode to noANSI
        * method initialEndStyle()
    * CliOneParam:
        * Added a field related.
* 1.11 (2022-02-22)
    * Added supports for STDIN, STDOUT, and STDERR.
* 1.10 (2022-02-21)
    * **[new]** support for the old command line (cmd.exe). It is activated automatically.
        * It degraded the colors to b&w and changes the utf-8 characters to be compatible.
        * Also, the scroll bar and the waiting cursor is not displayed in this mode.
        * See compatibility for more information.

* 1.9 (2022-02-20)
    * **[new]** argumentIsValueKey and memory
    * **[changed]** **Changed the signature of createParam(), switched the second and third argument**
* 1.8 (2022-02-20)
    * **[new]** setParam() throw an exception if the parameter is not defined.
    * **[new]** showParamSyntax2()
    * **[new]** CliOneParam::$nameArg name of the argument (used in help)
* 1.7 (2022-02-18)
    * **[fix]** added type hinting for most fields and methods.
    * **[new]** new setValue() for CliOneParam.
* 1.6.1 (2022-02-18)
    * **[fix]** fixed a small bug with the value is set manually, so it is still marked as missing.
* 1.6 (2022-02-18)
    * **[new]** new method isParameterPresent()
* 1.5.5 (2022-02-18)
    * getParameter() always returns a parameter, no matter if it does not exist.
        * You can use the method isValid() to check its validity
    * setSilentError() you can silent the error output.
    * addhistory() renamed as setAddHistory()
    * To add a new parameter add() validates if the key is already in use, if the key is an alias of other, or if the
      alias is in use.
* 1.5.4 (2022-02-18)
    * fixed a problem with the default value.
    * added history (if available)
* 1.5.3 (2022-02-18)
    * nothing, just a renumeration
* 1.5.2 (2022-02-18)
    * **[fix]** some cleanups of the code.
* 1.5.1 (2022-02-18)
    * **[fix]** fixed a problem when the type is "none", it returned null instead of false.
    * **[new]** CliOneParam::evalParam() could return the value instead of the instance.
* 1.5 (2022-02-17)
    * **[fix]** corrected the display and trim of some text when the text uses a color.
    * **[new]** it allows multiples types of arguments (not only flags), including positional, flags, long-flags are
      none.
    * **[new]** added stack. Some visual elements allows to stack values.
* 1.4.1 (2022-02-15)
    * **[fix]** some fix for characters thare unicode. The system will use automatically MB_STRING if the library is
      available.
      Otherwise, it will use the default library
    * **[new]** new styles and patterns for components.
* 1.4 (2022-02-15)
    * **[replaced]** now all colors are express not abbreviated "<e>" => "<red>", etc.
    * **[new]** added all basic colors, background and solved a problem with the underline.
    * **[new]** added showFrame(),showTable(),showWaitCursor(),showProgressBar()
* 1.3 (2022-02-14)
    * **[new]** added autocomplete (tab key)
    * **[new]** added breadcrub
    * **[new]** added showValuesColumn()
    * **[replaced]** now keys (showing in options) are aligned at the center.
* 1.2.2 (2022-02-14)
    * **[fixed]** fixed a problem where the question is truncated with an ellipsis (...)
* 1.2.1 (2022-02-13)
    * **[fixed]** fixed some bugs
    * **[new]** keys are padded, example /[ 1] /[ 2] /[ 3] ... [99], /[value 1] /[value 2] /[value  ]
* 1.2 (2022-02-13)
    * **[replaced]** "options" renamed as "multiple". Added "multiple2","multiple3","multiple4"
    * **[new]** associative arrays are allowed.
    * **[new]** added templates.
    * **[new]** added valuekey.
* 1.1 (2022-02-12)
    * **[new]** new methods savedata(),getArrayParams(),setArrayParam(),readData()
    * **[replaced]** a new argument for the method replaceColor()
    * **[new]** a new type called password
* 1.0.1 (2022-02-11)
    * **[Fixed]** namespace.
    * **[Fixed]** replaceColor() fixed a color
    * **[Added]** CliOne::indVendorPath()
* 1.0 (2022-02-11)
    * End of beta, first release.
* 0.7 (2022-02-11)
    * Added option4.
    * optionshorts allows to specify the first letter, only if the first letter is unique, examples: yes/no allows to
      use y/n
* 0.6 (2022-02-11)
    * Added option2 and option3
    * allowNulls() now doesn't work with default values.
* 0.5 (2022-02-03)
    * [unittest] Better unit test.
    * [CliOneParam] You can set if you allow empty values or not.
    * [CliOne] You can set if you allow empty values or not.
* 0.4 (2022-01-27) Now test coverage is over the 75%
* 0.3 (2022-01-26) new corrections to the reading of values
* 0.2 some updates
* 0.1 first version

repository: EFTEC/CliOne

repo_name: EFTEC/CliOne


text:
# Security-Cam

Security-Cam is a simple security system that detects movement through a UVC compatible webcam, records the movement
with photos and video, which can then be sent to the registered Gmail address (limited to Gmail accounts at the moment).

This was created as a project for the Intel Edison chip, but it should
be compatible with all Linux systems that have Python and OpenCV
installed (python-opencv package). In the setup, I will cover how to set
it up on the Edison.

## Setup
If you haven't set up your Edison already, please follow this [guide](https://software.intel.com/en-us/iot/getting-started).

## Packages

For this portion, I'll use some of the same packages that drejkim's [edi-cam](https://github.com/drejkim/edi-cam) project uses,
so I'll post their package setup here (be sure to check out their project as well!).

## Configuring the package manager

Edison's operating system is based off Yocto Linux, which uses `opkg` as its package manager. [AlexT's unofficial opkg repository](http://alextgalileo.altervista.org/edison-package-repo-configuration-instructions.html) is highly recommended for adding packages to Edison. It includes many useful packages, such as git and the UVC driver.

To configure the repository, add the following lines to `/etc/opkg/base-feeds.conf`:

    src/gz all http://repo.opkg.net/edison/repo/all
    src/gz edison http://repo.opkg.net/edison/repo/edison
    src/gz core2-32 http://repo.opkg.net/edison/repo/core2-32

The configuration used in this demo is also provided for reference. If `/etc/opkg/base-feeds.conf` is empty, simply copy this file into `/etc/opkg/`.

Update `opkg`:

    opkg update

If the update is successful, the output should look like this:

    Downloading http://repo.opkg.net/edison/repo/all/Packages.gz.
    Inflating http://repo.opkg.net/edison/repo/all/Packages.gz.
    Updated list of available packages in /var/lib/opkg/all.
    Downloading http://repo.opkg.net/edison/repo/edison/Packages.gz.
    Inflating http://repo.opkg.net/edison/repo/edison/Packages.gz.
    Updated list of available packages in /var/lib/opkg/edison.
    Downloading http://repo.opkg.net/edison/repo/core2-32/Packages.gz.
    Inflating http://repo.opkg.net/edison/repo/core2-32/Packages.gz.
    Updated list of available packages in /var/lib/opkg/core2-32.

## Cloning this repository onto Edison

To install git:

    opkg install git

Then clone this repository using `git clone <git repo URL>`.

## Installing Python and OpenCV

This program uses Python and OpenCV so we'll need those packages to run (I'm also including other
python packages for a complete installation):

    opkg install python-pkgutil python-audio python-image python-email python-netserver python-xmlrpc python-distutils python-ctypes python-html python-json python-compile python-misc python-numbers python-unittest python-difflib opencv python-opencv

## Getting Started

To start with, you'll want to create a configuration file called 'security.conf' by running `./configure.sh`
In addition to just running the command by itself, you can issue other flags (you can find out more
details about them by running the -h or --help flag.

Once the 'security.conf' file is generated, you can run `./run_security.sh` to start the program.
It only runs once at the moment, so once movement is detected, it will save the pictures/video, send out any
messages (if configured to do so), and then wait for the user to press 'q' to quit.

If you want to remove pictures and/or video to free up space for more pictures/video, you will need to manually remove the "Group <Number>" folder inside the 'Pictures' and 'Video' folders.


text:
---
layout: essay
type: essay
title: Such Simple Standards
# All dates must be YYYY-MM-DD format!
date: 2020-02-13
labels:
  - Software Engineering
  - Javascript
  - Coding Standards
  - ESLint
---

# Transitioning
After the big move from JSFiddle to IntelliJ, I felt like I was doing something completely new despite using the same language.
Of course, it wasn't the first time I used an IDE nor coding in Javascript. It was a very unclear feeling like everything was all too familiar
and strange at the same time. After getting some practice in, I feel much more comfortable around using the program only to discover that
we were required to use a coding style inspection known as ESLint.

# Deja Vu
Prior to this class, I had only used a "coding standard" once and that was in my second semester in my first year of college. Before that, I
had never learned of any sort of inspection script that would detect improper syntax in my code. All of my real knowledge of a "standard"
came from classes that briefly went over how you should phrase your code in certain languages so that it looks better. I have to admit that
it was so much easier to just type things out and not have to deal with all sorts of "red flags" along the way. After taking ICS 211, which
introduced a similar coding standard expectation to Java in the Eclipse IDE, I was left wondering what the purpose really was to add extra guidelines
for something so trivial. Now, my opinion has completely changed.

# Current Thoughts
While it is inconvenient to have several errors in your code that are not directly related to how your code runs, I now feel that having
a coding standard is a blessing in disguise. In some way, if everyone used the same coding standard for a language, everyone would have
an easier time to look at their code or look at other people's code. It shouldn't be similar to looking at a foreign language when someone
doesn't follow the same style as you would implement. With that, it would create a uniform style that would be neat and organized in a way
that makes it easy to understand and read. Similarly, having a coding standard means making programmers really take the extra time to be meticulous
in their coding. The extra step of fixing their mistakes can build habits of rechecking their prior code to make sure that it not only
works properly but also is presentable in its form. It also isn't the case that a coding style inspection tool like ESLint is that much of
an inconvenience either. While it is a bit jarring to see so many red lines marking your code, it contains a tool that tells you what kind
of mistake you made, making sure you understand so that you can trivially avoid it the next time. ESLint also provides an option to automatically
fix your error for you with the click of a button. So even though many may see a "coding standard" as something trivial and irritating,
it really has some uses that could be beneficial to the larger scheme of things.


text:
### Install Sublime Text

Now you can install [Sublime Text](http://www.sublimetext.com/), a sophisticated text editor for code, markup and prose.

To get started, download [Sublime Text 2](http://c758482.r82.cf2.rackcdn.com/Sublime%20Text%202.0.2.dmg) and drag the app icon into your `/Applications` folder.

**TIP:** Remember to eject the disk image after installing the app.

Next, launch the app and navigate to the `Sublime Text 2 > Preferences > Settings - User` menu item.

Ensure the file contains the following preferences:

```
{
  "ensure_newline_at_eof_on_save": true,
  "rulers": [80],
  "tab_size": 2,
  "translate_tabs_to_spaces": true,
  "trim_trailing_white_space_on_save": true
}
```

**WARNING:** Punctuation errors with either curly-brackets, double-quotes, colons, square-brackets, or commas will be highlighted in red. If one of these symbols is missing, Sublime Text will highlight the next closest symbol. Analyze the above example preferences carefully. :eyes:

When you're done, save and close the file.

### subl

You'll find it insanely useful to open files and directories into Sublime Text from the Terminal.

To get started, run the following command:

```
ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl
```

To verify Sublime Text is wired up correctly, run the following command:

```
subl ~/.config/fish/config.fish
```

And Fish's startup file will open in Sublime Text.

### Edit config.fish

Many command line tools, like Git, use the `EDITOR` environment variable to open your preferred text editor.

While Fish's startup file is handy, add the following settings:

```
# Sublime Text
set -gx EDITOR 'subl -w'
```

Save the file and relaunch the Terminal. Verify these settings with the following command:

```
echo $EDITOR
```

And you'll see:

```
subl -w
```

### Change the PATH

Like most shells, Fish relies on the `PATH` environment variable to specify a set of directories where other commands can be found.

To see the contents of the PATH environment variable, run the following command:

```
echo $PATH
```

And you'll see:

```
/usr/bin /bin /usr/sbin /sbin /usr/local/bin
```

In upcoming sections, you'll use Homebrew to install additional commands. You'll want Fish to prefer these Homebrew-installed commands over the pre-installed commands that come with Mac OS X.

To change the `PATH` environment variable, opens the system file called `/etc/paths` in Sublime Text:

```
subl /etc/paths
```

Then, move `/usr/local/bin` to the **top of the file** like this:

```
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
```

Save the file and verify the change by running the following command:

```
echo $PATH
```

you'll see:

```
/usr/local/bin /usr/bin /bin /usr/sbin /sbin
```

Now, the `/usr/local/bin` directory is listed first. This means Fish (and any shell that leverages `/etc/paths`) will prefer Homebrew-installed commands over the pre-installed ones.

### [⇐ Previous](3_fish.md) | [Next ⇒](5_ruby.md)


text:
SpreeEditor
===========

Rich editor for Spree. It implements different types of Rich Editors:

- YUI Rich Editor
- WYM Editor
- TinyMCE

Copyright (c) 2010 [divineforest], released under the New BSD License

gha_language: JavaScript


text:
# Path Planning Project

**Writeup Report**

The following rubric points are addressed:

* The code model for generating paths is described in detail.

## Model Documentation

The model for generating trajectories can be mainly divided into the following components:

* State Machine ([State.h](src/state/State.h))
* Trajectory Generator ([TrajectoryGenerator.h](src/state/TrajectoryGenerator.h))

#### State Machine
The state machine is the core component of the trajectory generation model.
Similar to the lessons, the following states and their transitions are implemented:

![alt text](images/state-machine.jpg "State Machine")

* **Ready**: This state was omitted in the implementation.
* **Keep Lane**: This state keeps the current lane.
* **Prepare for Lane Change Left** (PLCL): This state keeps either the lane or turns into a lane change left (LCL).
* **Lane Change Left** (LCL): Performs a left lane change and immediately turns into Keep Lane state.
* **Prepare for Lane Change Right** (PLCL): This state keeps either the lane or turns into a lane change left (LCL).
* **Lane Change Right** (LCR): Performs a right lane change and immediately turns into Keep Lane state.

It turned out that each state needs to satisfy the following three conditions to implement the `State` interface:

* It returns its possible successor states:
```c++
virtual std::vector<std::unique_ptr<State>> Next_States(std::shared_ptr<Model> model_) = 0;
```
* It provides the costs for a possible transition to it
```c++
virtual double Cost() const = 0;
```

* It is able to add spline points depending on the current or the target lane
```c++
virtual void Add_Spline_Points(std::vector<double> &spline_points_x, std::vector<double> &spline_points_y) const;
```

Each instance of `State` has a method
```c++
Trajectory Next_Trajectory(const std::unique_ptr<Trajectory> &prev_traj) const;
```
implemented by the base class `State`. Most of the common trajectory generation code resides there. It internally uses
the polymorphic `void Add_Spline_Points(...)` function to account for the state specific behaviour. One of the most
challenging part was the velocity control of the vehicle. It is implemented in `Trajectory State::Break_Up_Spline_Points(...)`
in `State.cpp` in the first section of this function. It computes a maximum acceleration based on previous measurements
to reduce acceleration limit exceedance in the simulation. By doing so, a good but yet improvable acceleration
behaviour can be observed.

#### Trajectory Generator

The trajectory generator, implemented in [TrajectoryGenerator.cpp](src/TrajectoryGenerator.cpp),
uses the state machine and decides by a minimum cost approach for the next state transition.

First off all the internal state gets initialized in the constructor by a `KeepLane` instance.
```c++
TrajectoryGenerator::TrajectoryGenerator(std::shared_ptr<const MapWaypoints> map_waypoints) :
        map_waypoints_(map_waypoints)
{
    state_ = std::move(std::make_unique<KeepLane>(map_waypoints, nullptr, 1,
                                                  std::list<std::shared_ptr<Model>>()));
}
```
The public interface provides a method called
```c++
Trajectory TrajectoryGenerator::Next_Trajectory(std::unique_ptr<Trajectory> &&previous_traj,
                                                std::unique_ptr<Model> &&model)
```
The caller provides the previous trajectory from the simulation and the model.
```c++
struct Trajectory
{
    std::vector<double> path_x;
    std::vector<double> path_y;
};

struct Model {
    EgoState ego_state;
    Sensors sensors;
};
```
I refer to [Types.h](src/Types.h) and includes for other type definitions.

In this `TrajectoryGenerator::Next_Trajectory(...)` method all possible next successor states `state_->Next_States(...)`
get called for their costs `state->Cost()`:

```c++
{
    //...

    std::vector<std::pair<std::unique_ptr<State>, double>> states_and_costs;
    for (auto &state :  state_->Next_States(sh_model))
    {
        double cost = state->Cost();
        states_and_costs.emplace_back(std::move(state), cost);
    }

    //...
}
```

Then the internal `state_` gets updated by the minimum cost state:
*We "`move`" to a new state*.

```c++
{
    //...

    auto min_el = std::min_element(states_and_costs.begin(), states_and_costs.end(),
                     [](const std::pair<std::unique_ptr<State>, double>& s0,
                             const std::pair<std::unique_ptr<State>, double>& s1) {
                         return s0.second < s1.second;
                     });
    state_ = std::move(min_el->first);
    return state_->Next_Trajectory(previous_traj);
}
```

## Room for improvement

#### Velocity control

Even though historic data has been used to control the velocity the implemented method could be improved.
For example, many more data points should be taken into consideration to provide a smoother behaviour.
One could also consider more advanced techniques like Model Predictive Control or PID controller.

#### Jerk optimal trajectories

Like in the lessons introduced jerk optimal trajectories could be taken into considerations to avoid
unnecessary acceleration violations.

## Best recorded result

![alt text](images/success_3.jpg "9.70 Miles")

![alt text](images/success_4.jpg "12.53 Miles")


text:
---
layout: post
title:  "Kotlin Basics: Standard Extension Functions"
date:   2017-03-10 15:00:00
description: What's the difference between the kotlin extension functions in Standard.kt? When to use let, apply, run, takeUnless or also?
comments: false
categories:
- kotlin
permalink: kotlin-standard-extensions
---

Kotlin's most powerful feature (compared to Java) are probably Extension Functions.
They allow you to add new functionality to an existing class, without using inheritance or reflection.
You can define your own extension functions and Kotlin ships with a lot of pre-defined ones.
There are e.g. a lot extensions for collections, but also those that extend every class in your program. That's right - _every single class_ is extended by the functions in `Standard.kt`.
When I started with Kotlin, I found them quite confusing. With this post, I hope to un-confuse them a little bit.

Before we get to the details, some basics.

An Extension Function is a function that adds new functionality to an existing class. It's functionally equivalent to a static utility function in Java, but we can call it from the object itself.

In Java, you might have something like this:

```
class Util {
  public static final boolean isNumeric(String receiver) {
     return reveiver.matches("\\d+");
  }
}
...

String myString = ...;

if(Util.isNumeric(myString)) ...
```

By using an extension function, Kotlin allows us to call the `isNumeric` method directly on the receiving object:

```kotlin
fun String.isNumeric(): Boolean {
  return this.matches("\\d+".toRegex())
}
...

val myString = ...

if(myString.isNumeric()) ...
```

Pretty cool, right? You might agree that using extension functions increases the code's readability.

The example shows how an extension function is defined. We use the `fun` keyword, followed by the type we want to extend (in this case `String`). Then a `.` and the name of the function. That's it!
The extension function will always receive an implicit parameter `this`, which is the object we called the extension function on (in this case, `myString`).

Let's take a look at Kotlin's standard extension functions.

##### run

```kotlin
public inline fun <T, R> T.run(block: T.() -> R): R = block()
```

This looks a bit messy in the beginning. But it's actually quite simple.
`run` is a generic extension function on _any_ type `T`, that executes another extension function on this type (extension functions as parameters are symbolized as `T.()`) and returns the result of that function.

Consider this example:

```kotlin
val generator = PasswordGenerator()
generator.seed = "someString"
generator.hash = {s -> someHash(s)}
generator.hashRepititions = 1000

val password: Password = generator.generate()
```

Someone didn't quite think through the design of this password generator class. Its constructor does nothing, but it needs a lot of initialization.  To use this class, I need to introduce a variable `generator`, set all necessary parameters and use `generate` to generate the actual password. This is cool if I want to generate multiple passwords with the same generator, but if I throwaway the generator variable anyway, I can save some typing by using `run`:

```kotlin
val password: Password = PasswordGenerator().run {
       seed = "someString"
       hash = {s -> someHash(s)}
       hashRepetitions = 1000

       generate()
   }
```

Lambdas in Kotlin implicitly return the result of the last line. That's why I can omit the temporary variable and store the password directly. Because an extension function is passed to `run` I can also access the password generator's properties like `seed` or `hash` directly.
This way "the things that belong together" stay together.
It's one line more, I give you that. But it's still less code with less redundancy I had to write.

##### apply

```kotlin
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
```

This function looks almost like `run`, but there is a slight difference. `apply` will always return `this`, which is the receiver of the extension function.
That means that we can use `apply` for builder-style initialization, even if the designer of the class didn't implement it with a builder in mind.
If we stick to the password generator example:

```kotlin
val generator = PasswordGenerator().apply {
       seed = "someString"
       hash = {s -> someHash(s)}
       hashRepetitions = 1000
   }

val password = generator.generate()
```

This is particularly useful if you need an object with the same settings more than once.
It can also be used to avoid `init{}` blocks during the initialization of a class.
Instead of:

```kotlin
class Message(message: String, signature: String) {
  val body = MessageBody()

  init {
    body.text = message + "\n" + signature
  }
}
```

You can write:

```kotlin
class Message(message: String, signature: String) {
  val body = MessageBody().apply {
    text = message + "\n" + signature
  }
}
```

##### let

```kotlin
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
```

`let` is particularly useful to use it instead of a `null` check:

```kotlin
val fruitBasket = ...

val result = apple?.let {
  fruitBasket.add(it)
}
```

The apple (`it`) will only be added to the basket if it's not `null`.
Notice that `let` will return the result of the last line in the lambda (which is the result of `add`).
Just like `run`, `let` also helps to keep the scope of your variables small. Instead of `this` you have to use `it` or a custom variable name to reference it:

```kotlin
val fruitBasket = ...

appleTree.pick()?.let {
  fruitBasket.add(it)
}
```

##### also

```kotlin
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
```

Kotlin 1.1 introduced this new extension function called `also`. It fills the gap between `let` and `apply`.
Just like `apply`, it will always return its receiver. But instead of an extension function it takes a normal function as an argument.

```kotlin
class FruitBasket {
    private var weight = 0

    fun addFrom(appleTree: AppleTree) {
        val apple = appleTree.pick().also { apple ->
            this.weight += apple.weight
            add(apple)
        }
        ...
    }
    ...
    fun add(fruit: Fruit) = ...
}
```

I renamed the implicit `it` to an explicit `apple` this time.  Assuming the function `appleTree.pick()` returns an apple, the weight of the whole basket increases.
Notice that both the apple and the basket have a `weight` property.  If I had used `apply`, it would not be possible[*](#footnote1) to access the basket's `weight`. Since `apply` takes an extension function, `this` would refer to the apple and not the basket.  With `also` this is possible.

##### takeIf and takeUnless

```kotlin
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
```

The last two functions I want to mention have also been added to Kotlin with 1.1.

`takeIf` does exactly that - it takes the receiver if it satisfies a condition.
`takeUnless` inverts the condition and takes `this` only if the condition is not satisfied.

For example:

```kotlin
val redApple = apple.takeIf { it.color == RED }
val otherApple = apple.takeUnless { it.color == RED }
```

Those two methods are the functional equivalent to the `filter` function to collections, but they operate on a single variable.

##### Summary

All extension functions can be used to avoid temporary variables/Re-scope a variable (or the result of a function).  Many of the extension functions in `Standard.kt` can be used interchangeable. Pick the ones that match your style and that offer the best readability in your context.
The table below shows a common usage for each of the presented functions.

Function  | Argument  |  Returns | Usage examples
--|---|---|
`run`  | `this` | any result | make an object a builder for another object
`apply`  | `this` | `this` | make an object its own builder
`let`  | `it` | any result | null checks
`also`  | `it` | `this` | You need `apply` but don't want to shadow `this`
`takeIf`  |`it` | `it` or `null`  | shorthand for `if(predicate(it)) it else null`
`takeUnless`  | `it` | `it` or `null` | shorthand for `if(!predicate(it)) it else null`

---

* You still can by using `this@FruitBasket`, but do you want to do this?


text:
# environexus

This is a library used to integrate an Environexus controller (complete with wireless nodes on a network)
with Home Assistant. Or integrate with whatever you want

`pip install environexus`

`from nexus import LightHub`
`hub = LightHub('<IP_ADDRESS>:3480')`

repository: tombasche/environexus

repo_name: tombasche/environexus


text:
# Macros

Macros are used to calculate parameters from a measurement. To work with Macros you can select **Macros** from the left side bar, you can select **View → Macros** from the top menu bar or you can use the shortcut `Ctrl+4 / ⌘4`.

![The Macro List](images/macro-list.png)

**My Macros** shows a list of Macros you have created. **Explore** will provide a list of all Macros currently available on the Platform. Click on the list headers to sort the list of Macros by name, creator and date.

A **single click** on a Macro from the list will bring up details about the Macro in the right side bar. Here you can also see the discussion around the macro as well as add new comments. A **double click** will directly open the Macro in the Macro Editor.

Select the search field in the top right corner `Ctrl+F / ⌘F` to enter a search query followed by the enter key to search the list of Macros. Use the `×` button inside the input field or the `ESC` key to reset the search.

## Create a new Macro

You can create a new Macro by opening the Macro editor selecting **File → New Macro** from the main menu. The Macro template will be automatically added to your Code Editor and you are ask to pick a measurement from your Notebook to use as your measurement template. You can select that measurement at any time selecting **Measurement** from the **Menu Bar**, but it is easier to start with a measurement provided.

## Editing an existing Macro

You can edit a Macro simply by selecting a macro from the list of macros and open the editor by double clicking it or you can use the edit button in the right side bar to open the Macro Editor.

When you are the creator of the Macro you can either overwrite the existing Macro or you can save it as a new Macro. In case you are not the creator, you can only save the macro as a new one.

repository: underhillanna/PhotosynQ-Documentation

repo_name: underhillanna/PhotosynQ-Documentation


text:
# WeatherApp
A web application that allows to keep an eye on the weather.

**WeatherApp** uses Flask-SQLAlchemy to connect a database to the web application and work with a weather service API to get the current weather from all over the world.

The following operations were performed:
* [x] Use a Weather API to get the current weather data from all over the world.
* [x] Add a Flask SQLAlchemy library to store your data in a database.
* [x] Handle wrong city names. Output user-friendly flash messages to users if they did something wrong.

## Technologies used

- python - version 3.8
- flask - version 1.1.4

## Project demonstration

Here's a walkthrough of some implemented features:

Initial Layout

Handling the addition of the city that is already shown

Handing the addition of a non-existing city

## License

    Copyright [2021] [Vladyslav Petrenko]

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

repository: Vladpetr/WeatherApp

repo_name: Vladpetr/WeatherApp


text:
# Float-Based-CSS-and-SASS-Grid

How to make float-based grid using CSS and SASS

## Technologies

* Sass
* HTML
* Gulp.js
* NPM
* Node.js

## Installation

1. Download project on yor computer.
2. Install node.js and npm.
3. Open terminal in main project folder.
4. Write in the terminal
```
npm install
```
5. If you want track all Sass files "on fly" use in terminal command as below. You will get main.css file in "css" folder. That file needs to be linked in index.html
```
gulp watch
```
* if you want only compile Sass use command as below.
```
gulp sass
```

## Licence

MIT License

repository: daankh/Float-Based-CSS-and-SASS-Grid

gha_language: CSS

repo_name: daankh/Float-Based-CSS-and-SASS-Grid


text:
# Ghostunnel + Federation Suite

## Description

Exercises [Ghostunnel](https://github.com/square/ghostunnel) SPIFFE Workload
API by wiring up two workloads that achieve connectivity using Ghostunnel
backed with identities and trust information retrieved from the SPIFFE Workload
API.

The two workloads are in separate trust domains and are federated using the
SPIRE bundle endpoints. This enables each Ghostunnel proxy to authenticate
identities issued by the other trust domain.

A custom container image is used that runs Ghostunnel, SPIRE agent, and socat
(acting as the workload).

The SPIRE server and agent in each trust domain are brought down during different
portions of the test to ensure that as long as the SVID is valid, ghostunnel
connectivity is not disrupted by a little downtime.

repository: spiffe/spire

gha_language: Go

repo_name: spiffe/spire


text:
# Colliders, Triggers and RigidBodies

## Learning Objectives

- By the end of this session you should:
  - Know the function of colliders, triggers and ridgidbodies
  - Know the difference between colliders and triggers
  - Understand when to use a collider and when to use a trigger
  - Be able to do a basic implementation of them in Unity.

This project has two simple scenes which you can use to explore the basic functions of rigibodies, colliders and triggers.

https://github.com/tommakesgames/GS_Demo

## Colliders and Rigidbodies

  - Open up Scene1 (a cube and a sphere positioned over a tilted plane)
  - Play the scene.

  ###### 1. What happens?
  A. Cube falls, sphere doesn't.

  ###### 2. What component does the Cube have, which the Sphere lacks?
  A.

  - Add this component to the sphere.
  - Play the scene.
    - *Both objects should now fall and hit the sloped floor.*

  - Disable the 'Mesh Collider' on the Plane.

  ###### 3. How does this change the object interaction?
  A.

  - Re-enable the 'Mesh Collider' on the Plane.
  - Disable the 'Sphere Collider' on the Sphere.

  ###### 4. How does this change things?
  A.

  ###### 5. What do you need for a physics collision to occur?
  A.

  ###### 6. What is the role of the collider, and what is the role of the rigidbody?
  A.

  ### Extension

  - Play with the values of the rigidbody component
    - How does 'Mass', 'Drag' and 'Angular Drag' affect the objects? (this will be easier to see on the Cube).
  - What happens when you toggle the 'Constraints' values (this menu is folded by default near the bottom - unfold it)?
  - What are the 'Interpolate' options for? (hint: Use the in-built help shortcut to find out).

## Colliders and Triggers

  - Open up Scene2 (a floor, a wall and a ballLauncher are in the scene).
  - Play the scene, and click with the left-mouse button, press space or press A/X on a controller.
  - Note the debug messages in the console.

  ###### 7. What happens at the moment?
  A.

  - Select the wall. In the 'Box Collider' component, make sure 'Is Trigger' is ticked/true.
  - Now play the scene.

  ###### 8. What has changed?
  A.

  - Open up 'ballCollision.cs' in the 'Scripts' folder. (This script is attached to the 'ball' prefab in our example)
  - In 'ballCollision.cs', in the `OnCollisionEnter` function, uncomment the line `Destroy(collision.gameObject);`.
  - Make sure 'Is Trigger' for the Box Collider of the wall is now **UN**ticked/false.
  - Play the scene.

  ###### 9. How does the ball react to the wall, even though it's destroyed?
  A.

  - In 'ballCollision.cs', in the `OnCollisionEnter` function, _COMMENT OUT AGAIN_ the line `Destroy(collision.gameObject);`.
  - In 'ballCollision.cs' in the `OnTriggerEnter` function, uncomment the line `Destroy(other.gameObject);`.
  - Select the wall. In the 'Box Collider' component, make sure 'Is Trigger' is **ticked/true**.
  - Play the scene.

  ###### 10. How does the ball react to the wall (trigger) being destroyed? How is it different from when the wall was a collider?
  A.

  ###### 11. Can you explain the difference between a trigger and a collider?
  A.

### Extension

Other ways to investigate and experiment with colliders and triggers:

- Click on the button next to 'Edit Collider'...
	- You can directly edit the collider by dragging faces (for a Box) and length and radius (for a sphere/capsule). When do you think this would be useful in a game?
- 	Create a Physics Material (right click in 'Project' > Create > Physics Material), drag and drop it onto the 'Material' field in the collider. Play with the values of the Physics Material - it's fairly self-explanatory! See how the ball interacts with the wall.
- Look at the 'ballMovement.cs' script (this is attached the to ball prefab in the Project).
  - Focus on the line `rb.AddForce(forceSpeed * transform.forward, ForceMode.Impulse);`
  - Investigate the possible values for `ForceMode`, and see how changing it from `Impulse` affects the ball's behaviour. There are four possible values/force modes.

## Summary

  ###### When would you use a collider?

A.

  ###### When would you use a trigger?
  A.

  ###### When do you need a rigidbody?
  A.

  ###### What do you need to implement a collider (including scripting)?
  A.

  ###### What do you need to include a trigger in your game (including scripting)?
  A.