text:
# gepard
General purpose communication and synchronization layer for distributed applications / events, semaphores, locks and messages for JavaScript, Java and Python

- [Overview](#overview)
- [What is new](#what-is-new)
  - [Release 1-4-0 New Heartbeat Protocol to ensure the Availability of Connections](#release-1-4-0-new-heartbeat-protocol-to-ensure-the-availability-of-connections)
  - [Release 1-3-3 New FileContainer class for JavaScript and Java to simplify file-transfer.](#release-1-3-3-new-filecontainer-class-for-javascript-and-java-to-simplify-file-transfer)
  - [Release 1-3-0 Let's talk about Python](#release-1-3-0-lets-talk-about-python)
  - [Controlling Connections and Actions with a Hook](#controlling-connections-and-actions-with-a-hook)
  - [Perfect load balanced message handling.](#perfect-load-balanced-message-handling)
  - [Java bindings for all features:](#java-bindings-for-all-features)
- [Install](#install)
- [Getting Started](#getting-started)
  - [Base](#base)
  - [JavaScript](#javascript)
  - [Java](#java)
  - [Python](#python)
- [Configuration](#configuration)
- [Use Cases](#use-cases)
  - [Configuration Changes (Events)](#configuration-changes-events)
  - [Concurrent editing of a Dataset (Semaphores)](#concurrent-editing-of-a-dataset-semaphores)
  - [Synchronization of file processing (Locks)](#synchronization-of-file-processing-locks)
  - [A Nice Exotic Mixture of Programming Languages](#a-nice-exotic-mixture-of-programming-languages)
- [The Event Body](#the-event-body)
- [Examples](#examples)
  - [Examples Short](#examples-short)
    - [Event listener](#event-listener)
    - [Event Emitter](#event-emitter)
    - [Locks](#locks)
    - [Semaphores](#semaphores)
    - [Request / Result](#request--result)
      - [Send request](#send-request)
      - [Send result](#send-result)
  - [Examples Long](#examples-long)
    - [Event listener](#event-listener-1)
      - [In Application](#in-application)
      - [In Browser](#in-browser)
    - [Event Emitter](#event-emitter-1)
      - [In Application](#in-application-1)
      - [In Browser](#in-browser-1)
- [File Transfer with the FileContainer Class](#file-transfer-with-the-filecontainer-class)
  - [FileSender](#filesender)
  - [ileReceiver](#ilereceiver)
- [Heartbeat and Reconnection Capability Parameterization](#heartbeat-and-reconnection-capability-parameterization)
  - [Broker Side](#broker-side)
  - [Client Side](#client-side)
    - [Example to test](#example-to-test)
- [Technical Aspects of the Client](#technical-aspects-of-the-client)
- [Found a bug? Help us fix it...](#found-a-bug-help-us-fix-it)
- [https://github.com/gessinger-hj/gepard/blob/master/CHANGELOG.md](#httpsgithubcomgessinger-hjgepardblobmasterchangelogmd)
- [Contributors](#contributors)
- [Features](#features)
- [Changelog](#changelog)

# Overview
Gepard is a system consisting of a broker and connected clients.
The communication is done via sockets or web-sockets.
The sockets are always open so that any partner of a connection may be informed if this connection ended.
This is very useful in the area of semaphores and locks.

A client uses only one socket for all interactions with the broker. Thus a program needs only 1 client for all features.
In order to use only 1 Client instance it is suggested to use the static method

* JavaScript:

```js
gepard = require  ( "gepard" )  :
var client = gepard.getClient ( [ port [, host ] ] ) ;
```

* Java:

```java
import org.gessinger.gepard.Client ;
Client client = Client.getInstance ( [ port [, host ] ] ) ;

```

* Python:

```py
import gepard
client = gepard.Client.getInstance ( [ port [, host ] ] ) ;

```

Up to now a client is a standalone JavaScript program, a JavaScript app inside a browser, a Java program or a Python program.
In the next step clients for other languages like Php, Perl etc are planned.

The broker can be instantiated from a JavaScript program but the most common and simplest way to use it is to start it detached as a daemon.

The appropriate command is:

```bash
node_modules/.bin/gp.broker
```
This starts the Broker and the corresponding web-socket-proxy

If you want to start the broker alone:

```bash
node_modules/.bin/gp.broker.no.web
```

There is a separate program for administration purposes:
```bash
node_modules/.bin/gp.info
```
or
```bash
node_modules/.bin/gp.admin [ --help ]
```
# What is new

## Release 1-4-0 New Heartbeat Protocol to ensure the Availability of Connections

Gepard is based on fast communication by means of always-open sockets. Therefore it is crucial to monitor these connections.
This is achieved by a mechanism which exchanges packets between the broker and all connected clients in fixed time intervals defined
by the broker. This interval is transmitted to clients as they connect.

The broker sends a __PING__ message to the connected clients in each interval to which all clients are expected to respond with a __PONG__
message within the three next intervals. If no such response is received by the end of the third interval, the broker closes the connection-socket.

On the other end, after dispatching a __PONG__ message, the client waits for the next __PING__ from the broker to arrive within 3 intervals.
In case the subsequent __PING__ is not received, the client closes the connection socket and emits a __"disconnect"__ event to signal the status to the application.

If the client is configured to re-connect, it will try to establish a new connection to the broker in a pre-defined interval. On success, the client
will emit a __"reconnect"__ event to the application. All gepard-event-listeners which had been registered at the time of disconnect will then automatically be registered
with the broker again.

Example time-out conditions are:

- Broker restart after maintenance
- Backup time of a virtual machine
- Restart of a firewall

[Parameter, details and example](#heartbeat-and-reconnection-capability-parameterization)

## Release 1-3-3 New FileContainer class for JavaScript and Java to simplify file-transfer.

An instance of the __FileContainer__ class may be inserted at any place inside the body of an Event.

If the client runs on the same machine as the broker only the full path-name of the file will be transferred.

If the broker runs on a different machine the content of the file is read in as a byte-array and transferred as payload to the broker.

If the broker detects a target on a different machine the file is read in and put into the event's body before sending the data.

This is done on a per connection basis.

[Details](#file-transfer-with-the-filecontainer-class)

## Release 1-3-0 Let's talk about Python

In this release a full featured Python client is included. The implementation is __pure generic Python code__.
The features are:

* emit event
* listen to events
* request / result ( messages )
* semaphores ( synchronously / asynchronously )
* locks

## Controlling Connections and Actions with a Hook

In order to control connections and actions a default hook class is provided:
[ConnectionHook](https://github.com/gessinger-hj/gepard/blob/master/src/ConnectionHook.js)

This class contains several methods which are called in appropriate cases:

```js
connect ( connection )
shutdown ( connection, event )
getInfoRequest ( connection, event )
addEventListener ( connection, eventNameList )
sendEvent ( connection, eventName )
lockResource ( connection, resourceId )
acquireSemaphore ( connection, resourceId )
```
Each of these methods must return an answer wether to allow or reject the corresponding action.

The answer must be either a boolean value or a __Thenable__ which means a __Promise__ object of any kind.

The default for shutdown is to return a __false__ value if the incoming connection is not from localhost.
In all other cases the default returns a __true__

The parameter can be used to test the allowance in a deeper way.

For example using a Promise for shutdown enables an asynchronous check with help of a database configuration.

To configure this hook a __subclass__ of __ConnectionHook__ must be implemented and defined as user-hook in an JSON configuration file:

```json
{
  "connectionHook": "<path-to-javascript-code>/XmpConnectionHook"
}
```
This hook file is __require'd__ with the start of the broker.

In this case the command to start the broker is:

__
gp.broker --config=<full-config-file-name>
__

An example for a user defined hook is the [XmpConnectionHook.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/XmpConnectionHook.js) file:

```js
var util = require ( "util" ) ;
var ConnectionHook = require ( "gepard" ).ConnectionHook ;
var XmpConnectionHook = function()
{
  XmpConnectionHook.super_.call ( this ) ;
};
util.inherits ( XmpConnectionHook, ConnectionHook ) ;
XmpConnectionHook.prototype.connect = function ( connection )
{
  console.log ( "connection.getRemoteAddress()=" + connection.getRemoteAddress() ) ;
  return true ;
};
module.exports = XmpConnectionHook ;
```
If you prefer to start the broker from within your own JavaScript-program the configuration object can be set like:
```js
  var b = new Broker() ;
  b.setConfig ( <config-object or path to config-json-file> ) ;
  b.listen() ;
```
The parameter __connection__ in the above method-signatures is an internal used object with mainly the public useful methods:

1.  connection.isLocalHost()
1.  connection.getRemoteAddress()
1.  connection.getHostName()
1.  connection.getLanguage()
1.  connection.getApplicationName()
1.  connection.getApplication()
1.  connection.getId()

## Perfect load balanced message handling.

The use-case for request/respond is enhanced to a perfect load balancing.

Suppose there are __n__ message-listeners offering the same service-name ( event-name )

__m__ messages come in to the broker with __m__ = __n + 1__

The following is done:

1.  the first __n__ messages are sent to the __n__ free listener for processing the request.
1.  the __m-th__ message is stored inside the broker waiting for any of the listeners sending back the response.
1.  after receiving the first message-response from any listener the waiting __m-th + 1__ message is sent to the now free listener.

As long as a sent message is not returned the Broker stores it in relation to the worker connection.
If this connection dies the stored message is sent back to the originator marked with the fail state and appropriate text.
The status can be tested with event.isBad() which returns true or false.

## Java bindings for all features:

* emit event
* listen to events
* request / result ( messages )
* semaphores
* locks

With this it is very easy to communicate or synchronize between JavaScript programs or webapps in a browser with a Java server or Java program.

The conversion from JSON to Java and vice versa is done with the Gson Google library for Java.

If you need special serialization / deserialization you may set the appropriate Gson instance in the Event-class statically with the method Event.setGson() ;

The Event-class may convert the json to map Java's byte[]-array to NodeJS's Buffer and vice versa.
This can be set statically by Event.mapByteArrayToJavaScriptBuffer ( boolean state ).
The default is true.

# Install

__npm install gepard__

or the newest stable but development version:

npm install git+https://github.com/gessinger-hj/gepard

# Getting Started

Here are some kind of "Hello World" examples.

All commands are in the directory: __node_modules/.bin__ or __node_modules/.bin/gepard__

Up to now the JavaScript and the Java classes are implemented.

The examples show the nice and easy interaction between programs written in these different languages.

## Base
1.  __gp.broker
__
    Start the gepard broker with websocket proxy

1.  __gp.shutdown
__
    Send a __shutdown__ event to all clients an stop the broker

1.  __gp.info
__
    Show basic information from the broker

## JavaScript

1.  __gp.listen --name=hello
__
    Start a listener for events named __hello__

    If you want to listen to all events with name starting with hello use a wildcard:

    __gp.listen "--name=hello*"__

1.  __gp.emit --name=hello__ [--body='{"City":"Frankfurt"}']
    emit an event with name __hello__

1.  __gp.sem__

    Acquire a semaphore

1.  __gp.lock__

    Acquire a lock

1.  If you want to play with the web-client implementation use the appropriate files in:
    __node_modules/gepard/xmp/webclient__

To simplyfy this the command

```bash
gp.http.simple [options]
```

is supplied starting a simple js webserver detached.
Options are:

* --port=<port>, default=8888
* --root=<web-root>, default=node_modules/gepard/xmp/webclient
* --index=<index-file>, default=index.html

Start your browser and go to: __localhost:8888__

1.  __gp.http.simple.shutdown__

    Stop the simple webserver.

1.  __gp.http.simple.is.running__

    Check if the simple webserver is running.

In order to try out the examples goto node_modules/gepard/xmp.

The following examples exist:

* Listener.js
* Emitter.js
* EmitterWithBody.js
* EmitterWithStatusInfo.js
* Requester.js
* Responder.js
* Locker.js
* AsyncSemaphore.js

## Java

In order to try out the examples goto node_modules/gepard/java.
All examples are included in lib/Gepard.jar.
With the following command all examples can be executed:

```bash
java [-D<name>=<value>] -cp lib/Gepard.jar:lib/gson-2.3.1.jar org/gessinger/gepard/xmp/Listener
```

__Listener__ may be replaced by:

* Listener
* Emitter
* EmitterWithBody
* EmitterWithStatusInfo
* Requester
* Responder
* Locker
* AsyncSemaphore
* BlockingSemaphore

The class-version in the existing Gepard.jar is 1.6, so you need to have at least java 1.6 installed.
There is an ant file to build your own jar.

Options, e.g. for the event-name must be set in the common Java format: -Dname=hello

## Python

In order to try out the examples goto node_modules/gepard/python/xmp.

The following examples exist:

* Listener.py
* Emitter.py
* EmitterWithBody.py
* EmitterWithStatusInfo.py
* Requester.py
* Responder.py
* Locker.py
* AsyncSemaphore.py
* BlockingSemaphore.py

# Configuration

The communication is based on sockets. Thus only the port and optional the host must be specified to use Gepard.
The defaults are:

* port=17501
* host=localhost
* web-socket port=17502

The port, host and logging directory can be set either by
supplying these items

1. within creating an instance of Client or Broker in your code.

2. as startup arguments of your program as:
	- -Dgepard.port=<port>
	- -Dgepard.host=<host>
	- -Dgepard.log=<log-dir>

3. with environmant variables of the form:
	- export ( or set ) GEPARD_PORT=<port>
	- export ( or set ) GEPARD_HOST=<host>
	- export ( or set ) GEPARD_LOG=<log-dir>

# Use Cases

## Configuration Changes (Events)

Suppose you have 1 program that changes configuration-entries in a database-table.
After the new entries are committed the program sends an event with:

```js
client.emit ( "CONFIG-CHANGE" ) ;
```

Several clients do their work based on these data.

All clients including web-clients setup a listener for example with

```js
client.on ( "CONFIG-CHANGE", function callback(e) {} ) ;
```

## Concurrent editing of a Dataset (Semaphores)
Two users with their web browser want to edit the same user-data in a database.
In this case a Semaphore is very useful.

Both do

```js
gepard.port = 17502 ;
var sem = new gepard.Semaphore ( "user:4711" ) ;
this.sem.acquire ( function sem_callback ( err )
{
  // we are owner
  fetch data, edit and save

  then:

  this.release() ; // with this statement the second user's browser app is callbacked
}) ;
```

## Synchronization of file processing (Locks)

Suppose there are many files in a directory waiting to be processed.

Let's name the directory: foo/bar/input

In order to speed up the overall processing several identical programs should work together.

In this case Locks are very useful.
The following should be done:

```js
var fs     = require ( "fs" ) ;
var gepard = require ( "gepard" ) ;
var lock ;

var array = fs.readdirSync ( "foo/bar/input" ) ;
for ( var i = 0 ; i < array.length ; i++ )
{
	lock = new gepard.Lock ( array[i], function()
	{
		try
		{
			if ( ! this.isOwner() ) return ;
			.............. process file ................
		}
		finally
		{
			this.release() ;
		}
	} ) ;
}
```
## A Nice Exotic Mixture of Programming Languages

Suppose the following: There are a couple of JavaScript and Python programs to interact with a database. The database changes.
And it would be nice to not change modules for database access.

Especially if the new database is an Oracle database. Perhaps on Linux.

Everybody who had ever tried to install the appropriate NodeJS or Python module ended up in a mess of build, configuration and installation problems.

One of the nicest Java features is the total abstraction of the database handling via the JDBC api.

It is clear what to do: Use a Java Gepard client connected to a database and execute all simple REST kind of actions
via request/respond on the basis of Gepard.

In this combination changing a database vendor is only a 10 second job changing the connection url and restart the Java client. Ok: another 5 seconds. But that's it.

No compilation, no installation no problems.

# The Event Body
This member of an event is the holder for all payload-data. In all languages this is a hashtable with the restriction that the key must be
of type string.

* Java: __Map<String,Object>__
* JavaScript: __{}__ or in long form: __Object__
* Python: __{}__ which is in fact an object of type __dict__

Setter and getter are the appropriate methods __Event.putValue(name,value)__ and __Event.getValue(name)__.

__value__ is either a scalar type, a hashtable with strings as keys and valid object types, a list containing valid object types or a a combination of all valid types.
Thus a set of data like a tree can be used.

__Note: Gepard's data exchange mechanism is NOT intended to transport serialized objects between clients.__

The valid types are:
* scalar type objects: string, int, double, number
* array type objects:
  - Array ( [] )
  - List ( [] )
* hashtable type objects:
  - Java: Map<String,Object>
  - Python: dict ( {} )
  - JavaScript: Object ( {} )

There are 2 type of objects which are treated by gepard in a special way:
* dates
  - JavaScript: Date
  - Java: Date
  - Python: datetime.datetime
* bytes
  - JavaScript: Buffer
  - Java: byte[]
  - Python: bytearray, bytes ( bytes should not be used to send because in python < 3 bytes is a subclass of str, typeof byte == 'str'
    and thus cannot be detected by this mechanism)

In these cases an object is transferred from a generic class of a sender to the generic class of the receiver which means it is reconstructed in the target programming language.

__Note on Python:__

The built-in date class in python is not able to parse or format ISO date strings. In order to enable full interoperability related to dates
the gapard module tries to import the well known __dateutils__ module. This in turn imports the __six__ module. If these modules are in
python's module path the generic python date class can be used.

Details in:

* JavaScript: [gepard/xmp/EmitterWithBody.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/EmitterWithBody.js)
* Java: [gepard/java/org.gessinger/gepard/xmp/EmitterWithBody.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/EmitterWithBody.java)
* Python: [gepard/python/xmp/EmitterWithBody.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/EmitterWithBody.py)

# Examples

Ready to use examples for JavaScript are located in __.../gepard/xmp__

Ready to use examples for Java are located in __.../gepard/gepard/java/org.gessinger/gepard/xmp__ and compiled in
__.../gepard/java/lib/Gepard.jar__

Ready to use examples for Python are located in __.../gepard/python/xmp__

## Examples Short

### Event listener

Adding a event-listener with the __on()__ method may be done with a single event-name or a list of event-names.

__JavaScript__: client.on ( "ALARM", callback )

 or client.on ( [ "ALARM", "BLARM" ], callback )

__Java__: client.on ( "ALARM", callback )

or client.on ( new String[] { "ALARM", "BLARM" }, callback )

__Python__: client.on ( "ALARM", callback )

or client.on ( [ "ALARM", "BLARM" ], callback )

The callback will be called with an Event object of the appropriate name ( e.getName() )

Application

```js
  var gepard = require ( "gepard" ) ;
  var client = gepard.getClient() ;
```
Browser

```js
  var client = gepard.getWebClient ( 17502 ) ;
```

Code

```js
client.on ( "ALARM", function event_listener_callback(e)
{
  console.log ( e.toString() ) ;
});
```

Java

```java
import org.gessinger.gepard.Client ;
import org.gessinger.gepard.EventListener ;
import org.gessinger.gepard.Event ;
Client client = Client.getInstance() ;

client.on ( "ALARM", new EventListener()
{
  public void event ( Event e )
  {
    System.out.println ( e ) ;
  }
} ) ;
```

Python

```python
import gepard
client = gepard.Client.getInstance()

def on_ABLARM ( event ):
  print ( "on_ALARM" )
  print ( event )

client.on ( "ALARM", on_ABLARM )
```

Details in:

* JavaScript: [gepard/xmp/Listener.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/Listener.js)
* Java: [gepard/java/org.gessinger/gepard/xmp/Listener.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/Listener.java)
* Python: [gepard/python/xmp/Listener.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/Listener.py)

### Event Emitter

Application

```js
var gepard = require ( "gepard" ) ;
var client = gepard.getClient() ;
client.emit ( "ALARM",
{
  var thiz = this ;
  write: function()
  {
    thiz.end() ; // close connection after written
  }
});
```

Browser

```js
var client = gepard.getWebClient ( 17502 ) ;
client.emit ( "CONFIG-CHANGED" ) ;
```

Java

```java
import org.gessinger.gepard.Client ;
Client client = Client.getInstance() ;
client.emit ( "ALARM" ) ;
```

Python

```python
import gepard
client = gepard.Client.getInstance()
client.emit ( "ALARM" )
```

Details in:

* JavaScript: [gepard/xmp/Emitter.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/Emitter.js)
* JavaScript: [gepard/xmp/EmitterWithStatusInfo.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/EmitterWithStatusInfo.js)
* JavaScript: [gepard/xmp/EmitterWithBody.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/EmitterWithBody.js)
* Java: [gepard/java/org.gessinger/gepard/xmp/Emitter.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/Emitter.java)
* Java: [gepard/java/org.gessinger/gepard/xmp/EmitterWithStatusInfo.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/EmitterWithStatusInfo.java)
* Java: [gepard/java/org.gessinger/gepard/xmp/EmitterWithBody.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/EmitterWithBody.java)
* Python: [gepard/python/xmp/Emitter.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/Emitter.py)
* Python: [gepard/python/xmp/EmitterWithStatusInfo.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/EmitterWithStatusInfo.py)
* Python: [gepard/python/xmp/EmitterWithBody.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/EmitterWithBody.py)

### Locks

Application

```js
  var gepard = require ( "gepard" ) ;
  var lock = new gepard.Lock ( "resid:main" ) ;
```
Browser

```js
gepard.port = 17502 ;
var lock = new gepard.Lock ( "resid:main" ) ;
```
Code

```js
lock.acquire ( function ( err )
{
  console.log ( this.toString() ) ;
  if ( this.isOwner() )
  {
    .........
    this.release() ;
  }
} ) ;
```

Java

```java
import org.gessinger.gepard.Lock ;
Lock lock = new Lock ( "resid:main" ) ;
lock.acquire() ;
if ( lock.isOwner() )
{
  .........
  lock.release() ;
}
```

Python

```python
import gepard

lock = gepard.Lock ( "resid:main" )
lock.acquire()

if lock.isOwner():
  ......................
  lock.release()

```

Details in:

* JavaScript: [gepard/xmp/Locker.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/Locker.js)
* Java: [gepard/java/org.gessinger/gepard/xmp/Locker.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/Locker.java)
* Python: [gepard/python/xmp/Locker.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/Locker.py)

### Semaphores

Application

```js
  var gepard = require ( "gepard" ) ;
  var sem = new gepard.Semaphore ( "user:4711" ) ;
```
Browser

```js
gepard.port = 17502 ;
var sem = new gepard.Semaphore ( "user:4711" ) ;
```

Code

```js
sem.acquire ( function ( err )
{
  console.log ( this.toString() ) ;

    .....................

  this.release() ;
} ) ;
```

Java

Asynchronously

```java
import org.gessinger.gepard.Semaphore ;
import org.gessinger.gepard.SemaphoreCallback ;
final Semaphore sem = new Semaphore ( "user:4711" ) ;
sem.acquire ( new SemaphoreCallback()
{
  public void acquired ( Event e )
  {
    System.out.println ( sem ) ;
    .....................
    sem.release() ;
  }
}) ;
```

Synchronously

```java
import org.gessinger.gepard.Semaphore ;
final Semaphore sem = new Semaphore ( "user:4711" ) ;
// with or without a timeout
sem.acquire(5000) ;

if ( sem.isOwner() ) // if not timeout occured
{
    .....................
  sem.release() ;
}
```

Python

Asynchronously

```python
import gepard

def on_owner(sem):
  ................
  sem.release()

sem = gepard.Semaphore ( "user:4711" )
sem.acquire ( on_owner )
```

Synchronously

```python

import gepard

sem = gepard.Semaphore ( name )

sem.acquire ( 5 ) # with or without a timeout

if sem.isOwner():
  ...........
  sem.release()
```

Details in:

* JavaScript: [gepard/xmp/AsyncSemaphore.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/AsyncSemaphore.js)
* Java: [gepard/java/org.gessinger/gepard/xmp/AsyncSemaphore.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/AsyncSemaphore.java)
* Java: [gepard/java/org.gessinger/gepard/xmp/AsyncSemaphore.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/BlockingSemaphore.java)
* Python: [gepard/python/xmp/AsyncSemaphore.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/AsyncSemaphore.py)
* Python: [gepard/python/xmp/BlockingSemaphore.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/BlockingSemaphore.py)

### Request / Result

#### Send request

Application:

```js
  var gepard = require ( "gepard" ) ;
  var client = gepard.getClient() ;
```
Browser:

```js
  var client = gepard.getWebClient ( 17502 ) ;
```
Code:

```js
client().request ( "getFileList"
, function result(e)
  {
    console.log ( e.getBody().list ) ;
    this.end() ;
  });
```

Java

```java
import org.gessinger.gepard.Client ;
import org.gessinger.gepard.ResultCallback ;
import org.gessinger.gepard.Util ;
import java.util.List ;
final Client client = Client.getInstance() ;
client.request ( "getFileList", new ResultCallback()
{
  public void result ( Event e )
  {
    if ( e.isBad() )
    {
      System.out.println ( "e.getStatusReason()=" + e.getStatusReason() ) ;
    }
    else
    {
      List<String> list = (List<String>) e.getBodyValue ( "file_list" ) ;
      System.out.println ( Util.toString ( list ) ) ;
    }
    client.close() ;
  }
}) ;

```

Python

```python
import gepard

client = gepard.Client.getInstance()

def getFileList ( e ):
  if e.isBad():
    print ( e.getStatusReason() )
  else:
    print ( e.getValue ( "file_list" ) )
  e.getClient().close()

client.request ( "getFileList", getFileList )

```

Details in:

* JavaScript: [gepard/xmp/Requester.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/Requester.js)
* Java: [gepard/java/org.gessinger/gepard/xmp/Requester.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/Requester.java)
* Python: [gepard/python/xmp/Requester.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/Requester.py)

#### Send result

Application:

```js
  var gepard = require ( "gepard" ) ;
  var client = gepard.getClient() ;
```
Browser:

```js
  var client = gepard.getWebClient ( 17502 ) ;
```
Code:

```js
var list = [ "one.js", "two.js", "three.js" ] ;
client.on ( "getFileList", function ( e )
{
  e.getBody().list = list ;
  e.sendBack() ;
});
```

Java

```java
import org.gessinger.gepard.Client ;
import org.gessinger.gepard.EventListener ;
import org.gessinger.gepard.Event ;
final Client client = Client.getInstance() ;
client.on ( name, new EventListener()
{
  public void event ( Event e )
  {
    String[] fileList = new String[] { "a.java", "b.java", "c.java" } ;
    e.putBodyValue ( "file_list", fileList ) ;
    e.sendBack() ;
  }
} ) ;
```

Python

```python
import gepard
client = gepard.Client.getInstance()

fileList = [ "a.py", "b.py", "c.py" ] ;
def on_getFileList ( event ):
  print ( "Request in" ) ;
  print ( "File list out:" ) ;
  print ( fileList ) ;
  event.body["file_list"] = fileList ;
  event.sendBack() ;

client.on ( "getFileList", on_getFileList )
```

Details in:

* JavaScript: [gepard/xmp/Responder.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/Responder.js)
* Java: [gepard/java/org.gessinger/gepard/xmp/Responder.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/Responder.java)
* Python: [gepard/python/xmp/Responder.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/Responder.py)

## Examples Long

### Event listener

#### In Application

```js
var gepard = require ( "gepard" ) ;
var c = gepard.getClient() ;

var eventName = "ALARM" ;
console.log ( "Listen for events with name=" + eventName ) ;
c.on ( eventName, function(e)
{
  console.log ( e ) ;
});
c.on('end', function()
{
  console.log('socket disconnected');
});
c.on('error', function ( event)
{
  console.log( event );
});
c.on('shutdown', function()
{
  console.log('broker shut down');
});
```

#### In Browser

```html
<script type="text/javascript" src="Event.js" ></script>
<script type="text/javascript" src="MultiHash.js" ></script>
<script type="text/javascript" src="GPWebClient.js" ></script>
```

```js
    var wc = gepard.getWebClient ( 17502 ) ;
    this.wc.on ( "open", function onopen()
    {
    }) ;
    this.wc.on ( "error", function onerror()
    {
    }) ;
    this.wc.on ( "close", function onclose()
    {
    }) ;
		wc.on ( "ALARM", function event_listener_callback ( e )
		{
		  console.log ( e.toString() ) ;
		}) ;
```

### Event Emitter

#### In Application

```js
var gepard  = require ( "gepard" ) ;
var c = gepard.getClient() ;

var event = new gepard.Event ( "CONFIG-CHANGED" ) ;
event.setBody ( { "config-name" : "app.conf" } ) ;
c.emit ( event,
{
  write: function() // close connection after write
  {
    c.end() ;
  }
});
```
#### In Browser

```html
<script type="text/javascript" src="Event.js" ></script>
<script type="text/javascript" src="MultiHash.js" ></script>
<script type="text/javascript" src="GPWebClient.js" ></script>
```

```js
var wc = gepard.getWebClient ( 17502 ) ;
var event = new gepard.Event ( "CONFIG-CHANGED" ) ;
event.setBody ( { "config-name" : "app.conf" } ) ;
wc.emit ( event ) ;
```

# File Transfer with the FileContainer Class

The basic usage of this class is as follows:

## FileSender

JavaScript:

See also: [gepard/xmp/FileSender.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/FileSender.js)

```js
var gepard  = require ( "gepard" ) ;
var client = gepard.getClient() ;
var event = new gepard.Event ( "__FILE__" ) ;
var file = "<full-file-name>" ;
event.putValue ( "DATA", new gepard.FileContainer ( file ) ) ;
client.request ( event, function ( e )
{
  if ( e.isBad() )
  {
    console.log ( e.getStatus() ) ;
  }
  else
  {
    console.log ( "File " + file + " sent successfully." )
  }
  this.end() ;
}) ;
```

Python:

See also: [gepard/python/xmp/FileSender.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/FileSender.py)

```python
client = gepard.Client.getInstance()

event = gepard.Event ( "__FILE__" )

file = "<full-file-name>" ;
event.putValue ( "DATA", gepard.FileContainer ( file ) )

def result ( e ):
  if e.isBad():
    print ( e.getStatusReason() )
  else:
    print ( "File " + file + " sent successfully." )
  e.getClient().close()

print ( "Sending " + file )
client.request ( event, result )
```
Java:

See also: [gepard/java/org.gessinger/gepard/xmp/FileSender.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/FileSender.java)

```java
    final Client client = Client.getInstance() ;

    Event event = new Event ( "__FILE__" ) ;
    final String file = "<full-file-name>"
    event.putValue ( "DATA", new FileContainer ( file ) ) ;
    client.request ( event, new ResultCallback()
    {
      public void result ( Event e )
      {
        if ( e.isBad() )
        {
          System.out.println ( e ) ;
        }
        else
        {
          System.out.println ( "File " + file + " sent successfully." ) ;
          System.out.println ( "code: " + e.getStatusCode() );
          System.out.println ( "name: " + e.getStatusName() );
          System.out.println ( "reason: " + e.getStatusReason() );
        }
        client.close() ;
      }
    }) ;
```

##FileReceiver

JavaScript:

See also: [gepard/xmp/FileReceiver.js](https://github.com/gessinger-hj/gepard/blob/master/xmp/FileReceiver.js)

```js
  var client = gepard.getClient() ;
  client.on ( "__FILE__", function(e)
  {
    var data = e.removeValue ( "DATA" ) ;
    console.log ( data.getName() + " received." ) ;
    var fname = data.getName() + ".in" ;
    try
    {
      data.write ( fname ) ;
      console.log ( fname + " written." ) ;
    }
    catch ( exc )
    {
      e.control.status = { code:1, name:"error", reason:"could not write: " + fname } ;
      console.log ( exc ) ;
    }
    e.sendBack() ;
  });
```

Python:

See also: [gepard/python/xmp/FileReceiver.py](https://github.com/gessinger-hj/gepard/blob/master/python/xmp/FileReceiver.py)

```py
client = gepard.Client.getInstance()

def on___FILE__ ( e ):
  data = e.removeValue ( "DATA" )
  print ( data.getName() + " received." ) ;
  fname = data.getName() + ".in"
  try:
    data.write ( fname ) ;
    print ( fname + " written.")
  except Exception as exc:
    print ( exc )
  e.sendBack() ;

client.on ( "__FILE__", on___FILE__ )
```
Java:

See also: [gepard/java/org.gessinger/gepard/xmp/FileReceiver.java](https://github.com/gessinger-hj/gepard/blob/master/java/src/org/gessinger/gepard/xmp/FileReceiver.java)

```java
final Client client = Client.getInstance() ;
client.on ( "__FILE__", new EventListener()
{
  public void event ( Event e )
  {
    try
    {
      FileContainer fileContainer = (FileContainer) e.removeValue ( "DATA" ) ;
      String fname = fileContainer.getName() + ".in" ;
      fileContainer.write ( fname ) ;
      System.out.println ( fname + " written." );
      e.setStatus ( 0, "success", "File accepted." ) ;
    }
    catch ( Exception exc )
    {
      e.setStatus ( 1, "error", "File not saved." ) ;
      System.out.println ( Util.toString ( exc ) ) ;
    }
    try
    {
      e.sendBack() ;
    }
    catch ( Exception exc )
    {
      System.out.println ( Util.toString ( exc ) ) ;
    }
  }
} ) ;

```

# Heartbeat and Reconnection Capability Parameterization

## Broker Side

The default ping interval for the broker is 180000 milli-sec or 3 minutes. This value can be changed in different ways:

1.  Startup parameter: --gepard.heartbeat.millis=<nnn>
1.  Evironment variable: GEPARD_HEARTBEAT_MILLIS=<nnn>
1.  Variable in configuration-file: { "heartbeatMillis":<nnn> }
1.  In program: broker.setHeartbeatMillis ( <nnn> )

## Client Side

The default is reconnect=false

 This value can be changed in different ways:

1.  Startup parameter: --gepard.reconnect=true
1.  environment variable: export GEPARD_RECONNECT=true
1.  client.setReconnect ( true ) before any socket connection is active
1.  gepard.setProperty ( 'gepard.reconnect', 'true' )

If the boker is shut down all clients receive a __shutdown event__.
If __reconnect==true__ the appropriate callback in the client is called and the client api tries to reconnect.

At this place a call to __client.setReconnect(false|False)__ initiates a Client-shutdown without reconnection.

There are two new callbacks available signaling the state-change to the owner-application:

* Java
  1.  client.onReconnect ( InfoCallback icb )
  1.  client.onDisconnect ( InfoCallback icb )

* Python
  1.  client.onReconnect ( <callback> )
  1.  client.onDisconnect ( <callback> )

* JavaScript
  1.  client.on ( "reconnect", <callback> )
  1.  client.on ( "disconnect", <callback> )

### Example to test

1.  open a terminal, execute: node_modules/.bin/gp.broker or node node_modules/gepard/src/Broker.js
1.  open a terminal, execute: node node_modules/gepard/xmp/Listener.js
1.  open a terminal, execute: python node_modules/gepard/python/xmp/Listener.py
1.  open a terminal, goto node_modules/gepard/java

 execute: java -cp lib/Gepard.jar:lib/gson-2.3.1.jar org.gessinger.gepard.xmp.Listener

Then goto terminal one and kill the Broker either with ^C ( ctrl+C ) or with kill -9 <pid> or with the taskmanger on windows.

Appropriate output is visible.

Then start the Broker again and all clients reconnect again. Check with gp.info that all event-listener are registered again.

# Technical Aspects of the Client

NodeJS clients use the powerful but simple framework for asynchronously callbacks.

In Java and Python this asynchronicity is modeled by threads. There is a single thread reading from the socket connected to the Broker.
Incoming events are dispatched and the appropriate callbacks are executed. The main thread is not affected.

Thus any number of event listener may be registered or removed in the main thread.

Synchronous callbacks are needed with Locks and Semaphores. In this case an id-based blocking message queue
is used for communication between the threads.

Incoming events for asynchronous processing are propagated to separate running worker threads via a blocking fifo queue. Thus callbacks do not block each other. This applies to Java and Python.

By default 2 threads are running. This can be changed with the method Client.setNumberOfCallbackWorker(). Maximum is 10.

From this it is clear that all callback methods run in the context of one of the internal worker-threads and __not__ in the context of the main thread.

Per default the internal thread is not a daemon thread. If needed this can be changed by calling the method
- Python: Client.setDaemon([True|False])
- Java: Client.setDaemon([true|false])

before the first action on a Client instance because the internal thread is started when the first connection is needed.

# Found a bug? Help us fix it...

We are trying our best to keep Gepard as free of bugs as possible, but if you find a problem that looks like a bug to you please follow these steps to help us fix it...

* Update Gepard and make sure that your problem also appears with the latest version of Gepard.

* Goto the [issue tracker](https://github.com/gessinger-hj/gepard/issues) to see if your problem has been reported already.
  If there is no existing bug report, feel free to create a new one. If there is an existing report, but you can give additional information,
  please add your data to this existing issue. If the existing issue report has already been closed,
  please only re-open it or comment on it if the same (or a closely related issue) re-appears,
  i.e., there is a high chance that the very same bug has re-appeared. Otherwise, create a new issue report.

* Whenever you create a new issue report in our issue tracker, please make sure to include as much information as possible like
  exceptions with text and stack trace or other log information.

  Having all the required information saves a lot of work.

#
https://github.com/gessinger-hj/gepard/blob/master/CHANGELOG.md

# Contributors
- Hans-Jürgen Gessinger
- Paul Gessinger

# Features
* High performance
* Minimal configuration with
  - __GEPARD_PORT__
	- __GEPARD_HOST__
* All JavaScript client features like event listener, event emitter, semaphores, locks and messages
	are available in any web-browser apps.
* All client features are also available for Java and Python

# Changelog
See [change log details](https://github.com/gessinger-hj/gepard/blob/master/CHANGELOG.md)

repository: mcozd/gepard

repo_name: mcozd/gepard


text:
# Nova Larastan Tool

Run Larastan right from your Laravel Nova application

![nova_larastan screenshot](docs/NovaLarastanTool.png)

## Installation

You can install the package in to a Laravel app that uses [Nova](https://nova.laravel.com) via composer:

```bash
composer require ijpatricio/nova-larastan-tool
```

Next up, you must register the tool with Nova. This is typically done in the `tools` method of the `NovaServiceProvider`.

```php
// in app/Providers/NovaServiceProvider.php

// ...
public function tools()
{
    return [
        // ...
        new \Ijpatricio\NovaLarastanTool\NovaLarastanTool(),
    ];
}
```

As Larastan is mainly for a dev environment, to keep the dependencies `dev` only, you can setup previous `tools()` method as following:
```php
public function tools()
{
    $tools = [
        //... your regular tools
    ];

    if (app()->environment() === 'local') {
        $tools = array_merge($tools, [
            //... your require-dev tools
            new \Ijpatricio\NovaLarastanTool\NovaLarastanTool()
        ]);
    }

    return $tools;
}
```

## Usage

Click on the "Analyse code" button. That's it.

If Larastan is not installed, you will instead see something like this:

![nova_larastan screenshot](docs/LarastanNotInstalled.png)

Go to [LarastanGithubRepository](https://github.com/nunomaduro/larastan) for installation details.

### Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

### Security

If you discover any security related issues, please email ijpatricio (at) gmail dot com instead of using the issue tracker.

## Credits

- [João Patrício](https://github.com/ijpatricio)
- [Nuno Maduro](https://github.com/nunomaduro)

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

license: MIT

repository: ijpatricio/nova-larastan-tool

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: ijpatricio/nova-larastan-tool


text:
## Add your LEX codes here ...

## What is Lex?
[Lex](https://en.wikipedia.org/wiki/Lex_(software)) is used to generate lexical analyzers.

## Installation

### For Windows Systems:
- Head over to [this link](https://sourceforge.net/projects/gnuwin32/files/flex/2.5.4a-1/flex-2.5.4a-1.exe/download) to download flex.
- Install by double clicking `flex-2.5.4a-1_2.exe` from the downloads folder.
- Add the path: `C:\Program Files (x86)\GnuWin32\bin` in Environment Variables.

### For Linux Systems:

```bash
  sudo apt install flex
```

## Example
The file `c_language_analyzer.l` is the lex file which reads input from `check.c` file and analyses it simular to C - language.

```bash
  flex c_language_analyzer.l
  gcc lex.yy.c -o c_language_analyzer
  c_language_analyzer
```

branch_name: refs/heads/main

gha_license_id: MIT


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

### Description

CoreText in Apple iOS 8.x through 8.3 allows remote attackers to cause a denial of service (reboot and messaging disruption) via crafted Unicode text that is not properly handled during display truncation in the Notifications feature, as demonstrated by Arabic characters in (1) an SMS message or (2) a WhatsApp message.

### POC

#### Reference
- http://www.reddit.com/r/apple/comments/37e8c1/malicious_text_message/

#### Github
- https://github.com/perillamint/CVE-2015-1157

repository: trickest/cve

gha_language: HTML

repo_name: trickest/cve


text:
* 0.14 (not released yet)
  - updated fermi2 to r193 for a fix of open end trimming
  - updated bwa to r1142 (post 0.7.15)
  - updated trimadap for one additional 3'-end PE adapter
  - updated hapdip to r56 for better filtering in the fermikit mode
  - updated htsbox to r327 (forgot if it has any effect on fermikit)
  - updated k8 to 0.2.2 as is required by more recent hapdip
  - the assembly components should almost the same as v0.13, except the fermi2 bugfix for good
* 0.13
  - updated trimadap to r9 for trimming (not only masking)
  - updated hapdip to r36 for minor bug fixes
  - updated htsbox to r130 for a few minor changes and BAM sorting
  - dropped samtools dependency for BAM sorting (now by htsbox)
  - added test script (by Mike Lin)
  - The assembly components are identical to v0.12.
  - The calling components are also identical.
* 0.12
  - updated htsbox to r302 for SV calling
  - updated hapdip to r19 for multi-sample filtering.
  - This is the first public release of fermi.kit.
* 0.11
  - updated fermi2.pl to r188 for robustness (no method changes)
  - updated htsbox to r289 for quality binning and razip fix
  - The assembly is the same as v0.9
  - This version is not packaged.
* 0.10
  - updated htsbox to r282 which fixed a bug in samview's PAF output.
  - updated bfc to r181 which fixes a potential out-of-order bug. This bug
    should almost never happen for normal use of bfc.
  - updated bwa to r1044 for the same bugfix as in bfc.
  - updated trimadap-mt to r8 for the same bug.
  - updated seqtk to r82. It comes with two new commands `rename` and `gc`,
    though they are not actually useful to the fermi.kit pipeline.
  - The assembly is the same as v0.9.
* 0.9
  - updated fermi2.pl. It uses a new formula to automatically set -k.
  - updated htsbox to r281. No effective changes.
  - For 100bp reads, the assembly is the same as v0.8.
  - This version is used to produce the results in the manuscript.
* 0.8
  - updated bfc to r177. r177 fixed a bug which causes segfault if the read
    length is close to 128, 256, 512bp, etc. The results should be the same
    (except the random effect).
  - fermi2.pl optionally skip error correction.
  - This version is used to assemble 261 SGDP samples.
* 0.7
  - used to assemble SGDP public samples
  - used to assemble the CHM1-NA12878 pair v4

repository: WGLab/LinkedSV

gha_language: C

repo_name: WGLab/LinkedSV


text:
---
title: "Vapes"
date: 2016-01-27T15:58:26+08:00
lastmod: 2016-01-27T15:58:26+08:00
description: "Explorations into open source build systems for Windows using DosBox."
tags: ["News", "Programming", "JavaScript"]
categories: ["News"]
weight: 2
draft: false
toc:
  auto: false
math:
  enable: true
---

This outlines my very brief look into the world of vaping.

## Resources

* Grease case: <https://blackrockog.com/pages/best-oil-vape-pen-case?utm_source=whaxy&utm_medium=content&utm_content=casegrid&utm_campaign=vapecartridges>
* Decent pen: <http://kandypens.com/gravity-quartz-crystal-coilless-ceramic-vaporizer-sandblasted-black.html>
* High CPD: <https://www.medicaljane.com/review/pop-naturals-high-cbd-co2-oil-cartridge-review/>
* Vape: <https://www.sourcevapes.com/collections/top-rated-products/products/flosstradamus-source-orb-xl-gr1-ti-triple-coil-vape-pen?variant=14140365062>

repository: joelvaneenwyk/homepage

gha_language: JavaScript

repo_name: joelvaneenwyk/homepage


text:
---
title: How to set the Oak login token session expiration
description: Steps to set oak origin token session expiration timeout
type: Troubleshooting
role: Admin
level: Intermediate
version:  6.5, Cloud Service
feature: Developer Tools
topic: Administration
exl-id: 940d3cca-6052-40b6-b4f7-c0689ad21c94
---
# How to set the Oak login token session expiration

*This video walks through the steps to set the Oak login token session expiration.*

>[!VIDEO](https://video.tv.adobe.com/v/335468?quality=12&learn=on)

gha_language: SCSS


text:
# Getini

This is a simple command line utility that extracts a value from an INI file.

## Usage:

```
getini [FILE] [SECTION] KEY

```

This will output the value of the KEY in section SECTION in the INI file given
by FILE.

If FILE is not given or is "-", standard input is used.

If SECTION is not given, it defaults to returning matching keys before the
first section header in the INI file.

KEY and SECTION are case-insensitive.

If the key was found, it is output to standard output.
If the key was not found, `getini` exits with code 1.

repository: kennep/getini

repo_name: kennep/getini


text:
<!--
%\VignetteIndexEntry{Introduction to TileDB}
%\VignetteEngine{simplermarkdown::mdweave_to_html}
%\VignetteEncoding{UTF-8}
-->
---
title: "First Steps with TileDB"
css: "water.css"
---

This document introduces TileDB via several simple examples. A corresponding
document with more complete [API documentation](documentation.html) is also available.

# Getting started

Once the TileDB R package is installed, it can be loaded via `library(tiledb)`. Installation is
supported for Windows, Linux and macOS via the [official CRAN package][cran_tiledb], on Linux and
macOS via the [conda](https://anaconda.org/conda-forge) package as well as from source.

Documentation for the TileDB R package is available via the `help()` function from within R as well
as via the [package documentation][tiledb-r_docs] and an [introductory notebook][tiledb_notebook].
Documentation about TileDB itself is [also available](https://docs.tiledb.com/main/).

Several "quickstart" examples that are discussed on the website are available in the
[examples][tiledb_examples] directory. This vignette discusses similar examples.

In the following examples, the URIs describing arrays point to local file system object. When TileDB
has been built with S3 support, and with proper AWS credentials in the usual environment variables,
URIs such as `s3://some/data/bucket` can be used where a local file would be used. See the script
[ex_S3.R][ex_s3] for an example.

# Dense Arrays

## Preliminaries

These illustrations use the array created by the file [ex_1.R][ex_1] which one can run from within
R, or on the command-line. To follow along with discussion that follows, it helps to run the example
once to create the array after possibly adjusting the array location path from its default value
(using the current directory or, if set as an option, an override).

## Basic Reading of Dense Arrays

The file [ex_1.R][ex_1] in the examples directory is a simple yet complete example extending
[quickstart_dense.R][qs_dense] by adding a second and third attribute. In this as well as the
following examples we will use `tiledb_array()` to access the array; the older variants
`tiledb_dense()` and `tiledb_sparse()` remain supported but are deprecated and may be removed at
some point in the future.

*Read 1-D*

The first example extracts rows 1 to 2 and column 2 from an array. It also limits the selection to
just one attribute (via `attrs`), asks for the return to be a `data.frame` (instead of a simpler list)
and for the (row and column, if present as here) indices to not be printed (via `extended=FALSE`).

```r
> A <- tiledb_array(uri = uri, attrs = "b",
+                   return_as = "data.frame", extended=FALSE))
> A[1:2,2]
[1] 101.5 104.0
>
```

Note that the examples create three two-dimensional attributes. The attributes can be selected via
the `attrs` argument, or the `attrs()` method on the array object.  The square-bracket indexing then
selects with in the 2-d attribute object.

If multiple objects are returned (as `list` or `data.frame`), subsetting on the
returned object works via `[[var]]` or `$var`.  A numeric index also works (but needs to account for
`rows` and `cols`).

```r
> A <- tiledb_array(uri = uri, attrs = c("a","b"),
+                   return_as = "data.frame")
> A[1:2,2][["a"]]
[1] 2 7
> A[1:2,2]$a
[1] 2 7
>
```

*Read 2-D*

This works analogously.  Note that the results are generally returned as vectors, or as a columns of
a `data.frame` object in case that option was set.

```r
> A[6:9,3:4]
$a
[1] 28 29 33 34 38 39 43 44

$b
[1] 114.5 115.0 117.0 117.5 119.5 120.0 122.0 122.5

$c
[1] "fox" "A"   "E"   "F"   "J"   "K"   "O"   "P"
>
```

## Read 2-D with attribute selection

We can restrict the selection to a subset of attributes when opening the array.

```r
> A <- tiledb_dense(uri = uri, attrs = c("b","c"),
+                   return_as = "data.frame", extended=FALSE)
> A[6:9,2:4]
       b     c
1  114.0 brown
2  114.5   fox
3  115.0     A
4  116.5     D
5  117.0     E
6  117.5     F
7  119.0     I
8  119.5     J
9  120.0     K
10 121.5     N
11 122.0     O
12 122.5     P
>
```

This also illustrated the effect of setting `return_as = "data.frame"` when opening the array.

This scheme can be generalized to variable cells, or cells where N>1, as we can expand each
(atomistic) value over corresponding row and column indices.

The column types correspond to the attribute typed in the array schema, subject to the constraint
mentioned above on R types.  (The char comes in as a factor variable as is still the R 3.6.* default
which is about to change. We can also override, users can too.)

```r
> A <- tiledb_array("/tmp/tiledb/ex_1/", attrs=c("b","c"),
+                   return_as = "data.frame", extended=TRUE)
> sapply(A[6:9, 3:4], "class")
       rows        cols           b           c
  "integer"   "integer"   "numeric" "character"
>
```

Consistent with the `data.frame` semantics, *now* requesting a named column *reduces to a vector* as
this happens at the R side:

```
> A[6:9, 3:4]$b
[1] 114.5 115.0 117.0 117.5 119.5 120.0 122.0 122.5
>
```

# Sparse Arrays

## Basic Reading and Writing of Sparse Arrays

*Simple Examples*

Basic reading returns the coordinates and any attributes.  The following examples use the array
created by the [quickstart_sparse][qs_sparse] example.

```r
> A <- tiledb_array(uri = uri, is.sparse = TRUE)
> A[]
$rows
[1] 1 2 2

$cols
[1] 1 3 4

$a
[1] 1 3 2

>
```
We can also request a `data.frame` object, either when opening or by changing this object characteristic on the fly:

```r
> return.data.frame(A) <- TRUE
> A[]
  a rows cols
1 1    1    1
2 3    2    3
3 2    2    4
```

For sparse arrays, the return type is by default ‘extended’ showing rows and column but this can be overridden.

Assignment works similarly:

```r
> A[4,2] <- 42L
> A[]
> A[]
  rows cols  a
1    1    1  1
2    2    3  3
3    2    4  2
4    4    2 42
>
```

Reads can select rows and or columns:

```r
> A[2,]
  rows cols a
1    2    3 3
2    2    4 2
> A[,2]
  rows cols  a
1    4    2 42
>
```

Attributes can be selected similarly.

## Date(time) Attributes

Similar to the dense array case described earlier, the file [ex_2.R][ex_2]
illustrates some basic operations on sparse arrays. It also shows date and datetime types instead of
just integer and double precision floats.

```r
> A <- tiledb_array(uri = uri, return_as = "data.frame")
> A[1577858403:1577858408]
        rows cols a   b          d                       e
1<PHONE_NUMBER>    1 3 103 2020-01-11 2020-01-02 18:24:33.844
2<PHONE_NUMBER>    1 4 104 2020-01-15 2020-01-05 02:28:36.214
3<PHONE_NUMBER>    1 5 105 2020-01-19 2020-01-05 00:44:04.805
4<PHONE_NUMBER>    1 6 106 2020-01-21 2020-01-06 12:58:51.770
5<PHONE_NUMBER>    1 7 107 2020-01-25 2020-01-09 04:29:56.309
6<PHONE_NUMBER>    1 8 108 2020-01-26 2020-01-07 13:55:10.240
>
```

The row coordinate is currently a floating point representation of the underlying time type.  We can
both select attributes (here we excluded the “a” column) and select rows by time (as the time stamps
get converted to the required floating point value).

```r
> attrs(A) <- c("b", "d", "e")
> A[as.POSIXct("2020-01-01"):as.POSIXct("2020-01-01 00:00:03")]
        rows cols   b          d                       e
1<PHONE_NUMBER>    1 101 2020-01-05 2020-01-01 03:03:07.548
2<PHONE_NUMBER>    1 102 2020-01-10 2020-01-02 21:02:19.747
3<PHONE_NUMBER>    1 103 2020-01-11 2020-01-02 18:24:33.844
>
```

More extended examples are available showing indexing by date(time) as well as character dimension.

# Additional Information

The TileDB R package is documented via R help functions (_e.g._ `help("tiledb_array")` shows
information for the `tiledb_array()` function) as well as via a [website regrouping all
documentation][tiledb-r_docs].  Extended [API documentation][api_documentation] is available, as is a
[examples/][tiledb_examples] directory.

TileDB itself has extensive [installation](https://docs.tiledb.com/developer/installation),
and [overall documentation](https://docs.tiledb.com/developer/) as well as a [support forum](https://forum.tiledb.com/).

[cran_tiledb]: https://cran.r-project.org/package=tiledb
[tiledb-r_docs]: https://tiledb-inc.github.io/TileDB-R/
[api_documentation]: https://tiledb-inc.github.io/TileDB-R/documentation.html
[tiledb_examples]: https://github.com/TileDB-Inc/TileDB-R/tree/master/inst/examples
[tiledb_notebook]: https://github.com/TileDB-Inc/TileDB-R/tree/master/inst/notebooks

[ex_1]: https://github.com/TileDB-Inc/TileDB-R/blob/master/inst/examples/ex_1.R
[ex_2]: https://github.com/TileDB-Inc/TileDB-R/blob/master/inst/examples/ex_2.R
[ex_s3]: https://github.com/TileDB-Inc/TileDB-R/blob/master/inst/examples/ex_S3.R

[qs_dense]: https://github.com/TileDB-Inc/TileDB-R/blob/master/inst/examples/quickstart_dense.R
[qs_sparse]: https://github.com/TileDB-Inc/TileDB/blob/dev/examples/cpp_api/quickstart_sparse.cc

repository: TileDB-Inc/TileDB-R

gha_language: R

gha_license_id: NOASSERTION

repo_name: TileDB-Inc/TileDB-R


text:
---
layout: post
title: "Episode 77: Boss Wants Me To Speak and The 2% Raise"
date: 2017-10-04 12:00:00 -0700
guid: f95b4a47-9808-4c35-a33f-e4b738ec6d26
duration: "35:22"
length: 33944228
file: "https://dts.podtrac.com/redirect.mp3/download.softskills.audio/sse-077.mp3"
categories: episode
enable_comments: true
---

This week Jamison and Dave answer these questions:

1. My boss wants me to speak at conferences, but I'm very new to software. What should I do?
2. How do I get more than a 2% raise? That is the company average.

We talked about conferences a bit more way back in [episode 6](https://softskills.audio/2016/04/11/episode-6-speaking-at-conferences/).

We also talked more about playing the salary game in [episode 23](https://softskills.audio/2016/08/22/episode-23-cto-questions-and-getting-a-raise/), which is a technique for sharing salary information with your co-workers.

repository: soft-skills-engineering/website

branch_name: refs/heads/gh-pages

repo_name: soft-skills-engineering/website


text:
# mysqli_result::data_seek

This is useful function when you try to loop through the resultset numerous times.

For example:

```
<?php

$result = mysqli_query($connection_id,$query);

while ($row = mysqli_fetch_assoc($result))
 {
  // Looping through the resultset.
 }

// Now if you need to loop through it again, you would first call the seek function:
mysqli_data_seek($result,0);

while ($row = mysqli_fetch_assoc($result))
 {
  // Looping through the resultset again.
 }

?>
```

---

[Official documentation page](https://www.php.net/manual/en/mysqli-result.data-seek.php)

**[To root](/README.md)**


text:
---
indicator: 3.5.2
layout: indicator
permalink: /3-5-2/
sdg_goal: '3'
data_non_statistical: false
goal_meta_link: 'https://unstats.un.org/sdgs/metadata/files/Metadata-03-05-02.pdf'
goal_meta_link_text: United Nations Sustainable Development Goals Metadata (PDF 214 KB)
graph_type: bar
indicator_name: >-
  Alcohol per capita consumption (aged 15 years and older) within a calendar
  year in litres of pure alcohol
indicator_sort_order: 03-05-02
published: true
reporting_status: complete
target: >-
  Strengthen the prevention and treatment of substance abuse, including narcotic
  drug abuse and harmful use of alcohol
target_id: '3.5'
graph_title: >-
  Percent of adults (ages 18 years and older) who reported binge drinking in the
  past month
un_custodian_agency: World Health Organisation (WHO)
un_designated_tier: '1'
data_show_map: false
source_active_1: true
source_url_text_1: >-
  2011-2018 Los Angeles County Health Survey Data: Percent of adults (ages 18
  years and older) who reported binge drinking in the past month (M2 - Alcohol
  Use)
source_active_2: false
source_url_text_2: Link to Source
source_active_3: false
source_url_3: Link to source
source_active_4: false
source_url_text_4: Link to source
source_active_5: false
source_url_text_5: Link to source
source_active_6: false
source_url_text_6: Link to source
title: Untitled
national_indicator_available: >-
  Percent of adults (ages 18 years and older) who reported binge drinking in the
  past month
national_geographical_coverage: Los Angeles County
computation_units: Percentage
source_organisation_1: Los Angeles County Department of Public Health (DPH)
source_geographical_coverage_1: Los Angeles County
source_url_1: 'http://www.publichealth.lacounty.gov/ha/hasurveyintro.htm'
data_disaggregation_information: 'age, gender, race'
computation_definitions: >-
  Binge drinking is defined as drinking 4 or more drinks for females and 5 or
  more drinks for males on one occasion at least one time in the past month.
tags:
  - Proxy
---
**Proxy indicator:**
The international indicator measures _Alcohol per capita consumption (aged 15 years and older) within a calendar year in litres of pure alcohol_. The data available at the local level is "Percent of adults (ages 18 years and older) who reported binge drinking in the past month".

repository: dawncomer/open-sdg-data-starter

branch_name: refs/heads/develop

gha_language: Shell

repo_name: dawncomer/open-sdg-data-starter


text:
# v<IP_ADDRESS> - 7 November 2022

1. Updated solution to VS 2022
1. Added support for `maximumNumberOfDownloadedItems` to throttle downloads
1. Added `IPlaylist` to the `IGenerator` status updates
1. FIX: `Latest` download strategy would download the latest episode not the cache, it now does nothing if the latest episode is in the cache

# v<IP_ADDRESS> - 15 April 2022
1. FIX: ControlFile loading and saving was leaving the file open because `Dispose()` was not being called
1. FIX: Added missing `PostDownloadCommand` property to `IPodcastInfo`
1. FIX: Added missing `GetDiagnosticOutput` and `GetDiagnosticRetainTemporaryFiles` to `IReadOnlyControlFile`
1. FIX: `postdownloadcommand` element was being written twice by `SaveToFile`, one of them an invalid format which was causing files to become corrupt when written.
1. FIX: Changed all calls to `EventHandler<>.Invoke()` to be the new `handler?.Invoke(this,args)` as it can avoid some race conditions
1. FIX: `PodcastEpisodeNamingStyle.UrlFileNameFeedTitleAndPublishDateTimeInfolder` was always using the windows path separator in the folder name, it now follows the OS where it is running for the separator
1. `Podcasts` property of the ControlFile changed from `IList<PodcastInfo>` to be `IList<IPodcastInfo>` as it enables mocking and testing
1. `SyncItem` objects returned by the `IEpisodeFinder` now contain a `Guid` ID.
1. `StatusUpdateEventArgs` now has a flag to indicate if the task is complete as well as a reference to the `SyncItem` if available
1. Added these chars to the invalid filename chars ('?', ':', '\'', '’') as Google's crappy MediaStore implementation treats them as invalid (in some folders)
1. Added ability to register an already created object into the `IIocContainer` by calling `Register<TService>(TService instance)`
1. Created `IGenerator` and added the playlist generator into the IocContainer
1. Added the ability to generate a playlist to an arbitrary folder to `IGenerator`
1. Playlists are now sorted

# v<IP_ADDRESS> - 24 September 2021

1. First version deployed through Chocolatey
1. Updated user docs to describe installing through Chocolatey
1. Tweaked `app.config` to enable all console apps to run under .NET Framework runtime version 2 *or* version 4 depending what is installed. This means that you no longer are prompted to install .NET Framework 3.5 when running on Windows 10 and 11.
1. The utilities console apps now prints out the environment information when displaying help

# v<IP_ADDRESS> - 23 April 2019

1. Updated solution to VS 2017
1. Ported the core assemblies and console apps to .NET Core. Supporting .NET Standard v2 and .NET Core v2.1
1. .NET Core version should be identical to the v<IP_ADDRESS> .NET Framework (Windows only build). The only differences being
    -  MTP - we did this by using PInvoke this obviously depends on the platform so I have excluded it. We would only ever be able to get it to work on Windows and you might as well use the net35 build
    -  Permon counters - not supported in the BCL - this may change in future
    -  Tests - NUnit is supported however Rhino mocks are not
    -  WPF - used in the App, this isn’t a big loss as we never shipped it in the main ZIP anyway. WPF is due to be a part of .NET Core v3 released this year.
    -  LinFu - not supported on .NET Core, I have provided an implementation of our IoC Container that uses Microsoft.Extensions.DependencyInjection (this is available .NET Framework but guess what - not v3.5 we need at least 4.6.1)
1. .NET Core version has been tested on
    - .NET Core on Windows, Unbuntu on x86, Ubuntu on ARM v8 and Mac
    - Mono on Ubuntu on x86, Ubuntu on ARM V8 and Mac

# v<IP_ADDRESS> - 19 June 2018

1. Prevent crash if TLS1.1 and TLS 2.0 not available

# v<IP_ADDRESS> - 12 June 2018

1. Workaround for servers that no longer support TLS1.0

# v<IP_ADDRESS> - 28 February 2018

1. Added support for M3U playlist format

# v<IP_ADDRESS> - 22 February 2018

1. FIX: Fixed `AccessViolationException` with Windows 10 Creators Update 1703: `IStream.Write` no longer allows `NULL` for `pcbWritten`
1. Added support for `playlistPathSeparator`

# v<IP_ADDRESS> - 2 July 2016

1. Updated solution to VS 2015

# v<IP_ADDRESS> - 8 December 2015

1. Allowed invalid suffix UTC in the RFC822 Date as some sites use this suffix

# v<IP_ADDRESS> - 18 February 2015

1. Fixed a bug where automatically deleting a folder would remove the state.xml file
1. Stopped creating a download folder unless it is needed
1. Added ability to delete empty folders to SyncPodcasts
1. Added ability to purge empty folders
1. Added `DeleteEmptyFolder` config setting

# v<IP_ADDRESS> - 19 December 2013

1. Fixed an issue where if there was an error getting the free space on the destination drive then it would stop the copying. This prevented the destination of a sync from being a relative path, a UNC path or an MTP path

# v<IP_ADDRESS> - 28 July 2013

1. Added support for MTP devices and path schemas
1. Added `PodcastUtilities.Integration.Tests`

# v<IP_ADDRESS> - 9 September 2012

1. FIX: Fixed issues with `DownloadPodcasts` and `SyncPodcasts` if the podcasts were stored and accessed via a UNC pathname in the sourceRoot of the control file.
1. Added support for `{exefolder}` token in post download commands
1. Added `PostDownloadCommand` into config and supported args and cwd, changed from a string to be an `ITokenisedCommand`
1. Added `PerfmonCountersInstaller`
1. Made `ReadWriteControlFile` support `ICloneable`, test cloning to test `XmlSerialisation` read and write

# v<IP_ADDRESS> - 6 March 2012

1. Added `MaximumNumberOfFiles` config (to sync) into the global defaults for a PodcastInfo
1. Made `MaximumNumberOfFiles` defaultable
1. Added diagnostics section to global config, implemented verbose and retain temp files
1. Update docs for download to media player strategy, updated API CHM and example control file

# v<IP_ADDRESS> - 30 July 2011

1. Added `PurgePodcasts` utility
1. Added `DownloadStrategy` config
1. Corrected bug in publish date in naming style
1. Added state to downloads
1. added `UrlFilenameFeedTitleAndPublishDateTimeInFolder` naming style (pubdate_folder_title_url)
1. Made `DownloadPodcasts` respect `FreeSpaceToLeaveOnDestination` when downloading
1. Updated documentation used and developer, added naming styles that use the episode title
1. Fix bug where `SyncPodcasts` (or `PurgePodcasts`) would fault if a folder was missing (issue #9)
1. Fixed `IOException` when large number of concurrent threads (>10) were attempting to access the state file on slow flash memory - implemented retrying
1. Eliminated chars from filenames that are illegal in xml playlist files
1. Fixed `PurgePodcasts` so that it correctly supports `PodcastEpisodeNamingStyle.UrlFilenameFeedTitleAndPublishDateTimeInFolder`
1. Ensure that `PurgePodcasts` will only delete files that match the `Pattern` element in the `control.xml` file for the feed
1. Added `freeSpaceToLeaveOnDownloadMB` to control file and also added `retryWaitInSeconds` to enable file contention recovery to be configured for slow flash drives
1. Fixed handling of invalid characters when using episode title for filename

# v<IP_ADDRESS> - 6 July 2011

1. Added `DownloadPodcasts` utility
1. Added `maxNumberOfConcurrentDownloads` to control XML file
1. Added naming styles to the episode finder
1. Made the feed finder take account of the `SourceRoot` of all podcasts
1. Added max age for podcast episodes into the config file

# v<IP_ADDRESS> - 7 May 2011

1. Utilities include `SyncPodcasts` and `GeneratePlaylist`

repository: derekwilson/PodcastUtilities

gha_language: C#

repo_name: derekwilson/PodcastUtilities


text:
# Bytewax

## Description

The [Bytewax](https://bytewax.io) batch materialization engine provides an execution
engine for batch materializing operations (`materialize` and `materialize-incremental`).

### Guide

In order to use the Bytewax materialization engine, you will need a [Kubernetes](https://kubernetes.io/) cluster running version 1.22.10 or greater.

#### Kubernetes Authentication

The Bytewax materialization engine loads authentication and cluster information from the [kubeconfig file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/). By default, kubectl looks for a file named `config` in the `$HOME/.kube directory`. You can specify other kubeconfig files by setting the `KUBECONFIG` environment variable.

#### Resource Authentication

Bytewax jobs can be configured to access [Kubernetes secrets](https://kubernetes.io/docs/concepts/configuration/secret/) as environment variables to access online and offline stores during job runs.

To configure secrets, first create them using `kubectl`:

``` shell
kubectl create secret generic -n bytewax aws-credentials --from-literal=aws-access-key-id='<access key id>' --from-literal=aws-secret-access-key='<secret access key>'
```

Then configure them in the batch_engine section of `feature_store.yaml`:

``` yaml
batch_engine:
  type: bytewax
  namespace: bytewax
  env:
    - name: AWS_ACCESS_KEY_ID
      valueFrom:
        secretKeyRef:
          name: aws-credentials
          key: aws-access-key-id
    - name: AWS_SECRET_ACCESS_KEY
      valueFrom:
        secretKeyRef:
          name: aws-credentials
          key: aws-secret-access-key
```

#### Configuration

The Bytewax materialization engine is configured through the The `feature_store.yaml` configuration file:

``` yaml
batch_engine:
  type: bytewax
  namespace: bytewax
  image: bytewax/bytewax-feast:latest
```

The `namespace` configuration directive specifies which Kubernetes [namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) jobs, services and configuration maps will be created in.

#### Building a custom Bytewax Docker image

The `image` configuration directive specifies which container image to use when running the materialization job. To create a custom image based on this container, run the following command:

``` shell
DOCKER_BUILDKIT=1 docker build . -f ./sdk/python/feast/infra/materialization/contrib/bytewax/Dockerfile -t <image tag>
```

Once that image is built and pushed to a registry, it can be specified as a part of the batch engine configuration:

``` shell
batch_engine:
  type: bytewax
  namespace: bytewax
  image: <image tag>
```

repository: baskaranz/feast

repo_name: baskaranz/feast


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

### Description

The ssh_gssapi_parse_ename function in gss-serv.c in OpenSSH 5.8 and earlier, when gssapi-with-mic authentication is enabled, allows remote authenticated users to cause a denial of service (memory consumption) via a large value in a certain length field.  NOTE: there may be limited scenarios in which this issue is relevant.

### POC

#### Reference
No PoCs from references.

#### Github
- https://github.com/ARPSyndicate/cvemon
- https://github.com/DButter/whitehat_public
- https://github.com/Dokukin1/Metasploitable
- https://github.com/Iknowmyname/Nmap-Scans-M2
- https://github.com/NikulinMS/13-01-hw
- https://github.com/Zhivarev/13-01-hw
- https://github.com/bralbral/ipinfo.sh
- https://github.com/kaio6fellipe/ssh-enum
- https://github.com/syadg123/pigat
- https://github.com/tchivert/ipinfo.sh
- https://github.com/teamssix/pigat
- https://github.com/zzzWTF/db-13-01


text:
# Enable or disable Windows services

You need to speficy a list in csv format of services that you want to manage or use one of the default ones. Use _Service Display Names_ ONLY in this list. In doubt look at the defaults.

## Syntax:

$ disableEnableServices.ps1 -action {enable | disable | check} [-auto {$true | $false}] [-preset \<path>]

### MAN

* -action

    * enable: sets services startup type to manual

    * disable: sets services startup type to disabled

    * check: shows status of services in the list

* -auto (has effect only with enable or disable) [default: $false]

    * $false: decide action for each service

    * $true: like, automatic, you know

* -preset [default: ./services.csv]

    * path to the csv file

repository: kuczaQ/PowerShell-Scripts

repo_name: kuczaQ/PowerShell-Scripts


text:
# Steps

# Idea Wall
This awesome application lets you post ideas, to a wall.  Clue is in the name, hey?

This application is not actually a genuine app, it's to be used in the docker/kubernetes workshop.

## Dependencies
This application writes its data to Redis, so you need to have a redis to connect it to.

## Building & Running
The following steps will get you into a working state:

  - `npm install`
  - `npm run assets`
  - set environment variables `REDIS_HOST` and `REDIS_PASSWORD` to the right values
  - `npm run start`

The application should then be on http://<IP_ADDRESS>:9000

### Issues found

* eu-west1-c region not found

---

### Deploy

1. install gcloud sdk
2. install terraform
3. gcloud auth login
4. ./deploy.sh

### Support China

|  | gcloud | kubectl | service |
| ------| ------ | ------ | ------ |
| **office** | ✔ | ✔ | ✔ |
| **vpn** | ✔ | ✔ | ✔ |
| **home** | ☓ | ☓ | ✔ |

### Asia Region Service Accessing

|Region\Action  | Office TW VPN(Xian DC) | Office | Home | Home TW VPN(Xian DC) |
| ------| ------ | ------ | ------ | ------ |
| **Asia-southeast1** | ![office-xian](./asserts/images/southeast-office-xian-vpn.png) | ![office](./asserts/images/southeast-office.png) | ![home](./asserts/images/southeast-home.png) | ![home-xian](./asserts/images/southeast-home-xian-vpn.png) |
| **Asia-east1** | ![office-xian](./asserts/images/east-office-xian-vpn.png) | ![office](./asserts/images/east-office.png) | ![office](./asserts/images/east-home.png) | ![home-xian](./asserts/images/east-home-xian-vpn.png) |
| **Asia-northeast1** | ![office-xian](./asserts/images/northeast-office-xian-vpn.png) | ![office](./asserts/images/northeast-office.png) | ![home](./asserts/images/northeast-home.png) | ![home-xian](./asserts/images/northeast-home-xian-vpn.png) |

### Asia Region Dev building service - kubectl get pods > /dev/null

|Region\Action  | Office TW VPN(Xian DC) | Office | Home | Home TW VPN(Xian DC) |
| ------| ------ | ------ | ------ | ------ |
| **Asia-southeast1** | 0.13s user
 0.02s system
 22% cpu
 0.631 total | 0.13s user
 0.02s system
 30% cpu
 0.494 total | timeout | 0.13s user
 0.02s system
 23% cpu
 0.610 total |
| **Asia-east1** | 0.42s user
 0.07s system
 53% cpu
 0.905 total | 0.13s user
 0.02s system
 25% cpu
 0.594 total | timeout | 0.14s user
 0.02s system
 29% cpu
 0.536 total |
| **Asia-northeast1** | 0.13s user
 0.02s system
 16% cpu
 0.841 total | 0.44s user
 0.08s system
 31% cpu
 1.643 total | timeout | 0.13s user
 0.02s system
 23% cpu
 0.630 total |

```
time kubectl set image deployment/frontend nodejs-redis=docker.io/ihakula/idea-board:step-6
deployment "frontend" image updated
kubectl set image deployment/frontend
0.14s user 0.03s system 5% cpu 3.020 total

time kubectl scale deployment frontend --replicas=3
deployment "frontend" scaled
kubectl scale deployment frontend --replicas=3
0.14s user 0.02s system 7% cpu 2.111 total

```

repository: devops-china/kubernetes

repo_name: devops-china/kubernetes


text:
---
layout: portfolio
title: Realtor.com Local
---

![Realtor.com Local](/assets/rdc_local/rdc_local.jpg)

Data should tell a clear story to its users.

- *Project*: Realtor.com - New Local section
- *Description*: Transforming raw data into an experience with a story
- *Roles*: Lead UX Designer (Visual & Interaction)
- *Constraints*: Data, Platforms, Brand styleguide
- *Dates*: 2013-2014

*US State menu*

*School Report Card*

*Neighborhood Page - Current*

*User Flow*

*Current Status*

- 2013 - Architecture established, concept design, user testing - [Live version](http://www.realtor.com/local)
- 2014 - Multiple parts currently in development (not yet public, but soon)

*Description*

Realtor.com is the flagship product of Move Inc. and the original site for online real estate. It’s focus had been on users on the hunt who were ready to buy/rent. A new opportunity arose that was less about search results and more about research. A growing number of users were looking for information on their areas of interest, such as neighborhoods with good schools, walkable cities, and crime data. We decided to create a destination for users in this research mode, and the *Local* section was born. Developers quickly built databases, wired APIs and optimized keywords. Soon we had a huge amount of data, but it needed a focus.

I joined the team as lead UX (visual/interaction) designer and immersed myself with the developers and their data. With the help of our developers, Product Manger, and Information Architect, I wrote user stories, created user flow diagrams, and began to wireframe layouts for this local data. Instead of working from what data we had available, we designed what we thought users would look for on the page and then determined what data met those needs. We then tested our concepts along side competitors in lab and remote user studies. We humbly listened to users disagree with our assumptions and provide priceless feedback.

Soon I had revised concepts based on user and team feedback which are currently in development. Features like responsive layouts and interactive maps may sound impressive, but the content must be presented in a digestible manner to make an engaging experience for users. This project has gone from being a flood of data, with little focus, to being a crafted narrative tailored to meet the needs or real users. It's been a great lesson in project management and a reminder of the value of real user testing. I can’t wait to share it with our audience.


text:
---
#
# Use the widgets beneath and the content will be
# inserted automagically in the webpage. To make
# this work, you have to use › layout: frontpage
#
layout: frontpage
header:
  title: ''
  image_fullwidth: ../images/scvt/pool_sign_photo.jpeg
widget1:
  title: "Membership"
  url: '/membership/'
  text: 'How to sign up'
widget2:
  title: "Classes"
  url: '/classes/'
  text: 'More about our classes'
widget3:
  title: "About Us"
  url: '/about/'
#  image: scvt/scuba_hokie.png
  text: 'Learn about the club'
#
# Use the call for action to show a button on the frontpage
#
# To make internal links, just use a permalink like this
# url: /getting-started/
#
# To style the button in different colors, use no value
# to use the main color or success, alert or secondary.
# To change colors see sass/_01_settings_colors.scss
#
#
callforaction:
  url: http://eepurl.com/7ESfr
  text: Sign up for our mailing list ›
  style: alert
permalink: /index.html
#
# This is a nasty hack to make the navigation highlight
# this page as active in the topbar navigation
#
homepage: true
---


text:
# NetworkServer

## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**id** | **str** | Unique network server identifier |
**port** | **int** | UDP/TCP port on which to listen for client connections |
**protocol** | **str** | Protocol which is used to establish client connections |
**interface** | **str** | Bind server socket to a particular device, specified as interface name (required for dpdk driver) | [optional]
**stats** | [**NetworkServerStats**](NetworkServerStats.md) |  |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

repository: Spirent/openperf

repo_name: Spirent/openperf


text:
# WiFi Platformio Implementation

WiFi library used in platformio, the library can build a client or a server on ESP8266 or ESP32.

you could easily choose the chip in platformio.ini, for example, the configuration for ESP8266 is:
```
[env:featheresp8266]
platform = espressif8266
framework = arduino
board=huzzah
```

## Getting Started

1. You need to install [platformio](https://platformio.org/) before using the code. However, it is easier to change the code to compatiable with Arduino IDE.

2. In the src/ folder, you need to choose to keep main_client.cpp or main_server.cpp for your device.

3. You can use Platformio directly to compile or upload the firmware.

Or you use:
```
make (all): to compile the firmware
make upload: to upload to your device
make clean: clean the project
make update: to update all the libraries
```

## API Functions
Server
```
void setup_server(char* ssid, char* password);
void check_client();
void client_to_serial();
void server_to_client(byte* data, int data_size);
void run_server();
void set_data_serial(bool enable);
void server_status();

```
Client
```
void setup_client_wifi(char* new_ssid, char* new_password);
void client_to_server(byte* data, int data_size);
void check_server();
int read_server(byte* data);
bool server_status();
void set_data_server(bool enable);

```
## Licence

MIT


text:
# vs-window-title-changer

This is a Visual Studio extension that allows you to set the VS titlebar using an expression.
The expression can use some of the internal state variables of Visual Studio
(e.g.: path of currently open solution file) to compose the title string.

## Installation

You have several options to install this extension:
- In the `Tools | Extensions and Updates...` menu of VS studio search online
  for the "Visual Studio Window Title Changer" extension.
  It's enough to put "title changer" to the search box.
- [Download from the Visual Studio Gallery](https://visualstudiogallery.msdn.microsoft.com/2e8ebfe4-023f-4c4d-9b7a-d05bbc5cb239)
- [Download from the release section of this repo](https://github.com/pasztorpisti/vs-window-title-changer/releases)

## Usage and help

After installing the plugin go to the `Tools | Options... | VS Window Title Changer` options.
Select the `Window Title Setup` row and click the `...` button when it appears.
This should pop up the title setup window where you can enter your window title expression.

![Title Setup Window](TitleSetupWindow.png)

While the title expression setup window is open you can press F1 to read the help.
Alternatively you can read the same help [here](http://htmlpreview.github.io/?https://github.com/pasztorpisti/vs-window-title-changer/blob/master/Forms/TitleSetupEditorHelp.html).

## Development

The code and solution files for VS2005, VS2008 and VS2010 can be found in the
[pre-vs2017 branch](https://github.com/pasztorpisti/vs-window-title-changer/tree/pre-vs2017).

repository: pasztorpisti/vs-window-title-changer

repo_name: pasztorpisti/vs-window-title-changer


text:
# posh-navigation

posh-navigation exports functions for quickly jumping between enlistments and projects.

## Exported functions

### Get-Enlistment

Retrieves the current enlistment based on current location.

	C:\repositories\git-status-cache\src\GitStatusCache> Get-Enlistment

	Alias ProjectsTemplate Root
	----- ---------------- ----
	gsc   gitstatuscache   C:\repositories\git-status-cache

### Set-Enlistment

Navigates to the specified enlistment.

	C:\repositories\git-status-cache\src\GitStatusCache\ide> Set-Enlistment gscpc
	C:\repositories\git-status-cache-posh-client> Set-Enlistment gsc
	C:\repositories\git-status-cache>

### Resolve-ProjectRoot

Returns the root path for the specified project in the current enlistment. Useful helper for scripts that operate on projects shared in multiple enlistments (ex. building, running tests, etc.).

	C:\repositories\git-status-cache> Resolve-ProjectRoot rj
	C:\repositories\git-status-cache\ext\rapidjson
	C:\repositories\git-status-cache> Resolve-ProjectRoot rdc
	C:\repositories\git-status-cache\ext\ReadDirectoryChanges

### Set-Project

Navigates to the specified project.

	C:\repositories\git-status-cache> Set-Project gsc
	C:\repositories\git-status-cache\src\GitStatusCache> Set-Project rj
	C:\repositories\git-status-cache\ext\rapidjson>

## Installation

posh-navigation will automatically create a sample JSON configuration file and add an import for the module in your PowerShell $PROFILE.

1. Launch PowerShell and navigate to posh-navigation's root.
2. Run Install.ps1.
3. Reload your shell or call ". $profile" to reload PowerShell with posh-navigation.

After installation you can customize your environment by modifying the JSON configuration file.

	PS C:\Repositories\posh-navigation> .\install.ps1
	Creating sample config file at "C:\repositories\posh-navigation\bin\machineName.json".
	Adding posh-navigation to profile.
	posh-navigation successfully installed!
	Please reload your profile for the changes to take effect:
		. $PROFILE

## Configuration

After installation define your enlistments and projects by modifying the JSON configuration file.

Enlistments may specify a ProjectsTemplate that contains aliases and paths to specific projects within the enlistment. The same ProjectsTemplate may be referenced by multiple enlistments.

	{
	    "Enlistments":
	    [
	        {
	            "Alias": "1",
	            "ProjectsTemplate": "mario",
	            "Root": "E:\\ws\\1"
	        },
	        {
	            "Alias": "2",
	            "ProjectsTemplate": "mario",
	            "Root": "E:\\ws\\2"
	        },
	        {
	            "Alias": "e",
	            "Root": "D:\\environment"
	        },
	        {
	            "Alias": "ta",
	            "Root": "D:\\text-adventure"
	        }
	    ],
	    "ProjectsTemplates":
	    [
	        {
	            "Name": "mario",
	            "Projects":
	            [
	                {
	                    "Alias": "k",
	                    "Root": "\\Products\\Kart"
	                },
	                {
	                    "Alias": "p",
	                    "Root": "\\Products\\Party"
	                }
	            ]
	        }
	    ]
	}

The following switches to enlistment 2 and navigates to the Kart project.

	Set-Enlistment 2
	Set-Project k

repository: cmarcusreid/posh-navigation

repo_name: cmarcusreid/posh-navigation


text:
# 2 - How KRM Works

⏱ *estimated time: 2 hours*

Now that you have a Kubernetes environment to work with, let's learn the basics of the Kubernetes Resource Model. This demo has 4 parts.

## What you'll learn

- What KRM stands for
- How to define a Kubernetes object using KRM
- How to manually apply a Kubernetes object to a cluster using `kubectl`
- How to streamline KRM editing using `kustomize`
- How the CymbalBank application can be expressed as Kubernetes resources
- How to push KRM resources to a Git repo
- How to create a Continuous Deployment pipeline triggered on a Git repo, to deploy KRM into production.

## Prerequisites

1. **Complete [part 1](/1-setup)** to bootstrap your environment.

###  **[Continue to Part A - Setup](partA-setup.md)**.

repository: raghu-manne/build-a-platform-with-krm

repo_name: raghu-manne/build-a-platform-with-krm


text:
# Formly Primer

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.1.

## Development server

Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.

## To Install Formly on Your Projects ....

Step 1 - Run `ng add @angular/material` and setup your preferred settings such as
    - the theme
    - typography
    - browser animations etc

Step 2 - Run `ng add @ngx-formly/schematics --ui-theme=material`;

You should then be good to go ...

## Explore the other branches .....

There are different branches to explore .... you will see different topics being tackled based on branch name ... enjoy :)

repository: Metrophobe/angular-formly-primer

repo_name: Metrophobe/angular-formly-primer


text:
# generator-mendix [![Build Status](https://secure.travis-ci.org/mendix/generator-mendix.png?branch=master)](https://travis-ci.org/mendix/generator-mendix) [![npm version](https://badge.fury.io/js/generator-mendix.svg)](http://badge.fury.io/js/generator-mendix) [![DAVID](https://david-dm.org/mendix/generator-mendix.svg)](https://david-dm.org/mendix/generator-mendix) [![Development Dependency Status](https://david-dm.org/mendix/generator-mendix/dev-status.svg?theme=shields.io)](https://david-dm.org/mendix/generator-mendix#info=devDependencies)

[![NPM](https://nodei.co/npm/generator-mendix.svg?downloads=true&stars=true)](https://nodei.co/npm/generator-mendix/)

> [Yeoman](http://yeoman.io) generator for Mendix widgets.

## About

This generator uses the Yeoman scaffolding tool to let you quickly create a [Mendix widget](https://world.mendix.com/display/public/howto50/Custom+Widget+Development) based on the latest [AppStoreWidgetBoilerPlate](https://github.com/mendix/AppStoreWidgetBoilerplate). You can either use the full boilerplate with example code, or choose to use an empty widget.

If you want to see a short demo (this uses the older 1.x widget generator and only Grunt), please look at our [webinar](http://ww2.mendix.com/expert-webinar-developing-widgets.html)

---

## Prerequisites _(you only have to do this once)_

First, you need to have [Node.js](https://nodejs.org/en/) installed. (We recommend a 6.x LTS version, the generator is tested against 6). After that, you need to install Yeoman and the Mendix Widget generator:

Open a command-line window (Press Win+R and type ``cmd`` or use Powershell)

```bash
  npm install -g yo generator-mendix
```

Make sure you have the latest version of ``yo``. The version we work with currently is 1.8.5 (which you can check by running ``yo --version``)

Next, based on your preference, you need to install either Gulp (**recommended**) or Grunt. Install this by typing:

```bash
  # If you want to use Gulp, run:

  npm install -g gulp-cli

  # If you want to use Grunt, run:

  npm install -g grunt-cli

```

---

## Scaffold a widget

### 1. Start the generator in the folder you want to create a widget

```bash
yo mendix
```

### 2. Provide the following information about your widget:

The following information needs to be provided about your widget:

* name
* description
* copyright
* license
* version
* author
* Github username (optional)

You can press \<Enter\> if you want to use the default values.

### 3.1. Which task runner do you want to use?

#### Gulp

The widget generator will include a **Gulpfile.js** and the necessary package.json for running Gulp tasks. We recommend using Gulp because of the speed.

#### Grunt

Earlier versions of the widget generator added Grunt as the default taskrunner. We included this option as well if you want to use this.

### 3.2. Which template do you want to use?

#### AppStoreWidgetBoilerplate

This uses the standard boilerplate which is on Github. This is recommended if you are a beginner. It includes example code with jQuery* and templates.

#### Empty widget

The empty widget will use a slim version of the AppStoreWidgetBoilerplate. It only provides the essential methods and setup. Furthermore, it will ask you if you want to use templates and jQuery*.

\* **We do not recommend using jQuery in your widgets, please [read this issue](https://github.com/mendix/AppStoreWidgetBoilerplate/issues/38). For simple DOM-manipulation you can use Dojo, which is provided by Mendix. Only use jQuery when you need it for certain external libraries that depend on it.**

---

## Use a taskrunner for development

The widget generator will scaffold a widget for you. It provides a convenient setup to develop you widget and publish it on Github. To make it even more easy, we add files for taskrunners.

### Gulp

The following tasks are provided in the **Gulpfile.js** and can be started by running ``gulp <TASKNAME>`` or ``npm run <TASKNAME>``:

* ``default``

You can omit this taskname and just run ``gulp``. This will watch for any changes in your ``src`` directory. If a change occurs, it will automatically create a new **MPK** and copy this to your ``widgets`` directory.

It will also copy any changed Javascript files to your deployment folder.  For changes in ``XML`` or ``CSS`` you will still need to synchronize your project directory (press F4 in the modeler) and redeploy.

* ``modeler``

This will try to start the test-project that is included in the ``test`` folder. It automatically opens the Modeler with this project. If you have your test-project in a different location, you can change the following options in ``package.json``:

```json
  "paths": {
    "testProjectFolder": "./test/",
    "testProjectFileName": "Test.mpr"
  },
```

Note: If you provide a different path to the test-project in Windows, make sure you escape backslashes. So for example: ```C:\Projects\TestFolder``` needs to be properly written in the JSON as:

```json
    "testProjectFileName": "C:\\Projects\\TestFolder"
```

* ``version``

This task will show you the version number of the widget by reading the ``packages.xml`` file. You can set the version number with this task by typing:

``gulp version -n=X.X.X`` or ``npm run version -- -n=X.X.X``

* ``folders``

This will tell you which folders Gulp is using. You can change the folder of the test-project folder (See ``modeler`` task)

* ``build``

This will build the widget for you. It will output a new **MPK** file to both your ``dist`` folder, as well as the ``widgets`` folder in your test-project directory.

* ``icon``

This task will read the ``icon.png`` file (or any other image file if you provide the task a filename using ``gulp icon --file=<filename>``) and outputs a base64 string that you can use in your widget.xml.

### Grunt

The tasks that are provided by Gulp are also provided in the **Gruntfile.js**. The following tasks are configured:

* ``start-modeler`` : same as ``gulp modeler``
* ``build``
* ``version`` and ``version:X.X.X``
* ``folders``
* ``icon``*
* ``watch`` : is the same as ``gulp default``

\*This task can only read ``icon.png``, but it will automatically set the base64 string in your widget.xml for you.

---

## Use a taskrunner in an existing widget

* _My widget repository does not have a ``Gruntfile.js`` or ``Gulpfile.js``._

We thought about that. Make sure you open a command-line terminal in your widget repository. It needs at least the widget files in the ``src`` folder. By simply running the generator there, it will ask you if you want to install a taskrunner. It also needs two parameters (widget name and version number) that it tries to read from the package.xml and widget.xml

* _My widget repository contains a package.json and ``Gruntfile.js`` or ``Gulpfile.js``_

Great! If you have made sure you have Grunt/Gulp installed (See above, prerequisites), you can start using it. The only thing you need to do is install the dependencies for the different tasks. Run the same folder:

```bash
  npm install
```

Now you can use the Grunt/Gulp tasks as described.

---

## Troubleshooting

* _I get an error that it cannot find a dependency or local Grunt/Gulp._

Did you make sure you have the dependencies installed? Run ``npm install`` in your widget folder (it needs to have a package.json and **Gulpfile.js**/**Gruntfile.js**)

* _Some of the tasks cannot be found_

Check the version of your **Gruntfile.js**/**Gulpfile.js** (stated in the top of the file). The tasks described here are written for the 2.0 version of the widget generator. Any previous versions are outdated. If you run the widget generator in your widget folder again, it will update the file and dependencies for you.

* _I am getting weird errors_

Please report your issues [here](https://github.com/mendix/generator-mendix/issues). and we'll troubleshoot together with you.

---

## TODO:

* Add LICENSE files [request](https://github.com/mendix/generator-mendix/issues/19)
* Add JSHint (Grunt/Gulp)
* Add SASS support (add ``_sass`` folder that will output CSS to your src folder)

## Issues

Issues can be reported on [Github](https://github.com/mendix/generator-mendix/issues).

repository: tomhmoses/generator-mendix

repo_name: tomhmoses/generator-mendix