text:
# Learning From Demonstration Experiments

This is the top package to test virtual springs and DMPs. It uses all other packages and contains ad-hoc programs. It contains the experiment procedure described in the paper:

* G. Solak and L. Jamone. Learning by demonstration and robust control of dexterous in-hand robotic manipulation skills. In IEEE/RSJ International Conference on Intelligent Robots and Systems. IEEE, 2019.

[![Youtube video](youtube-preview.png)](http://www.youtube.com/watch?v=BsC-uR-y08Q)

**Warning:** *This package is not intended for general use. It contains ad-hoc code for experiments presented in the above paper. It may serve as example code, but running it directly on a different robot setup may be unsafe.*

## Install
*Tested on Ubuntu 16.04, ROS-Kinetic and Ubuntu 18.04, ROS-Melodic*

- [Install ROS](http://wiki.ros.org/kinetic/Installation) & [create a catkin workspace](http://wiki.ros.org/catkin/Tutorials/create_a_workspace)
- Install [universal-robot](https://github.com/ros-industrial/universal_robot) package (replace *melodic-devel* with your distro):
  ```
  git clone https://github.com/ros-industrial/universal_robot.git -b melodic-devel
  ```
- Install [*allegro-hand-ros (experimental branch)*](https://github.com/gokhansolak/allegro-hand-ros/tree/experimental), [*dmp_tools*](https://github.com/ARQ-CRISP/ros_dmp_tools) and [*optoforce_publisher*](https://github.com/ARQ-CRISP/optoforce_publisher) according to their READMEs.
- Clone [*kdl_control_tools*](https://github.com/ARQ-CRISP/kdl_control_tools), [*spring_framework*](https://github.com/ARQ-CRISP/spring_framework), [*arq_ur5*](https://github.com/ARQ-CRISP/arq_ur5), [*allegro_hand_kdl*](https://github.com/ARQ-CRISP/allegro_hand_kdl), [*topic_connector*](https://github.com/ARQ-CRISP/ros_topic_connector), [*ur5_allegro_moveit*](https://github.com/ARQ-CRISP/ur5_allegro_moveit) into `your-catkin-workspace/src` directory:
  ```
  git clone git@github.com:ARQ-CRISP/kdl_control_tools.git
  git clone git@github.com:ARQ-CRISP/spring_framework.git
  git clone git@github.com:ARQ-CRISP/arq_ur5.git
  git clone git@github.com:ARQ-CRISP/allegro_hand_kdl.git
  git clone git@github.com:ARQ-CRISP/ros_topic_connector.git
  git clone git@github.com:ARQ-CRISP/ur5_allegro_moveit.git
  ```
- Install ROS dependencies using [rosdep](http://wiki.ros.org/rosdep):
  - ```rosdep update```
  - ```rosdep install --from-paths src --ignore-src -r -y```
- Build the workspace with `catkin_make`.

## Usage

### Learning DMPs

Learning from demonstration can be used to learn either _joint-space_ or _object-space_ trajectories. Use `record.launch` to record a trajectory first:

```bash
roslaunch lfd_experiments record.launch state_type:=object state_size:=9 time:=12 trajectory_name:=traj.txt
```

Parameters of *record*:
* *state_type:* joint, object or fingertip.
* *state_size:* Number of DMPs (dimensions). Joint count or 9 for object frame.
* *time:* Recording time in seconds.
* *trajectory_name:* Name of the trajectory file to be saved.

This node will save a *traj.txt* file in the *~/.ros* directory. You can use this trajectory to train DMPs:

```bash
roslaunch dmp_tools train.launch dmp_name:=dmp.xml trajectory_name:=traj.txt
```

Trained DMP will appear in the *~/.ros* directory (unless path specified).
In order to reproduce it using the *grasp_node*, the DMP should be copied into *data/grasp/dmp* and an entry should be added to *data/grasp/manipulate.yaml*.

Please see the [ros_dmp_tools](https://github.com/ARQ-CRISP/ros_dmp_tools) readme for optional parameters of `train.launch`.

#### Experiments in the paper:
The demonstrations are recorded while the object is in grasp, gravity compensation and virtual springs are active.
A grasp can be obtained using the `grasp.launch` and following the prompted instructions (see below).
The user shall stop before applying an existing DMP, start the `record.launch`, and give a demonstration.

### Reproducing a learned DMP

The experiment assumes that an object is standing in a predefined pose. A UR5 robot arm and a Allegro robot hand (mounted) are used to grasp, pick-up, manipulate and release the object. The experiment program is contained in ```grasp_node.cpp``` file.

The robot arm is moved to position the hand over the object. Then the hand takes a pregrasp shape and approaches the object following a Cartesian path.
Once near the object, a pre-learned DMP is executed to close fingers around the object.
At this point, the user is involved to make sure that the grasp is proper, because this experiment does not use any grasp planners.
When the fingers are on the object, virtual springs are activated to apply grasping forces on the object. The object is then lifted and a learned DMP is executed.

The program prompts the user at each phase to choose the type of grasp and the DMP to execute.

The arm is controlled using MoveIt! framework (packages _arq\_ur5_, _ur5\_allegro\_moveit_). Allegro hand is controlled using KDL library (_allegro\_hand\_kdl_). Fingers are closed using DMP framework and grasping forces are applied using the virtual spring framework (_ros\_dmp\_tools_, _spring\_framework_). You can load the RViz configuration file *data/config/lfd_experiments.rviz* to view the related markers.

#### Run in real-world:

The robot should be connected and the drivers should be running ([more info](https://github.com/ARQ-CRISP/arq_ur5)). Run each line in separate terminals:

```bash
roslaunch ur5_allegro_moveit ur5_allegro_bringup.launch robot_ip:=<IP_ADDRESS> optoforce:=true
roslaunch arq_ur5 moveit_rviz.launch allegro:=true
roslaunch arq_ur5 load_scene.launch scene:=qmul_realistic_world
roslaunch lfd_experiments grasp.launch
```

`grasp.launch` will start the grasp demo program.
The user should input the grasp name at the beginning of the program.
This should be the name of an existing entry in `/data/grasp/dmp\_grasps.xml` file.
The program will prompt the user before executing possibly dangerous moves. The user should check the proposed move in RViz before confirming.

`optoforce` argument is optional to load the robot with the optoforce fingertips. Default is _true_.

#### Run in simulation:

Simulation doesn't include physics. It is just RViz and fake controllers.

```bash
roslaunch allegro_hand_kdl allegro_torque.launch sim:=true RVIZ:=false
roslaunch ur5_allegro_moveit demo.launch optoforce:=true
roslaunch arq_ur5 load_scene.launch scene:=bimanual_computers
roslaunch lfd_experiments grasp.launch sim:=true
```


text:
Hosting .NET OWIN applications in node.js
====

Owin allows you to host .NET code in a node.js application. It helps with:
* implementing express.js handlers and connect middleware for node.js application using .NET 4.5,
* implementing CPU-bound computations in .NET and running them in-process with node.js application without blocking the event loop,
* using C# and .NET instead of writing native node.js extensions in C/C++ and Win32 to access Windows specific functionality from a node.js application.

Owin is a native node.js module for Windows. It hosts [OWIN](http://owin.org/) handlers written in .NET 4.5 (think C#) in a node.js application. Owin allows integration of .NET code into express.js applications by providing a connect wrapper around OWIN .NET handlers. Owin also provides an easy way to run CPU bound computations implemented in .NET without blocking the node.js event loop.

Read more about the background and motivations of the project [here](http://tomasz.janczuk.org/2013/02/hosting-net-code-in-nodejs-applications.html).

## What you need

* Windows x64
* node.js 0.8.x x64 (developed and tested with [v0.8.19](http://nodejs.org/dist/v0.8.19/))
* [.NET 4.5](http://www.microsoft.com/en-us/download/details.aspx?id=30653)

## How to: express.js request handler in .NET

First get the owin module and express.js:

```
npm install owin
npm install express
```

Implement your Startup.cs [OWIN](http://owin.org/) handler in C# as follows:

```c#
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace OwinHelloWorld
{
    public class Startup
    {
        public Task Invoke(IDictionary<string, object> env)
        {
            env["owin.ResponseStatusCode"] = 200;
            ((IDictionary<string, string[]>)env["owin.ResponseHeaders"]).Add(
                "Content-Type", new string[] { "text/html" });
            StreamWriter w = new StreamWriter((Stream)env["owin.ResponseBody"]);
            w.Write("Hello, from C#. Time on server is " + DateTime.Now.ToString());
            w.Flush();

            return Task.FromResult<object>(null);
        }
    }
}
```

Compile it to OwinHelloWorld.dll with:

```
csc /target:library /out:OwinHelloWorld.dll Startup.cs
```

Then in your server.js, create an express.js application and register two handlers. One is implemented in JavaScript, and the other uses the Owin module to load the .NET handler in OwinHelloWorld.dll:

```javascript
var owin = require('./lib/owin.js')
	, express = require('express');

var app = express();
app.use(express.bodyParser());
app.all('/jazz', owin('OwinHelloWorld.dll'))
app.all('/rocknroll', function (req, res) {
	res.send(200, 'Hello from JavaScript! Time on server ' + new Date());
});

app.listen(3000);
```

Now start your server:

```
node server.js
```

(Make sure OwinHelloWorld.dll is in the current directory, or specify the full file path to it in the call to the `owin()` function in your server.js)

Now open the web browser and navigate to `http://localhost:3000/jazz`. Welcome to .NET!

![jazz](https://f.cloud.github.com/assets/822369/190582/79ad0574-7efc-11e2-9d61-227ab70c37b4.PNG)

Now navigate to `http://localhost:3000/rocknroll`. Hello JavaScript!

![rocknroll](https://f.cloud.github.com/assets/822369/190583/8151f190-7efc-11e2-92ab-dcbfffd96f35.PNG)

## How to: CPU-bound in-process worker

This is how you can execute CPU-bound code written in .NET within the node.js process without blocking the node.js event loop. Read more about the scenario and goals [here](http://tomasz.janczuk.org/2013/02/cpu-bound-workers-for-nodejs.html).

First install the owin module with:

```
npm install owin
```

Then implement your CPU bound code in .NET and save it to Startup.cs:

```c#
namespace CalculateBudget
{
    public class Startup : Owinjs.Worker
    {
        protected override IDictionary<string, string> Execute(IDictionary<string, string> input)
        {
            int revenue = int.Parse(input["revenue"]);
            int cost = int.Parse(input["cost"]);
            int income = revenue - cost;

            Thread.Sleep(5000); // pretend it takes a long time

            return new Dictionary<string, string> { { "income", income.ToString() } };
        }
    }
}
```

The `Execute` method can conatin any long-running, CPU-blocking code. You can accept a dictionary of strings as input and return another dictionary of strings as the result of the computation.

Now compile the .NET into a `CalculateBudget.dll` (the name of the assembly should by convention match the namespace name and reference the `Owinjs.dll` included with the owin module:

```
copy node_modules\owin\lib\clr\Owinjs.dll
csc /target:library /r:Owinjs.dll /out:CalculateBudget.dll Startup.cs
```

Lastly implement your node.js application that imports the owin module and calls into the blocking .NET code from `CalculateBudget.dll`:

```javascript
var owin = require('owin')

console.log('Starting long running operation...');
owin.worker(
    'CalculateBudget.dll',
    { revenue: 100, cost: 80 },
    function (error, result) {
        if (error) throw error;
        console.log('Result of long running operation: ', result);
    }
);

setInterval(function () {
    console.log('Node.js event loop is alive!')
}, 1000);
```

Save the file as `test.js` and run it with `node test.js`. You will see output similar to this one:

```
C:\projects\owin_test>node test.js
Starting long running operation...
Node.js event loop is alive!
Node.js event loop is alive!
Node.js event loop is alive!
Node.js event loop is alive!
Node.js event loop is alive!
Result of long running operation:  { income: '20' }
Node.js event loop is alive!
Node.js event loop is alive!
```

This proves that the node.js event loop is not blocked while the CPU-bound computation runs on a CLR thread separate from the main event loop thread in node.js.

## How to: debugging

You can debug the .NET code running as part of your node.js application by attaching a managed code debugger(e.g. Visual Studio) to node.exe. Since the node.exe process runs both native and managed code, make sure to select the appropriate language to target:

![debug](https://f.cloud.github.com/assets/822369/190564/a41bab2c-7efb-11e2-878f-82ae2325876c.PNG)

## How to: exceptions

Exceptions thrown within the .NET code are propagated to the calling node.js application and re-thrown there by the owin module. For example:

```
C:\projects\owin_test>node test.js
Starting long running operation...

C:\projects\owin_test\test_worker.js:8
                if (error) throw error;
                                 ^
System.AggregateException: One or more errors occurred. ---> System.Exception: Sample exception
   at CalculateBudget.Startup.Execute(IDictionary`2 input)
   at Owinjs.Worker.<>c__DisplayClass1.<Invoke>b__0()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.Exception: Sample exception
   at CalculateBudget.Startup.Execute(IDictionary`2 input)
   at Owinjs.Worker.<>c__DisplayClass1.<Invoke>b__0()
   at System.Threading.Tasks.Task.Execute()<---
```

In case of express request handlers written in .NET, express framework will return them back to the browser client. For example:

![exception](https://f.cloud.github.com/assets/822369/190735/51f14504-7f0b-11e2-8ea1-04f81fa406ff.PNG)

## More

Issues? Feedback? You [know what to do](https://github.com/tjanczuk/owin/issues/new).
Pull requests welcome.

repository: andrijac/owin

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: andrijac/owin


text:
---
title: "In Javascript, what excutes first: Class Properties or the Constructor?"
date: 2020-11-29T09:40:43.627Z
description: A short blog post where I document my approach to finding a
  solution to a question I had.
tags:
  - oop
  - javascript
  - til
---
# What executes first? The Properties or the Constructor?

In most languages its the Properties first, but with how javascript doesn't conform to normal OOP and instead uses a prototypal inheritance model I wanted to double check.

As per usual, when I test things out in js I'm either using the browser console or Quokka the Vscode extension.

I wrote this small script out which uses a generator (something I don't use much).
```js
  function* when(){
    let i = 0;
    while(true){
      yield i;
      i++;
    }
  }
  const w = when()
  const next = () => w.next().value

  class Test{
    prop = next()
    constructor(){
      this.constr = next()
    }
  }
  const t = new Test()
  console.log(t)
```
The output proves that like most other languages the props get evaluated first and the constructor second.
```
Object { prop: 0, constr: 1 }
```


text:
### Dashboards for Apache Airflow Scheduler

#### Notes

- This dashboard is based on metrics [collected using the statsd_exporter](https://www.redhat.com/en/blog/monitoring-apache-airflow-using-prometheus).

|Apache Airflow Scheduler|
|:------------------|
|Filename: [apache-airflow-prometheus.json](apache-airflow-prometheus.json)|
|This dashboard has charts displaying `Tasks: Running, Starving, Executable`, `Heartbeat`, `Orphaned Tasks Cleared`, `Orphaned Tasks Adopted` and `Critical Section Duration` |

gha_language: Python


text:
---
layout: app

permalink: /mybelka/
description: A desktop client for the MyBelka program

screenshots:
  - mybelka/screenshot.png

authors:
  - name: Leinnan
    url: https://github.com/Leinnan

links:
  - type: GitHub
    url: Leinnan/mybelka
  - type: Install
    url: https://github.com/Leinnan/mybelka/releases

desktop:
  Desktop Entry:
    Comment: A desktop client for the MyBelka program
    Exec: mybelka
    GenericName: MyBelka
    Icon: mybelka
    Name: MyBelka
    NoDisplay: false
    StartupNotify: true
    Terminal: false
    Type: Application
    Categories: Qt
  AppImageHub:
    X-AppImage-UpdateInformation: gh-releases-zsync|Leinnan|mybelka|continuous|MyBelka*-x86_64.AppImage.zsync
    X-AppImage-Signature: no valid OpenPGP data found. the signature could not be verified.
      Please remember that the signature file (.sig or .asc) should be the first file
      given on the command line.
    X-AppImage-Type: 2
    X-AppImage-Architecture: x86_64
---

license: MIT


text:
![](https://raw.githubusercontent.com/Janne252/scar/master/images/promo_logo.png)
# SCAR - Language support for [Relic](http://www.relic.com/)'s SCAR Scripting Language
(Company of Heroes 2)

## Build & Install
 - Build: `vsce package`
 - Install: `code --install-extension scar-0.0.1.vsix`

## Features
 - [x] Lua syntax check (based on [oxyc/luaparse](https://github.com/oxyc/luaparse))
 - [x] Autocompletion
    - [x] SCARDOC functions
    - [x] SCARDOC enums
    - [x] LuaConstsAuto.scar blueprints
    - [x] Current document words
    - [x] Lua standard library functions
    - [x] Workspace user-defined function
         - [x] Workspace user-defined function documentation parsing (based on [LDoc](https://github.com/stevedonovan/LDoc) format)
 - [x] Intellisense (function parameter autocompletion)
    - [x] SCARDOC functions
    - [x] Lua standard library functions
    - [x] Workspace user-defined functions
 - [x] Dynamic syntax highlighting
    - [x] SCARDOC functions
    - [x] SCARDOC enums
    - [x] LuaConstsAuto.scar blueprints
    - [x] Lua standard library functions
    - [x] Workspace user-defined functions
 - [x] Misc
    - [x] Reload workspace user-defined functions
    - [x] Find LuaConstsAuto.scar blueprint

## Syntax Highlighting
![](https://raw.githubusercontent.com/Janne252/scar/master/images/promo_highlight.png)

## Autocompletion
![](https://raw.githubusercontent.com/Janne252/scar/master/images/promo_autocompletion.png)

## Intellisense
![](https://raw.githubusercontent.com/Janne252/scar/master/images/promo_intellisense.png)

## User-defined documentation parsing
![](https://raw.githubusercontent.com/Janne252/scar/master/images/promo_workspacedoc.png)

repository: williamhammond/vscode-scar

gha_language: TypeScript

gha_license_id: MIT

repo_name: williamhammond/vscode-scar


text:
---
id: LibraryInterface
title: Library Interface
---

This library exposes a single function `embed` that renders a notebook into a given DOM node and returns an interface for further interaction with the notebook:

```js
WolframNotebookEmbedder.embed(source, domNode, attributes)
```

* `source`:
    * a string with a cloud object URL of the notebook to embed, e.g. `'https://www.wolframcloud.com/obj/4beadfbb-84dd-4b26-87b6-bcd30b9abd65'` or `'https://www.wolframcloud.com/obj/myusername/myfolder/mynotebook.nb'`, *or*
    * an object with the following properties:
        * `cloudBase` (optional): a string denoting the [cloud base](https://reference.wolfram.com/language/ref/$CloudBase.html) to use (defaulting to `https://www.wolframcloud.com`)
        * `expr` (a string containing a `Notebook[...]` expression in [InputForm](https://reference.wolfram.com/language/ref/InputForm.html)) *or* `url` (a URL to fetch a notebook file from) *or* `path` (the path of a cloud object in the specified `cloudBase`)
* `domNode`: a DOM node in which to render the notebook, e.g. obtained by `document.getElementById('myContainer')`
* `attributes`: a JavaScript object with attributes

A `source` string such as `'https://www.wolframcloud.com/obj/myusername/myfolder/mynotebook.nb'` is equivalent to an object such as
```json
{"cloudBase": "https://www.wolframcloud.com", "path": "myusername/myfolder/mynotebook.nb"}
```
where the `cloudBase` and the `path` are determined based on the given string.

The following attributes can be given:

* `width`: width of the notebook in pixels; a value of `null` (the default) makes the notebook adapt to the width of the container node
* `maxHeight`: maximum height of the notebook in pixels; a value of `Infinity` (the default) allows the notebook to grow infinitely; a value of `null` makes the notebook adapt to the height of the container node
* `showBorder`: whether to show a border around the notebook; the default `null` will take into account a corresponding option of the embedded cloud object
* `allowInteract`: whether to enable interactivity in the notebook, which might use the server-side Wolfram Engine for computations; even if this is set to `true` (the default), the `Permissions` of the cloud notebook must also include `All -> {"Read", "Interact"}` for interactions to actually work
* `showRenderProgress`: whether to show the render progress indicator at the top of the notebook during the initial loading phase (see [Notebook Loading Phases](./NotebookLoadingPhases.md) for more information); the default is `true`
* `useShadowDOM` (experimental): whether to use a shadow DOM container for the notebook; the default is `false` (but might change in a future release after 0.2.x)

If the notebook exceeds the given width or height, scrollbars are introduced in that dimension. The default dimensions (`width: null`, `maxHeight: Infinity`) let the notebook adapt to the container node's width (line-wrapping as necessary) and make the container node grow vertically as necessary, so there will not be a vertical scrollbar, and there will only be a horizontal scrollbar if the notebook's contents are inherently wider than the available width (e.g. a graphic with a fixed size). In the case of `maxHeight: null`, the notebook's background will fill out the whole container node even if the notebook content is smaller.

The embedded notebook needs to be public (i.e. with [Permissions](https://reference.wolfram.com/language/ref/Permissions.html) of at least `All->"Read"`). For interactivity to work, the `"Interact"` permission is needed.

Notebooks on [Wolfram Enterprise Private Cloud (EPC)](https://www.wolfram.com/enterprise-private-cloud/) can be embedded as well, as long as they are public. Just use the cloud object URL pointing to your EPC as the `notebookURL`.

The function `embed` returns a `Promise` resolving to an object with various methods to control the notebook, e.g.:

* `setAttributes(options)`: changes embedding attributes (except for `allowInteract` and `useShadowDOM`, which cannot be changed dynamically)
* `detach()`: call this function when the embedded notebook is no longer needed, e.g. because the node it is embedded in disappears
* `addEventListener(eventName, callback)`: registers an event listener
* `removeEventListener(eventName, callback)`: unregisters an event listener
* many other notebook-related functions, e.g. `getDimensions()`, `getCells()`, `evaluateExpression(expr)`

See the [notebook API documentation](./NotebookAPI.md) for more details about these methods.

If something goes wrong while loading the notebook (e.g. because there is no notebook at the given `notebookURL`), the returned promise is rejected.

gha_language: JavaScript


text:
![](http://www.aurelienribon.com/blog/wp-content/uploads/2012/05/tween-engine-big-logo.jpg)

## Check out the demo!

  * [Android application](https://play.google.com/store/apps/details?id=aurelienribon.tweenengine.demo)
  * [Desktop application](http://code.google.com/p/java-universal-tween-engine/downloads/detail?name=tween-engine-demo-6.3.0.zip)
  * [WebGL html5 page](http://www.aurelienribon.com/universal-tween-engine/gwt/demo.html) (requires a WebGL enabled browser)

## Introduction

The Universal Tween Engine enables the interpolation of every attribute from any object in any Java project (being Swing, SWT, OpenGL or even Console-based). Implement the TweenAccessor interface, register it to the engine, and animate anything you want!

In one line, send your objects to another position (here x=20 and y=30), with a smooth elastic transition, during 1 second).

```java
// Arguments are (1) the target, (2) the type of interpolation,
// and (3) the duration in seconds. Additional methods specify
// the target values, and the easing function.

Tween.to(mySprite, Type.POSITION_XY, 1.0f).target(20, 30).ease(Elastic.INOUT);

// Possibilities are:

Tween.to(...); // interpolates from the current values to the targets
Tween.from(...); // interpolates from the given values to the current ones
Tween.set(...); // apply the target values without animation (useful with a delay)
Tween.call(...); // calls a method (useful with a delay)

// Current options are:

myTween.delay(0.5f);
myTween.repeat(2, 0.5f);
myTween.repeatYoyo(2, 0.5f);
myTween.pause();
myTween.resume();
myTween.setCallback(callback);
myTween.setCallbackTriggers(flags);
myTween.setUserData(obj);

// You can of course chain everything:

Tween.to(...).delay(1.0f).repeat(2, 0.5f).start(myManager);

// Moreover, slow-motion, fast-motion and reverse play is easy,
// you just need to change the speed of the update:

myManager.update(delta * speed);
```

Create some powerful animation sequences!

```java
Timeline.createSequence()
    // First, set all objects to their initial positions
    .push(Tween.set(...))
    .push(Tween.set(...))
    .push(Tween.set(...))

    // Wait 1s
    .pushPause(1.0f)

    // Move the objects around, one after the other
    .push(Tween.to(...))
    .push(Tween.to(...))
    .push(Tween.to(...))

    // Then, move the objects around at the same time
    .beginParallel()
        .push(Tween.to(...))
        .push(Tween.to(...))
        .push(Tween.to(...))
    .end()

    // And repeat the whole sequence 2 times
    // with a 0.5s pause between each iteration
    .repeatYoyo(2, 0.5f)

    // Let's go!
    .start(myManager);
```

You can also quickly create timers:

```java
Tween.call(myCallback).delay(3000).start(myManager);
```

Main features are:

  * Supports every interpolation function defined by [Robert Penner](http://www.robertpenner.com/easing/).
  * Can be used with any object. You just have to implement the TweenAccessor interface when you want interpolation capacities.
  * Every attribute can be interpolated. The only requirement is that what you want to interpolate can be represented as a float number.
  * One line is sufficient to create and start a simple interpolation.
  * Delays can be specified, to trigger the interpolation only after some time.
  * Many callbacks can be specified (when tweens complete, start, end, etc.).
  * Tweens and Timelines are pooled by default. If enabled, there won't be any object allocation during runtime! You can safely use it in Android game development without fearing the garbage collector.
  * Tweens can be sequenced when used in Timelines.
  * Tweens can act on more than one value at a time, so a single tween can change the whole position (X and Y) of a sprite for instance !
  * Tweens and Timelines can be repeated, with a yoyo style option.
  * Simple timers can be built with Tween.call().
  * **Source code extensively documented!**

## Get started and documentation index

Detailed documentation with code snippets and examples is available for the following topics:
  * Get started --- A step-by-step example to get you started, with code

  * The TweenAccessor interface --- Know how to implement it
  * Tweens and options --- See what are the possibilities
  * Timelines and options --- Learn how to build powerful sequences
  * Animating Android apps --- See how to use the engine with Android UIs

## Where can I ask for help?

There is a dedicated forum for you:
http://www.aurelienribon.com/forum/viewforum.php?f=5

Also, the following link will guide you to a discussion thread that started it all:
http://www.badlogicgames.com/forum/viewtopic.php?f=17&t=494

repository: lz-purple/Source

repo_name: lz-purple/Source


text:
Template Actions
Caddy's template features make it possible to add some dynamic content to your static website and include pages to help reduce duplication. Templates are supported by a few different directives such as templates, browse, and markdown.

Template actions only work on directives that support them. Check the documentation for your directive to see if and how they can be used.
Caddy templates use the syntax defined in Go's text/template package. Understanding text/template will help you take full advantage of templates, but for those of us who aren't programmers, here are some simplified instructions. Caddy also adds some extra helpful functions for templating web pages specifically, which we've documented here.

Basic Syntax
Template actions are enclosed between {{ and }} markers. Template words are case-sensitive.

Common Functions
Include another file:
{{.Include "path/to/file.html"}}  // no arguments
{{.Include "path/to/file.html" "arg1" 2 "value 3"}}  // with arguments
Get argument within included file:
{{index .Args 0}} // 0 is first argument, and so on
Include and render a Markdown file: (not needed in markdown middleware)
{{.Markdown "path/to/file.md"}}
Show current timestamp: (format)
{{.Now "Monday, 2 Jan 2006"}}
Cookie value:
{{.Cookie "name"}}
Header field value:
{{.Header "name"}}
Visitor's IP:
{{.IP}}
Server's IP:
{{.ServerIP}}
Visitor's hostname (requires DNS lookup, probably slow):
{{.Hostname}}
Request URI:
{{.URI}}
Host portion of request:
{{.Host}}
Port portion of request:
{{.Port}}
Request method:
{{.Method}}
Whether request path matches another path:
{{.PathMatches "/some/path"}}
A part of the URL:
{{.URL.RawQuery}}
RawQuery returns the query string. You can replace RawQuery with Host, Scheme, Fragment, String, or Query.Get "parameter".

Environment variables:
{{.Env.ENV_VAR_NAME}}
Truncate value to certain length: (from beginning, or from end)
{{.Truncate "value" 3}}  // "val"
{{.Truncate "value" -3}} // "lue"
String replacement:
{{.Replace "haystack" "needle" "replacement"}}
Current date/time object: (useful in date-related functions)
{{.NowDate}}
Get extension from file path:
{{.Ext "path/filename.ext"}}
Strip extension from file path:
{{.StripExt "filename.ext"}}
Strip HTML, leaving only the plain text:
{{.StripHTML "Shows only text content"}}
Lower-case a string:
{{.ToLower "Makes Me ONLY lowercase"}}
Upper-case a string:
{{.ToUpper "Makes me only UPPERCASE"}}
Split a string by separator:
{{.Split "123-456-7890" "-"}}
Convert list of values to a slice (array):
{{.Slice "a" "b" "c"}}
Map keys to values: (useful in advanced cases, with subtemplates, etc.)
{{.Map "key1" "value1" "key2" "value2"}}
List files in a directory:
{{.Files "sub/directory"}}
{{.Context.Files "sub/directory"}} // prefix with .Context in markdown templates
Whether HTTPS interception is likely:
{{.IsMITM}}
Random string of random length between min and max length:
{{.RandomString 100 10000}}
Built-in Sanitization Functions
These functions are built into text/template but you may find them helpful.

Make HTML-safe (escape special characters):
{{html "Makes it safe to render as HTML"}}
Make JavaScript-safe:
{{js "Makes content safe for use in JS"}}
URL-escape (query-encode):
{{urlquery "Makes safe for URL query strings"}}
Control Statements
If:
{{if .PathMatches "/secret/sauce"}}
	Only for secret sauce pages
{{end}}
If-else:
{{if .PathMatches "/secret/sauce"}}
	Only for secret sauce pages
{{else}}
	No secret sauce for you
{{end}}
If-elseif-else:
{{if .PathMatches "/secret/sauce"}}
	Only for secret sauce pages
{{else if eq .URL "/banana.html"}}
	You're on the banana page
{{else}}
	No bananas or secret sauce
{{end}}
Range: (iterate data; this example dumps request headers)
{{range $field, $val := .Req.Header}}
    {{$field}}: {{$val}}
{{end}}
Server-side comments:
{{/* This isn't sent to the client */}}
Comparison Functions
Useful in "if" statements, you can use comparison functions:

eq Equal
ne Not equal
lt Less than
le Less than or equal
gt Greater than
ge Greater than or equal
Or these logic functions:

not Reverses the if condition
or Returns first non-empty argument or the last argument
and Returns first empty argument or the last argument
Further Reading
These are just a few examples of what you can do. If you need even more template power, read the description of the text/template package which goes into much more detail.

repository: oJacker/caddydoc

repo_name: oJacker/caddydoc


text:
# `◁` - Reverse Item

- Arity: 1
- In: a
- Out: reversed(a)

Returns the reverse of `a`. If `a` is an integer, the sign is kept.

# Usage
```
321◁      ║⟨123⟩
321N◁     ║⟨-123⟩
`racecar`◁║⟨`racecar`⟩
```

repository: hyper-neutrino/Vyxal

repo_name: hyper-neutrino/Vyxal


text:
# env-overlay

Easily see what environment you are viewing your application in via a small overlay.

Lightweight (3.3K - 1.3K gzipped), easy to use and easy to customize.

- Comes with built-in visual, but can easily be customized via options.
- Calculates visuals for other environment names than the built-in - if none are provided via options

**Examples of defaults**

![Local Environment](/images/local.png) ![Development Environment](/images/development.png) ![Staging Environment](/images/staging.png) ![Demo Environment](/images/demo.png)

**Calculated result for "other"**

![Other Environment](/images/other.png)

## Installation

```bash
$ npm install env-overlay --save
```

## Usage

```js
import { envOverlay } from 'env-overlay'

// Here assuming the environment variable NODE_ENV is set for sure
// And that it is accessible via process.env
envOverlay(process.env.NODE_ENV)
```

## Signature

> (environment: string, options?: IEnvOverlayOptions) => void

[Click here to view IEnvOverlayOptions](#IEnvOverlayOptions)

## Options

### options.disallow - _String or array of strings_

Name(s) of environments to exclude usage of env-overlay.
The module will bailout early if the the environment name given matches the string, or one of the strings, given.

**Default**: "production"

### options.background - _Object { key (env name): value (any valid CSS color) }_

A map of background colors for given environment names.
There are default colors for the environments _"local"_, _"development"_, _"staging"_ and _"demo"_.

Should an environment not have a matching background color key/value provided in options, then a color will be assigned based on the environment name.

[All credit goes to Edd Turtle for this feature](https://www.designedbyaturtle.co.uk/2014/convert-string-to-hexidecimal-colour-with-javascript-vanilla/)

### options.text - _Object { key (env name): value (any valid CSS color) }_

A map of text colors for given environment names.
There are default colors for the environments _"local"_, _"development"_, _"staging"_ and _"demo"_.

### options.onLoaded - _Function_

Has the wrapper DOM node of the overlay as its argument for your DOM manipulatory pleasure.

## IEnvOverlayOptions interface

The typescript interface for the options (IEnvOverlayOptions) looks like this

```ts
export interface IEnvOverlayOptions {
  corner?: 'left' | 'right'
  disallow?: string | string[]
  background?: { [key: string]: string }
  text?: { [key: string]: string }
  onLoaded?: (node: HTMLDivElement) => void
}
```

repository: IgorSzyporyn/env-overlay

repo_name: IgorSzyporyn/env-overlay


text:
# Stipa pennata var. neomexicana VARIETY

#### Status
SYNONYM

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

#### Published in
J. Coulter, Man. bot. Rocky Mt. 408. 1885

#### Original name
null

### Remarks
null

repository: mdoering/backbone

path: /life/Plantae/Magnoliophyta/Liliopsida/Poales/Poaceae/Stipa/Stipa neomexicana/ Syn. Stipa pennata neomexicana/README.md

repo_name: mdoering/backbone


text:
# `Egg.js`

![Egg.js](https://mikeflynn.github.io/egg.js/eggjs.png)

Egg.js is a simple JS library that has no prerequisites and allows you to easily add web easter eggs by watching the user's key strokes.

### Example

It's really easy to use. Just include the egg.js file on the page...

```html
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/egg.js/1.0/egg.min.js"></script>
```

(Thanks to Cloudflare for hosting the library!)

...then use the `addCode()` function to add in your easter eggs. You need to pass it the character sequence to trigger the easter egg callback (which can either be in plain English or Javascript key codes), a function to trigger when it happens, and an optional set of metadata. Metadata can be anything from a string to an object.

```js
var egg = new Egg();
egg
  .addCode("up,up,down,down,left,right,left,right,b,a", function() {
    jQuery('#egggif').fadeIn(500, function() {
      window.setTimeout(function() { jQuery('#egggif').hide(); }, 5000);
    }, "konami-code");
  })
  .addHook(function(){
    console.log("Hook called for: " + this.activeEgg.keys);
    console.log(this.activeEgg.metadata);
  })
  .listen();
```

You can also define the easter egg using the constructor:

```js
var egg = new Egg("up,up,down,down,left,right,left,right,b,a", function() {
  jQuery('#egggif').fadeIn(500, function() {
    window.setTimeout(function() { jQuery('#egggif').hide(); }, 5000);
  }, "konami-code");
}).listen();
```

You can also add a hook, as shown above using `addHook()`, that will run after any egg code is triggered. You could use it to fire a Google Analytics event or send out a tweet that someone finally found your easter egg. Hooks get access to the whole Egg.js object so you can pull information about the easter egg that fired via `this.activeEgg`

You can see a live example of this on `egg.js` [website](http://thatmikeflynn.com/egg.js/).

### Why?

I put an easter egg in pretty much everything I make and after copying the same basic code over and over again I figured I should make it in to a simple library for my own use.

### Credits

Created by Mike Flynn / [@thatmikeflynn](http://twitter.com/thatmikeflynn) and Rob McVey / [@negative_sleep](http://twitter.com/negative_sleep)


text:
# About

Clickhouse writer service for Rockstat

## About Rockstat

Is an open source platform for a web and product analytics.
It consists of a set of components: JavaScript tracking client for web applications;
server-side data collector; services for geo-coding and detecting client device type;
a new server deployment system.
[Read more](https://rockstat.ru/about)

![Rockstat sheme](https://rockstat.ru/media/rockstat_v3_arch.png?3)

## Envs and defaults

## License

[LICENSE](LICENSE)

repository: rockstat/chwriter

repo_name: rockstat/chwriter


text:
# login.dfe.validation
[![Build Status](https://travis-ci.org/DFE-Digital/login.dfe.validation.svg?branch=master)](https://travis-ci.org/DFE-Digital/login.dfe.validation)
[![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest)

Validation library for DfE Login

# Password policy
Used to validate if a give password meets the password policy

```javascript
const passwordPolicy = require('login.dfe.validation').passwordPolicy;

const passwordMeetsPolicy = passwordPolicy.doesPasswordMeetPolicy('some-password');
```


text:
---
layout: article
title: "Daily Learning Notes for January 28, 2016"
cats: daily
permalink: /2016/01/28/
---

I was so happy I got my first assembly program to work before I went to sleep [yesterday]({% post_url 2016-01-27-notes %})! And today I finished the [fourth NAND2Tetris project](http://nand2tetris.org/04.php)!

{% include toc.html %}

## Input/output handling program specs

The second program I need to write for this week's project will display or clear pixels on the screen based on keyboard input. Here's an outline of my objective:

- The program should run an infinite loop that listens for keyboard input.

- When any key is pressed, the screen should make a pixel black and repeat this until every pixel on the screen is black.

- When no key is pressed, the screen clears the screen and turns the pixels white, repeating this until the whole screen is white.

- There is test script but no compare file; I should confirm the program works by watching the simulated screen in the CPU emulator.

- I can choose to change the pixels on the screen in any order I want, as long as eventually the screen turns all black if keys are pressed for long enough or all white if no keys are pressed for long enough.

OK, that's pretty straightforward. At least I understand my objective! That's always a good start. But I don't know how to turn pixels on or off and I don't know how to check for keyboard input! They just glossed over that at the end of [chapter 4](http://nand2tetris.org/chapters/chapter%2004.pdf) (PDF).

## How to turn pixels on and off

Digging back through the book again, I see that the Hack computer uses a *memory map* to associate devices with segments of the memory. To draw pixels on the screen, all I have to do is write a binary value (1 for black, 0 for white) to the right RAM addresses.

**Important screen specs:**

- The screen has 256 rows, with 512 pixels per row. So its display resolution is 512 x 256 -- 512 columns, 256 rows.

- The screen is linked to an 8K memory map, starting at RAM address 16384 (0x4000).

- "Each row in the physical screen, starting at the screen’s top left corner, is represented in the RAM by 32 consecutive 16-bit words."

- The symbol `SCREEN` is an I/O pointer to RAM address 16384 (0x4000), representing the top left pixel on the screen. So I can access that first pixel with `@SCREEN` and make it black by writing 1 to it with the command `M=1`. Cool!

- The formula for accessing a pixel at row *r* and column *c* is `RAM[16384 + (r * 32) + c/16]`. (I don't understand why yet, but I'll look at it more closely later.)

I tried running the example code to draw one black pixel on the screen, and sure enough, it worked! It's so tiny, I almost didn't see it in the CPU emulator, but it certainly worked! So that part was easy enough. I think the most challenging part of this project will be implementing that formula. Argh, math! I always get stuck on the math!

## How to handle keyboard input

I searched through the book for any mention of the keyboard, and I gathered a few very helpful details. In a way, working with the keyboard seems like it will be even more simple than working with the screen.

**Important keyboard specs:**

- The Hack computer uses a single-word memory map for the keyboard -- just 16 bits!

- The symbol `KBD` is an I/O pointer to RAM address 24576 (0x6000).

- When a key is pressed, its 16-bit ASCII code is stored in RAM[24576].

- If no key is pressed, that location contains the value 0.

I realized that I can test the keyboard in the CPU emulator without writing any code! All I had to do was scroll down to the very last RAM location and press a key on my keyboard. A number showed up! The letter A has the ASCII code 65 and Z is 90. Cool stuff! I wonder what the story is behind ASCII codes: how long ago was it invented, how did it become the standard, who came up with it, what were its competitors?

But anyway, back to business. I have my conditional statement now: if RAM[24576] is zero, clear the screen. Otherwise, make the pixels black one at a time in a pattern that would eventually cover the whole screen. But I don't know how to do that part!

## Experimenting with pixels and assembly

Just for fun (and to check my understanding), I wrote a little program that just turns the same pixel on or off depending on whether there's  keyboard input:

{% highlight html %}
// Set the loop's start location with a label
(LOOP)
// set the A register to point to the keyboard's memory map
@KBD
// load the keyboard value into D register
D=M
// Point to next jump location to clear the screen
@CLEAR
// If no key is pressed, jump to CLEAR
D;JEQ
// ELSE: set the A register to point to the first pixel
@SCREEN
// load 1 to turn on the top left pixel
M=1
// Skip over the CLEAR section
@END
// Unconditional jump
0;JMP
// Label to jump to if clearing the screen
(CLEAR)
@SCREEN
M=0
// Label for skipping the CLEAR section
(END)
// Jump back to the start: infinite loop!
@LOOP
// Unconditional jump
0;JMP
{% endhighlight %}

Woohoo, it works! That one pixels shows up if I press a button on my keyboard while the program is running, and it disappears when I let go. This is a good start!

But here's what I'm stuck on now: how do I increment the value of an address and then save that value to access the new address later?

Oh, my brain hurts again! I need to review what I actually understand in order to pinpoint exactly where it is that I'm getting confused:

- I know I can use `@100` followed by `0;JMP` to run whatever instruction is stored the instruction memory at address 100.

- I know I can also do `@100` followed by commands like `D=M+1` to perform operations on the *value* stored in the data memory at address 100.

- I know that if I did `@100` followed by `D=A+1` then the D register would hold the value 101, whereas `@100` followed by `D=M+1` would give me one plus the value *stored* in data memory location 100, not the number 100 itself. That's an important difference.

But how do I take a *variable* address, add one to it, and then access that new location? I need more caffeine or something, because I feel like I'm missing something *very* simple but I just can't see it!

Time for a break. I need to go to a working lunch meeting soon, anyway. That should help reset my brain, I hope.

**Three hours later:** Lunch, a good brainstorming session, a new freelance project, and a 30-minute walk -- what a perfect way to break up my day! All I need is a little caffeine and I'll be good to go.

OK, so I watched through some of the video lecture, and then I realized what I was missing: I can save results to the A register, too! So I can do `@SCREEN` to get the base address for the screen, then `A=A+1` to iterate it, and then `M=1` to set the next pixel to black! At least I think that should work. Let's test that out...

Woohoo! It works! Not exactly as I hoped, though. It creates a row of pixels evenly spaced a certain width apart, not a continuous line. I left the program running for a long time and ended up with 32 vertical lines on the screen.

That number means something... 32 is 2 to the power of 5. My screen is 512 pixels wide. And 512 divided by 32 is 16. And 16 is the magic number! That's how many bits each of my registers can hold. I've been setting every register to hold the value for 1, so that would explain why my pixels are 16 bits apart!

**Aha moment:** Every bit represents a pixel, so every register represents 16 pixels! So if I want to make the entire screen black, I need to store `1111111111111111` in each register instead of `0000000000000001`.

Let's test that out...

Yay, success! My screen is slowly turning completely black. It runs awfully slowly, but I love the fact that I can watch every register store the new value one at a time as the CPU emulator runs each line of assembly code.

I'm not sure if I'm supposed to turn the screen black *one pixel* at a time, or if it's OK if I turn the screen black 16 pixels at a time. I'm happy with it as it is, though. If I wanted to do it one pixel at a time, I would just have to change my program to add one to each register's existing value instead of setting every bit to 1.

OK, I'm going to finish implementing the final program. I won't write about it in detail so as not to give away the answer. Everything else I need to know to complete it is already written up in this blog post or it's spelled out in the book.

**A couple hours later:** Woohoo! It's working! I had to make a few adjustments to account for the limits of the screen's memory map and get my loops working properly, but one by one I fixed each bug and in the end, the process was actually very straightforward!

So that's it for week 4! Woohoo!

## Questions

- What is a pointer?
  - **Answer:** A pointer is a variable that stores a memory address! Woohoo, this finally makes sense to me now!
- How long ago was 512 x 256 a common display resolution for computer screens?
- What's the story behind the invention and adoption of ASCII code?

## Learning summary (#TIL)

- I learned how to use input and output devices with the Hack computer.
- I wrote another working program in assembly language, completing the fourth NAND2Tetris project!

## Next steps

- Decide if I want to jump right into week 5 or take a break for a while. (After all, I want to start a NAND2Tetris study group and I'm toying with the idea of creating a series of videos about what I've learned so far.)

## Time breakdown

- Study time: 5 hours 10 min
  - Second assembly program: 3 hours 12 min
  - Watching video lectures: 1 hour 58 min


text:
# WebBrowser

A small Swift library for opening URLs in the web browser from command line.

This was built for desktop Swift scripts and is compatible with Linux and
macOS.
I have not tested it on Linux yet.

## Installation
Add this to your Package.swift:
```swift
.package(url: "https://github.com/oliveroneill/WebBrowser.git", .upToNextMajor(from: "1.0.0")),
```

## Usage
```swift
import WebBrowser

do {
    try WebBrowser.open(url: URL(string: "http://google.com/")!)
} catch {
    // handle error
}
```

repository: oliveroneill/WebBrowser

repo_name: oliveroneill/WebBrowser


text:
# ember-cli-text-support-mixins

[![npm version](http://badge.fury.io/js/ember-cli-text-support-mixins.svg)](http://badge.fury.io/js/ember-cli-text-support-mixins) ![downloads](https://img.shields.io/npm/dy/ember-cli-text-support-mixins.svg) [![Code Climate](http://codeclimate.com/github/cybertoothca/ember-cli-text-support-mixins/badges/gpa.svg)](http://codeclimate.com/github/cybertoothca/ember-cli-text-support-mixins)

[![ember-observer-badge](http://emberobserver.com/badges/ember-cli-text-support-mixins.svg)](http://emberobserver.com/addons/ember-cli-text-support-mixins) [![License](http://img.shields.io/npm/l/ember-cli-text-support-mixins.svg)](LICENSE.md)

Ember.TextSupport enhancements including a `{{input-text}}` and `{{text-area}}` component.

## Compatibility

- Ember.js v3.12 or above
- Ember CLI v2.13 or above
- Node.js v10 or above

## Installation

The following command will install this add-on:

```bash
ember install ember-cli-text-support-mixins
```

### Demo & Documentation

The demonstration web application can be found here:
[https://ember-cli-text-support-mixins.cybertooth.io/](https://ember-cli-text-support-mixins.cybertooth.io/).
[Short description of the addon.]

### Dependencies

#### `ember-cli-element-closest-polyfill`

Polyfill terrible M$ browsers with the `Element.closest()` & `Element.matches()` using
[`ember-cli-element-closest-polyfill`](https://github.com/miguelcobain/ember-cli-element-closest-polyfill).

#### `keyevent`

The constants from [`keyevent`](https://github.com/cybertoothca/keyevent) are installed
by yarn and `ember-cli-node-assets`.

## Contributing

See the [Contributing](CONTRIBUTING.md) guide for details.

## License

This project is licensed under the [MIT License](LICENSE.md).

branch_name: refs/heads/main


text:
# GMan

*GMan links all GSuite accounts with the matching user-list storage in form of a YAML.*

**Features:**

- declare your users, groups and org units in code (infrastructure as code) via config YAML, which will then be
  applied to your GSuite organization
- export the current state as a starter config file
- preview any action taken

**Table of contents:**
<!-- TOC -->
- [GMan](#gman)
  - [Installation](#installation)
  - [Configuration & Authentication](#configuration--authentication)
    - [Basics: Admin & Directory API](#basics-admin--directory-api)
    - [Service account](#service-account)
    - [Impersonated Email](#impersonated-email)
    - [Config YAML](#config-yaml)
  - [Usage](#usage)
    - [Exporting](#exporting)
    - [Validating](#validating)
    - [Synchronizing](#synchronizing)
    - [Confirming synchronization](#confirming-synchronization)
    - [Static Password](#static-passwords)
  - [Limitations](#limitations)
    - [Sending the login info email to the new users](#sending-the-login-info-email-to-the-new-users)
    - [API requests quota](#api-requests-quota)
  - [Changelog](#changelog)
<!-- /TOC -->

## Installation

The official releases can be found [on GitHub](https://github.com/kubermatic-labs/gman/releases).

## Configuration & Authentication

### Basics: Admin & Directory API

The **Directory API** is intended for management of devices, groups, group members, organizational units and users.

To be able to use it, please make sure that you have access to an admin account in the Admin Console and you have
set up your API. For more detailed information, see
[the official Google documentation](https://developers.google.com/admin-sdk/directory/v1/guides/prerequisites).

Moreover, to access the extended settings of the groups, the **Groups Settings API** must be enabled (see
[the official documentation](https://developers.google.com/admin-sdk/groups-settings/prerequisites#prereqs-enableapis)).
To manage user licenses the **Enterprise License Manager API** has to be activated too (see
[the official documentation](https://developers.google.com/admin-sdk/licensing/v1/how-tos/prerequisites#api-setup-steps)).

### Service account

To authorize and to perform the operations on behalf of *GMan* a Service Account is required.
After creating one, it needs to be registered as an API client and have enabled these OAuth scopes:

* `https://www.googleapis.com/auth/admin.directory.user`
* `https://www.googleapis.com/auth/admin.directory.user.readonly`
* `https://www.googleapis.com/auth/admin.directory.orgunit`
* `https://www.googleapis.com/auth/admin.directory.orgunit.readonly`
* `https://www.googleapis.com/auth/admin.directory.group`
* `https://www.googleapis.com/auth/admin.directory.group.readonly`
* `https://www.googleapis.com/auth/admin.directory.group.member`
* `https://www.googleapis.com/auth/admin.directory.group.member.readonly`
* `https://www.googleapis.com/auth/admin.directory.resource.calendar`
* `https://www.googleapis.com/auth/admin.directory.resource.calendar.readonly`
* `https://www.googleapis.com/auth/admin.directory.userschema`
* `https://www.googleapis.com/auth/apps.groups.settings`
* `https://www.googleapis.com/auth/apps.licensing`

The scopes can be added in Admin console under *Security -> API Controls -> Domain-wide Delegation*.

Furthermore please generate a Key (save the *.json* config) for this Service Account. For more detailed
information, follow [the official instructions](https://developers.google.com/admin-sdk/directory/v1/guides/delegation#create_the_service_account_and_credentials).

The Service Account private key must be provided to *GMan* using the `-private-key` flag.

### Impersonated Email

Only users with access to the Admin APIs can access the Admin SDK Directory API, therefore the service
account needs to impersonate one of the admin users.

In order to delegate domain-wide authority to your service account follow this
[official guide](https://developers.google.com/admin-sdk/directory/v1/guides/delegation#delegate_domain-wide_authority_to_your_service_account).

The impersonated email must be specified in *GMan* using the `-impersonated-email` flag.

### Config YAML

All configuration happens in YAML file(s). See the [configuration documentation](/Configuration.md) for
more information, available parameters and values.

The configuration can happen all in a single file, or be split into distinct files for users, groups and
org units. In all cases, the three flag `-users-config`, `-groups-config` and `-orgunits-config` must be
specified, though they can point to the same file. All three resources are always synchronized, it is
not possible to _just_ sync users.

## Usage

After the completion of the steps above, *GMan* can perform for you:

1. [exporting](#exporting) existing users in the domain;
2. [validating](#validating) the config file;
3. [synchronizing](#synchronizing) the state of your GSuite organization

### Exporting

To get started, *GMan* can export your existing GSuite users into a configuration file. For this to work,
prepare a fresh configuration file and put your organization name in it. You can skip everything else:

```yaml
organization: myorganization
```

Now run *GMan* with the `-export` flag:

```bash
$ gman \
    -private-key MYKEY.json \
    -impersonated-email<EMAIL_ADDRESS>\
    -users-config myconfig.yaml \
    -groups-config myconfig.yaml \
    -orgunits-config myconfig.yaml \
    -export
2020/06/25 18:54:56 ⇄ Exporting organizational units…
2020/06/25 18:54:57 ⇄ Exporting users…
2020/06/25 18:54:57 ⇄ Exporting groups…
2020/06/25 18:54:58 ✓ Export successful.
```

Afterwards, the `myconfig.yaml` will contain an exact representation of your organizational unit, users and groups:

```yaml
organization: myorganization
orgUnits:
  - name: Developers
    description: dedicated org unit for devs
    parentOrgUnitPath: /
users:
  - givenName: Josef
    familyName: K
    primaryEmail<EMAIL_ADDRESS>    orgUnitPath: /Developers
  - givenName: Gregor
    familyName: Samsa
    primaryEmail<EMAIL_ADDRESS>    orgUnitPath: /
groups:
  - name: Team GMan
    email<EMAIL_ADDRESS>    members:
      - email<EMAIL_ADDRESS>        role: OWNER
```

### Validating

It's possible to validate a configuration file for:

- user config:
  - duplicated users (based on primary email),
  - primary and secondary emails being different,
  - if specified emails obey semantical correctness,
- organizational unit config:
  - duplicated org units,
  - correct parent org unit path,
  - correct org unit path,
- groups config:
  - duplicated groups (based on group email),
  - if specified group email obeys semantical correctness,
  - valid group members roles,
  - valid group members emails.

In order to validate the file, run *GMan* with the `-validate` flag. In this case, the private
key and impersonated email can be omitted.

```bash
$ gman \
    -users-config myconfig.yaml \
    -groups-config myconfig.yaml \
    -orgunits-config myconfig.yaml \
    -validate
2020/06/17 19:24:49 ✓ Configuration is valid.
```

If the config is valid, the program exits with code 0, otherwise with a non-zero code. If this flag
is specified, *GMan* performs **only** the config validation. Otherwise, validation takes place
before every synchronization.

### Synchronizing

Synchronizing means updating GSuite's state to match the given configuration file. Without
specifying the `-confirm` flag the changes are just previewed:

```bash
$ gman \
    -private-key MYKEY.json \
    -impersonated-email<EMAIL_ADDRESS>\
    -users-config myconfig.yaml \
    -groups-config myconfig.yaml \
    -orgunits-config myconfig.yaml
2020/06/25 18:55:54 ✓ Configuration is valid.
2020/06/25 18:55:54 ► Updating organization myorganization...
2020/06/25 18:55:54 ⇄ Syncing organizational units
2020/06/25 18:55:56 ✁ There is no org units to delete.
2020/06/25 18:55:56 ✎ There is no org units to create.
2020/06/25 18:55:56 ✎ There is no org units to update.
2020/06/25 18:55:56 ⇄ Syncing users
2020/06/25 18:55:56 ✁ There is no users to delete.
2020/06/25 18:55:56 ✎ There is no users to create.
2020/06/25 18:55:56 ✎ There is no users to update.
2020/06/25 18:55:56 ⇄ Syncing groups
2020/06/25 18:55:57 ✁ There is no groups to delete.
2020/06/25 18:55:57 ✎ There is no groups to create.
2020/06/25 18:55:57 ✎ There is no groups to update.
2020/06/25 18:55:57 ⚠ Run again with -confirm to apply the changes above.
```

Run the same command again with `-confirm` to perform the changes.

### Static Passwords

GMan can be used to manage dummy/testing accounts with predefined passwords. Note that you should never
put real passwords in cleartext anywhere near GMan, but if you have public passwords, e.g. for workshops
and demonstrations, this feature can be handy.

To make use of this, set a cleartext password for a user in your `users.yaml`:

```yaml
organization: myorganization
users:
  - givenName: Josef
    familyName: K
    primaryEmail<EMAIL_ADDRESS>    orgUnitPath: /Developers
    password: i-am-not-secure-at-all
```

You must then opt-in to this feature by running GMan with `-insecure-passwords`:

```bash
$ gman \
    -private-key MYKEY.json \
    -impersonated-email<EMAIL_ADDRESS>\
    -users-config myconfig.yaml \
    -groups-config myconfig.yaml \
    -orgunits-config myconfig.yaml \
    -insecure-passwords
2020/06/25 18:55:54 ✓ Configuration is valid.
2020/06/25 18:55:54 ► Updating organization myorganization...
...
```

GMan will now set the configured password and store its SHA256 hash as a custom schema field on the user.
On the next run, GMan will compare the hash with the configured password and update the user in GSuite
only if needed.

## Limitations

### Sending the login info email to the new users

Due to the fact that it is impossible to automate the send out of the login information
email via Google API there are two possibilities to enable the first log in of the new users:

- manually send the login information email from admin console via _RESET PASSWORD_ option
  (follow instructions on [this official Google documentation](https://support.google.com/a/answer/33319?hl=en))
- set up a password recovery for users (follow [this official Google documentation](https://support.google.com/a/answer/33382?p=accnt_recovery_users&visit_id=637279854011127407-389630162&rd=1&hl=en) to perform it).
  This requires the `recoveryEmail` field to be set for the users. Hence, in the onboarding
  message the new users ought to be informed about their new GSuite email address and that on
  the first login, the _Forgot password?_ option should be chosen, so the verification code
  can be sent to to the private recovery email.

### API requests quota

In order to retrieve information about licenses of each user, there are multiple API requests
performed. This can result in hitting the maximum limit of allowed calls per 100 seconds. In
order to avoid it, *GMan* waits after every Enterprise Licensing API request for 0.5 second.
This delay can be changed by starting the application with specified flag
`-throttle-requests <value>`, where value designates the waiting time in seconds (e.g. `5s`).

## Changelog

For detailed information on the latest updates, check the [Changelog](CHANGELOG.md).

repository: stroebitzer/gman

repo_name: stroebitzer/gman


text:
# NUnit.org website

To get started developing the website, you have two options. You can develop in a Docker Container using VS Code, or you can install Ruby locally and develop locally.

## Installing Docker and VS Code

Do this if you want to develop in a Docker container using VS Code.

1. Install and configure [Docker](https://www.docker.com/get-started) for your operating system.

    **Windows / macOS**:

    1. Install [Docker Desktop for Windows/Mac](https://www.docker.com/products/docker-desktop).
    2. Right-click on the Docker taskbar item and update **Settings / Preferences > Shared Drives / File Sharing** with the drive the web app source code is located in. If you run into trouble, see [Docker Desktop for Windows tips](/docs/remote/troubleshooting.md#docker-desktop-for-windows-tips) on avoiding common problems with sharing.

    **Linux**:

    1. Follow the [official install instructions for Docker CE/EE for your distribution](https://docs.docker.com/install/#supported-platforms).
    2. Add your user to the `docker` group by using a terminal to run: `sudo usermod -aG docker $USER`
    3. Sign out and back in again so your changes take effect.

2. Install [Visual Studio Code](https://code.visualstudio.com/).
3. Install the [Remote Development extension pack](https://aka.ms/vscode-remote/download/extension).

### Quick Start for Docker with VSCode

1. Start VS Code and click on the quick actions Status Bar item in the lower left corner of the window.

    ![Quick actions status bar item](https://code.visualstudio.com/assets/docs/remote/common/remote-dev-status-bar.png)

2. Select **Remote-Containers: Open Folder in Container...** from the command list that appears, and open the root folder of the project you just cloned.

3. The window will then reload, but since the container does not exist yet, VS Code will create one. This may take some time, and a progress notification will provide status updates. Fortunately, this step isn't necessary the next time you open the folder since the container will already exist.

    ![Dev Container Progress Notification](https://code.visualstudio.com/assets/docs/remote/containers/dev-container-progress.png)

4. After the container is built, VS Code automatically connects to it and maps the project folder from your local file system into the container.

5. Open the terminal in VS Code to a bash prompt within the container by clicking on **Terminal > New Terminal**

6. In the terminal, type `bundle exec jekyll serve` to build and run the web site. (See below)

7. Open the web site at [http://localhost:4000](http://localhost:4000).

8. Begin developing in Visual Studio Code.

## Installing Ruby and Jekyll locally

1. Install Ruby 2.2 ([Linux](https://www.ruby-lang.org/en/documentation/installation/), [Mac](https://gorails.com/setup/osx/10.10-yosemite), [Windows](https://rubyinstaller.org/))
2. If you are on Windows, install [DevKit](https://rubyinstaller.org/add-ons/devkit/)
3. `gem install bundler`
4. `bundle install`

## Building the project

GitHub will do this automatically when you push, but this allows you to view the site locally before you commit.

1. `jekyll serve`

gha_language: SCSS