text:
Mar-8-2021, Authored by Cathy Hong Zhang, Jun Shao, Eunju Kim

This document describes the coordinataion among the four components: Openstack Cluster, Cluster Controller, Resource Collector, and Scheduler as well as the cluster resource collection flow design.

In current code base, when the scheduler gets a POD request, it will send a HTTP request to the Resource Collector to get the the cluster resource information and the Resource Collector may loop through a linked list of all the siteinfocaches. This whole operation introduces a long latency to the POD creation path.
To reduce the POD creation latency, instead of a pull model, we will use a push model in our new code design. That is, the Resource Collector should proactively send to the Scheduler the cluster resource snapshot of those clusters when their resources change. Then in the POD scheduling flow path, the Scheduler only needs to query its local cache for all the clusters resource.

A cluster information consists of two parts. One part is static info. The other is dynamic info. The scheduling platform gets the cluster's static info through cluster CRD creation/registration. The scheduler should list/watch for the cluster's crd object creation/update/delete in ETCD, and should save the cluster's static info into its local cache.

The scheduler should get each cluster's dynamic resource info, such as available cpu, memory, disk storage, eip, etc. from the resource collector.

The following data structures show the cluster's dynamic info fields whose values will be dynamically obtained from the Openstack by the resource collector and then sent to the scheduler.

|  Cluster Resource Dynamic Info Fields |  Description                                          |
|:-------------------------------------:|:-----------------------------------------------------:|
|  Available CPUAndMemory               | currently available CPUAndMemory of a cluster         |
|  Available DiskStorage                | currently available disk space of a cluster           |
|  Available EIPs                       | currently available EIP count of a cluster            |

When the resource collector process first starts, it will query the Openstack for the total allocable CPU, Memory, DiskStorage, and EIP information and send these info to the scheduler.

TotalAllocableCPU/cluster= sum of (Total empty host's CPU capacity * the host's CPU allocation ratio)
TotalAllocableMemory/cluster= sum of (Total empty host's memory capacity * the host's memory allocation ratio)
TotalAllocableStorage/cluster= sum of (Total empty host's storage capacity * the host's storage allocation ratio)
TotalAllocableEIP/cluster= sum of (Total empty host's eip capacity * the host's eip allocation ratio)

Note that the resource collector only needs to send this info to the scheduler once.

## Coordination Between Cluster CRD Spec and the region-AZ configuration in Openstack Clusters
When a cluster CRD is registered with the scheduling platform, the cluster controller will send the static cluster information, such as the cluster's region and AZ, to the resource collector. The resource collector should save this information into its local cache. Later when the resource collector queries Openstack for a cluster's dynamic info, it should use the cluster's region and AZ from its local cache as the unique ideintifier of the cluster. Since the resource collector can get each cluster's region and AZ from its local cache, it does not need to send another query to Openstack for cluster's region and AZ info.

Care should be taken to make sure that each cluster's region and AZ in the cluster CRD matches those configured on the corresponding Openstack cluster.

## Resource Collection Flow from Openstack to the ResourceCollector
The resource collector queries Openstack for all clusters' dynamic info in per-region batch request every "query interval". The "query interval" should be configurable with default value being 60 seconds. It should use each cluster's region and AZ from its local cache as the unique identifier of that cluster.

The following requests are pulled every 60 seconds per region

This API will get all the hosts' resource info for a region
hypervisorsPages, err := hypervisors.List(client).AllPages()

This API will extract all the hosts' resource info for the region
hs, err := hypervisors.ExtractHypervisors(hypervisorsPages)

This is the host data structure
type Host struct {
    HostID       string
	UsedVCPUs    int
    UsedMem      int
	TotalVCPUs   int
	TotalMem     int
    ...
}

This API will get all the aggegates' AZ-Host mapping info for a region
aggregatePages, err := aggregates.List(client).AllPages()

This API will extract all the AZ-Host mapping info for the region
aggregates, err:= aggregates.ExtractAggregates(aggregatePages)

This is the aggregate data structure
type Aggregate struct {
       AvailabilityZone string
       Hosts []string //HostID array
}

This API will get all the volume info for the region
allPages, err := schedulerstats.List(client, listOpts).AllPages()

This API will extract all the volume info for the region
allStats, err := schedulerstats.ExtractStoragePools(allPages)
This is the shared volume data structure
type VolumeCapabilities struct {
	ProvisionedCapacityGb    float64
	FreeCapacityGb           float64
	TotalCapacityGb          float64
	VolumeType               string
    ...
}

The following information are only pulled once

This API will get all flavor type info for the region
flasPages, err := flavors.ListDetail(client, flavors.ListOpts{}).AllPages()

This API will extract all the flavor type info for the region
flas, err := flavors.ExtractFlavors(flasPages)

This is the flavor type data structure
type FlavorType struct {
	ID string
	Name string
	Vcpus string
	Ram int64
}

This API will get all volume type info for the region
allPages, err := volumetypes.List(client, volumetypes.ListOpts{}).AllPages()

This API will extract all the volume type info for the region
volumeTypes, err := volumetypes.ExtractVolumeTypes(allPages)

This is the volume type data structure
type VolumeType struct {
       ID string
       Name string
       VolumeBackendName string
}

## Cluster-level Resource Info Construction and Caching Flow Inside the ResourceCollector
After the resource collector gets the response from the batch query, it will construct each cluster's available cpu, memory, storage info and save them into its local cache. Since the available resource info in the Openstack response is per host, the resource collector has to construct per cluster resource info by adding all the hosts' resource info associated with a cluster. In the future we will incoporate an external middleware component that will construct per-AZ granular resource info in the response. Therefore, the resource collector does not need to loop through all the hosts to construct per-AZ resource info, which will improve the resource collector's performance.

Then the resource collector should send all clusters' updated resource info in batch message to the scheduler.

Each time the resource collector gets a new response from the Openstack, the resource collector should compare the latest resource info of a cluster with what was saved in its local cache. If there is a change, it will include that cluster in its batch resource update message to the scheduler. If there is no change, it should not include that cluster in the batch update message.

The following are the cluster resource info data structure

type RegionResource struct {
         RegionName string
         CPUAndMemoryResources map[string]CPUAndMemoryResource //map key is Az
         VolumeReource VolumeReource
}

type CPUAndMemoryResource struct {
	UsedVCPUs    int
    UsedMem      int
	TotalVCPUs   int
	TotalMem     int
    ResourceType string //hardcoded value is "default"
}

type VolumeReource struct {
	ProvisionedCapacityGb    float64
	FreeCapacityGb           float64
	TotalCapacityGb          float64
	VolumeType               string
    MaxOverSubscriptionRatio float64 //hardcoded value is 1
}

## Cluster-level Resource Info Flow from the ResourceCollector to the Scheduler
The following are the http API and message structure.

### Message structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
type SiteResourcesSpec struct {
        	SiteResources	[]SiteResourceSpec
}

type SiteResourceSpec struct {
        	SiteID: string  // region+AZ
        	CPUCapacity   	int64
    	    MemCapacity   	int64
        	Storage 	    []StorageSpec
}
type StorageSpec struct {
    	TypeID          	string   // (sata, sas, ssd)
    	StorageCapacity 	float64
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

### HTTP Rest API
| **Group**   | **API Name**            | **Method** | **Request**                               |
|-------------|-------------------------|------------|-------------------------------------------|
|SiteResource | updateSiteResource      | PATCH      | /globalscheduler/v1/siteresources/update  |

(1) Update SiteResources
-   Method: PATCH

-   Request Path: /globalscheduler/v1/regionresources/{RegionName}

-   Request Parameter:

-   Response:

    -   Normal response codes: 200

    -   Error response codes: 204(No Content) 404(Not Found). Please refer to https://tools.ietf.org/html/rfc5789#section-2.2 for more status codes

-   Example

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Request:
    http://<IP_ADDRESS>:8665/globalscheduler/v1/regionresources/{RegionName}
Body:
    {
        "CPUMemResources": [
            {
                "AvailabilityZone": "West-az1",
                "CpuCapacity": 800,
                "MemCapacity": 128,
            },
            {
                "AvailabilityZone": "West-az2",
                "CpuCapacity": 600,
                "MemCapacity": 256,
            },
            ...
        ],
        "VolumeResources": [
            {
                "TypeId": "sata",
                "StorageCapacity": 1000.00,
            },
            {
                "TypeId": "sas",
                "StorageCapacity": 2000.00,
            },
            {
                "TypeId": "ssd",
                "StorageCapacity": 3000.00,
            },
            ...
        ],

    }

Response:
{
    HTTP/1.1 200 OK
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

## Cluster-level Resource Info Caching Flow Inside the Scheduler
The scheduler should decode the http/gRPC message to get updated clusters' resource information. Note that the http/gRPC message only includes new available resource info for those clusters whose resource has changed from last sync point. It will reconstruct per cluster's flavor count information based on each cluster's latest available cpu/memory. Then it will update its local cache with updated cluster dynamic info.

The scheduler should use a separate thread to handle the interaction with the resource collector. That is, the the thread to handle the interaction with the resoruce collector should be different from the thread of handling the pod request.

The following are the API flow and data structures

### Scheduler APIs
| **Group** | **API Name**            | **Method** | **Request**                                      |
|-----------|-------------------------|------------|--------------------------------------------------|
| Cluster   | registerCluster         | POST       | /globalscheduler/v1/clusters                     |
|           | unregisterClusterById   | DELETE     | /globalscheduler/v1/clusters/id/{cluster_id}     |
|           | unregisterClusterByName | DELETE     | /globalscheduler/v1/clusters/name/{cluster_name} |
|           | listCluster             | GET        | /globalscheduler/v1/clusters                     |
|           | getClusterById          | GET        | /globalscheduler/v1/clusters/id/{cluster_id}     |
|           | getClusterByName        | GET        | /globalscheduler/v1/clusters/name/{cluster_name} |
|-----------|-------------------------|------------|--------------------------------------------------|
| Pod       | addPod                  | POST       | /globalscheduler/v1/pods                         |
|           | deletePodById           | DELETE     | /globalscheduler/v1/pods/id/{pod_id}             |
|           | listPods                | GET        | /globalscheduler/v1/pods/name/{pod_name}         |
|           | getPodById              | GET        | /globalscheduler/v1/pods                         |

### Scheduler Data Structure
(1) Resource’s data structures
•	SiteCacheInfoSnapshot – SiteCacheInfo of all sites
•	SiteCacheInfo – one site’s cache info such as available resources and allocation status
•	SiteTree –This is a map (not a tree structure in spite of the name) of zone (key) sites of a zone

![image.png](/images/SiteCacheInfo.png)

## POD Scheduling Flow Inside the Scheduler
The POD scheduling flow should be as follows. Each step may need to query the scheduler's local cache for each cluster's resource info.
The scheduler should not query the resource collector during this process.
1.
5. run bind plugin
6. update ETCD with the scheduling result for the POD.

repository: CoderKevinZhang/arktos

branch_name: refs/heads/futurewei-cloud-master

gha_language: Go

repo_name: CoderKevinZhang/arktos


text:
# gravapi

Maintainable, production ready web application that provides an API endpoint for transforming email addresses into gravatar uris.

docker version at <https://github.com/flrnprz/gravapi-docker>

## About this repo

This app was developed for learning purposes, inspired in: <https://github.com/honeypotio/challenge/blob/master/tasks/be_001.md>

### Stack

* Node and Express.
* Babel.
* Commander.
* Rollup.
* Jest and Supertest.

### cli

```shell
Options:
  -v, --version       output the version number
  -s, --serve [port]  start the server and bind to [port] (default: 1234)
  -h, --help          output usage information

Examples:
  $ PORT=1337 gravapi-cli             use env variable PORT
  $ gravapi-cli -s                    use default port: 1234
  $ gravapi-cli -s 4321               use custom port: 4321
```

license: MIT

repository: flrnd/gravapi

branch_name: refs/heads/master

extension: md

gha_language: JavaScript

gha_license_id: MIT

license_type: permissive

repo_name: flrnd/gravapi


text:
# Sequential Statistics
Erik-Jan van Kesteren

###[Back to index](../index.html)

## The problem
How do we calculate a sample mean? This is probably one of the most basic questions in statistics, with as its common answer the following: Given a vector of sample values $\bf{x}$ of length $N$, the sample mean $m$ is defined as
\[m = \frac{1}{N}\sum^N_{i=1}x_i\]

But this first assumption, _given a vector of sample values_, recently did not hold for me. The sheer size of the vector that I needed to process made sure it did not fit on my computer. Even worse, I had no way of knowing how big this vector would exactly be! My question was thus: how do I calculate the mean of a stream of sample values of indetermined length?

## Solution
The solution to this was rather simple for calculation of the mean. We initialise the value of the mean to 0, and then _update_ our current guess of the mean with the next value's weighted deviation from the current mean. This happens like so:

\[m_{i} = m_{i-1} + \frac{(x_i-m_{i-1})}{i}\]

Reading the formula in words, the $i^{th}$ mean is the $(i-1)^{th}$ mean plus the deviation of the $i^{th}$ input value from this current mean divided by the current $i$, i.e., the amount of values that have been input.

In code this is extremely simple to implement (click the code button on the right):

```r
set.seed(3665364)
# let's assume we receive data of length 1234
streamlength <- 1234

# initialise m_i
m_i <- 0
for (i in 1:streamlength) {
    m_prev <- m_i
    x_i <- rnorm(1, 0, 3)
    m_i <- m_prev + (x_i - m_prev)/i
}

print(m_i)
```

```
## [1] -0.08489741
```

Note that in the above code we never save the full vector $\bf{x}$; we only ever save the current and previous versions of the mean. This is perfect for an extremely large, variable length input vector such as the one I talked about in the introduction!

```r
set.seed(3665364)
# let's assume we receive data of length 1234
streamlength <- 1234

# initialise m_i
means <- numeric(streamlength)
for (i in 1:streamlength) {
    x_i <- rnorm(1, 0, 3)
    means[i] <- ifelse(i == 1, x_i, means[i - 1] + (x_i - means[i - 1])/i)
}

par(family = "serif")
plot(1:streamlength, means, type = "l", main = "Development of mean over stream",
    xlab = "i", ylab = "Mean", bty = "L", lwd = 1.5)
```

<img src="sequentialstats_files/figure-html/seqplot-1.svg" style="display: block; margin: auto;" />

Notice the big changes at the start of the stream, and the smaller changes at the end, asymptotically converging to the "true" mean value that we set here at 0.

## Bayesian estimation?
We can also see this as a form of bayesian updating, if we turn the formula around like so:

\[m_{i} = \frac{(x_i-m_{i-1}) + i \cdot m_{i-1}}{i}\]

Here, we set the prior to be $i \cdot m_{i-1}$, then we see $(x_i-m_{i-1})$ as our new data/evidence, $m_i$ is our posterior, and $i$ is the normalising constant. Cool!

## Update: More efficient!
The algorithm above translates nicely into the bayesian framework, but as with so many algorithms, it can be made much more efficient. It turns out that all we have to do is remember the `sum` of the values input in the stream and a counter `i` that indicates how many values went in. Then, when asking for the mean, all we need to do is $m_i=\frac{\texttt{sum}}{\texttt{i}}$. Simple!

This is better for three reasons:

1. It's simpler.
2. It's less prone to numerical problems with your computer: you only perform one operation.
3. This also extends to the variance and higher-order moments. For variance, we need to remember the `sum`, the `sum of squares`, and the counter `i`. Then, we can calculate the variance using the formula $Var(X) = E[X^2] - (E[X])^2$ to calculate the variance: $s^2_i=\frac{\texttt{sum of squares}}{\texttt{i}}-\left(\frac{\texttt{sum}}{\texttt{i}}\right)^2$. For each higher order moment, we need to remember a higher power sum in this framework.

Let's do it!

```r
set.seed(3665364)
# let's assume we receive data of length 1234
streamlength <- 1234

# initialise
sum <- 0
sumsq <- 0
i <- 0

for (j in 1:streamlength){
  value <- rnorm(1,0,3)
  sum <- sum + value
  sumsq <- sumsq + value^2
  i <- i+1
}

list(sum = sum,
     sum_of_squares = sumsq,
     i = i,
     mean = sum/i,
     variance = sumsq/i - (sum/i)^2)
```

```
## $sum
## [1] -104.7634
##
## $sum_of_squares
## [1] 11547.45
##
## $i
## [1] 1234
##
## $mean
## [1] -0.08489741
##
## $variance
## [1] 9.35053
```

## The question
For the mean this was simple to implement. The question I'm pondering in the back of my mind throughout all this is the following: can _any_ statistic be transformed into such a sequential statistic? How does this work for variance? Standard deviation? The median / other quantiles? If you let me know, I'll be sure to update this blog post with the additions.

###[Back to index](../index.html)

repository: vankesteren/blog

repo_name: vankesteren/blog


text:
# vuex-undo-redo

A Vue.js plugin that allows you to undo or redo a mutation.

> The building of this plugin is documented in the article *[Create A Vuex Undo/Redo For VueJS](https://vuejsdevelopers.com/2017/11/13/vue-js-vuex-undo-redo/)*

## Live demos

[![Edit Vuex Undo/Redo](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/vjo3xlpyny)

There's also a demo in [this Codepen](https://codepen.io/anthonygore/pen/NwGmqJ). The source code for the demo is [here](https://github.com/anthonygore/vuex-undo-redo-example).

## Installation

```js
npm i --save-dev vuex-undo-redo
```

### Browser

```html
<script type="text/javascript" src="node_modules/vuex-undo-redo/dist/vuex-undo-redo.min.js"></script>
```

### Module

```js
import VuexUndoRedo from 'vuex-undo-redo';
```

## Usage

Since it's a plugin, use it like:

```js
Vue.use(VuexUndoRedo);
```

You must, of course, have the Vuex plugin installed as well, and it must be installed before this plugin. You must also create a Vuex store which must implement a mutation `emptyState` which should revert the store back to the initial state e.g.:

```js
new Vuex.Store({
  state: {
    myVal: null
  },
  mutations: {
    emptyState() {
      this.replaceState({ myval: null });
    }
  }
});
```

### Ignoring mutations

Occasionally, you may want to perform mutations without including them in the undo history (say you are working on an image editor and the user toggles grid visibility - you probably do not want this in undo history). The plugin has an `ignoredMutations` setting to leave these mutations out of the history:

```js
Vue.use(VuexUndoRedo, { ignoreMutations: [ 'toggleGrid' ]});
```

It's worth noting that this only means the mutations will not be recorded in the undo history. You must still manually manage your state object in the `emptyState` mutation:

```js
emptyState(state) {
  this.replaceState({ myval: null, showGrid: state.showGrid });
}
```

## API

### Options

`ignoredMutations` an array of mutations that the plugin will ignore

### Computed properties

`canUndo` a boolean which tells you if the state is undo-able

`canRedo` a boolean which tells you if the state is redo-able

### Methods

`undo` undoes the last mutation

`redo` redoes the last mutation

repository: andy-jqli/vuex-undo-redo

repo_name: andy-jqli/vuex-undo-redo


text:
VT_CACHE_LINE_SIZE
==================

- Defined in header `<vt/ndarray/allocator.hpp>`
- Defined in header `<vt/ndarray.hpp>`

```c++
#ifndef VT_CACHE_LINE_SIZE
#   define VT_CACHE_LINE_SIZE 64
#endif
```

Unsigned integer value representing the cache-line size in bytes. This is used by `vt::ndarray_allocator` when determining a default alignment for allocations.

While the cache-line size can vary per machine, in practice the vast majority of modern systems have a cache-line size of 64 bytes. If 64 is not the correct value for your target hardware, you can override it by defining this macro to your desired value before including this library.

repository: vortechbv/vt-ndarray

repo_name: vortechbv/vt-ndarray


text:
The following notation is a simplified version of the syntax found in
`./dhall.abnf`.  This simplified notation is used for all of the following
judgments:

```
m, n = 0 / 1 + n  ; Natural numbers

d = ±n            ; Integers

x, y              ; Variables

; Mnemonics for the most commonly used labels:
;
; Terms are lowercase:
;
;     a    = input term whose type is "A"
;     b    = output term whose type is "B"
;     f    = "f"unction
;     l, r = "l"eft and "r"ight term that share the same type
;     e    = term whose type is "E"
;     t    = term whose type is "T"
;     u    = term whose type is "U"
;
; Types are uppercase:
;
;     A  = type of the input term "a"
;     B  = type of the output term "b"
;     E  = type of the term "e"
;     T  = type of the term "t"
;     U  = type of the term "u"
;
; Constants that are `Type`, `Kind`, or `Sort` are lowercase:
;
;     c = "c"onstant
;     i = function's "i"nput type
;     o = function's "o"utput type
;
; Similar terms are distinguished by subscripts like `a₀`, `a₁`, …
;
; A term that represents zero or more values or key-value pairs ends with `s…`,
; such as `as…`
;
; Note that these are only informal mnemonics.  Dhall is a pure type system,
; which means that many places in the syntax permit terms, types, kinds, and
; sorts. The typing judgments are the authoritative rules for what expressions
, are permitted and forbidden.
a, b, f, l, r, e, t, u, A, B, E, T, U, c, i, o
  = x@n                               ; Identifier
                                      ; (`x` is short-hand for `x@0`)
  / λ(x : A) → b                      ; Anonymous function
  / ∀(x : A) → B                      ; Function type
                                      ; (`A → B` is short-hand for `∀(_ : A) → B`)
  / let x : A = a in b                ; Let expression with type annotation
  / let x     = a in b                ; Let expression without type annotation
  / if t then l else r                ; if-then-else expression
  / merge t u : T                     ; Union elimination with type annotation
  / merge t u                         ; Union elimination
  / toMap t : T                       ; Conversion to a map with type annotation
  / toMap t                           ; Conversion to a map
  / [] : T                            ; Empty list literals with type annotation
  / [ t, ts… ]                        ; Non-empty list literals
  / t : T                             ; Type annotation
  / l || r                            ; Boolean or
  / l + r                             ; Natural addition
  / l ++ r                            ; Text append
  / l # r                             ; List append
  / l && r                            ; Boolean and
  / l ∧ r                             ; Recursive record merge
  / l ⫽ r                             ; Non-recursive right-biased record merge
  / l ⩓ r                             ; Recursive record type merge
  / l * r                             ; Natural multiplication
  / l == r                            ; Boolean equality
  / l != r                            ; Boolean inequality
  / l === r                           ; Equivalence (using ASCII to avoid
                                      ; confusion with the equivalence judgment)
  / f a                               ; Function application
  / t.x                               ; Field selection
  / t.{ xs… }                         ; Field projection
  / t.(s)                             ; Field projection by type
  / T::r                              ; Record completion
  / assert : T                        ; Assert judgemental equality
  / e with k.ks… = v                  ; Nested record update
  / n.n                               ; Double-precision floating point literal
  / n                                 ; Natural number literal
  / ±n                                ; Integer literal
  / "s"                               ; Uninterpolated text literal
  / "s${t}ss…"                        ; Interpolated text literal
  / YYYY-MM-DD                        ; Date
  / hh:mm:ss                          ; Time
  / ±HH:MM                            ; Time zone
  / {}                                ; Empty record type
  / { k : T, ks… }                    ; Non-empty record type
  / {=}                               ; Empty record literal
  / { k = t, ks… }                    ; Non-empty record literal
  / <>                                ; Empty union type
  / < k : T | ks… >                   ; Union type with at least one non-empty
                                      ; alternative
  / < k | ks… >                       ; Union type with at least one empty
                                      ; alternative
  / showConstructor t                 ; Union to Text elimination
  / missing                           ; Identity for import alternatives,
                                      ; will always fail to resolve
  / l ? r                             ; Alternative imports resolution
  / https://authority directory file  ; URL import
  / directory file                    ; Absolute file path import
  / . directory file                  ; Relative file path import
  / .. directory file                 ; Relative file path import
  / ~ directory file                  ; Home-anchored file path import
  / env:x                             ; Environment variable import
  / Some a                            ; Constructor for a present Optional value

                                      ; Reserved identifiers for builtins
  / Natural/build                     ; Natural introduction
  / Natural/fold                      ; Natural elimination
  / Natural/isZero                    ; Test if zero
  / Natural/even                      ; Test if even
  / Natural/odd                       ; Test if odd
  / Natural/toInteger                 ; Convert Natural to Integer
  / Natural/show                      ; Convert Natural to Text representation
  / Natural/subtract                  ; Perform truncated subtraction on two Naturals
  / Integer/toDouble                  ; Convert Integer to Double
  / Integer/show                      ; Convert Integer to Text representation
  / Integer/negate                    ; Invert sign of Integers, with positive
                                      ; values becoming negative and vice-versa
  / Integer/clamp                     ; Convert Integer to Natural by clamping
                                      ; negative values to zero
  / Date/show                         ; Convert Date to Text representation
  / Double/show                       ; Convert Double to Text representation
  / List/build                        ; List introduction
  / List/fold                         ; List elimination
  / List/length                       ; Length of list
  / List/head                         ; First element of list
  / List/last                         ; Last element of list
  / List/indexed                      ; Tag elements with index
  / List/reverse                      ; Reverse list
  / Text/show                         ; Convert Text to its own representation
  / Text/replace                      ; Replace a section of a Text literal
  / Time/show                         ; Convert Time to Text representation
  / TimeZone/show                     ; Convert TimeZone to Text representation
  / Bool                              ; Bool type
  / Optional                          ; Optional type
  / Natural                           ; Natural type
  / Integer                           ; Integer type
  / Double                            ; Double type
  / Text                              ; Text type
  / Bytes                             ; Bytes type
  / List                              ; List type
  / True                              ; True term
  / False                             ; False term
  / None                              ; Absent Optional value
  / Type                              ; Type of terms
  / Kind                              ; Type of types
  / Sort                              ; Type of kinds
```

```haskell
{-| This module contains the data types used to represent the syntax tree for
    a Dhall expression
-}

module Syntax
    ( -- * Types
      Expression(..)
    , Operator(..)
    , TextLiteral(..)
    , Builtin(..)
    , Constant(..)
    , ImportMode(..)
    , ImportType(..)
    , URL(..)
    , Scheme(..)
    , FilePrefix(..)
    , File(..)
    , PathComponent(..)

      -- * Re-exports
    , Natural
    , Text
    ) where

import Crypto.Hash (Digest, SHA256)
import Data.ByteString (ByteString)
import Data.List.NonEmpty (NonEmpty)
import Data.Text (Text)
import Numeric.Natural (Natural)

import qualified Data.Time as Time

-- | Top-level type representing a Dhall expression
data Expression
    = Variable Text Natural
      -- ^ > x@n
    | Lambda Text Expression Expression
      -- ^ > λ(x : A) → b
    | Forall Text Expression Expression
      -- ^ > ∀(x : A) → B
    | Let Text (Maybe Expression) Expression Expression
      -- ^ > let x : A = a in b
      --   > let x     = a in b
    | If Expression Expression Expression
      -- ^ > if t then l else r
    | Merge Expression Expression (Maybe Expression)
      -- ^ > merge t u : T
      -- ^ > merge t u
    | ToMap Expression (Maybe Expression)
      -- ^ > toMap t : T
      -- ^ > toMap t
    | EmptyList Expression
      -- ^ > [] : T
    | NonEmptyList (NonEmpty Expression)
      -- ^ > [ t, ts… ]
    | Annotation Expression Expression
      -- ^ > t : T
    | Operator Expression Operator Expression
      -- ^ > l □ r
    | Application Expression Expression
      -- ^ > f a
    | Field Expression Text
      -- ^ > t.x
    | ProjectByLabels Expression [Text]
      -- ^ > t.{ xs… }
    | ProjectByType Expression Expression
      -- ^ > t.(s)
    | Completion Expression Expression
      -- ^ > T::r
    | Assert Expression
      -- ^ > assert : T
    | With Expression (NonEmpty PathComponent) Expression
      -- ^ > e with k.ks… = v
    | DoubleLiteral Double
      -- ^ > n.n
    | NaturalLiteral Natural
      -- ^ > n
    | IntegerLiteral Integer
      -- ^ > ±n
    | TextLiteral TextLiteral
      -- ^ > "s"
      --   > "s${t}ss…"
    | BytesLiteral ByteString
      -- ^ > 0x"abcdef0123456789"
    | DateLiteral Time.Day
    | TimeLiteral
        Time.TimeOfDay
        Int
        -- ^ Precision
    | TimeZoneLiteral Time.TimeZone
    | RecordType [(Text, Expression)]
      -- ^ > {}
      --   > { k : T, ks… }
    | RecordLiteral [(Text, Expression)]
      -- ^ > {=}
      --   > { k = t, ks… }
    | UnionType [(Text, Maybe Expression)]
      -- ^ > <>
      --   > < k : T | ks… >
      --   > < k | ks… >
    | ShowConstructor Expression
      -- ^ > showConstructor t
    | Import ImportType ImportMode (Maybe (Digest SHA256))
    | Some Expression
      -- ^ > Some s
    | Builtin Builtin
    | Constant Constant
    deriving (Show)

-- | Associative binary operators
data Operator
    = Or                  -- ^ > ||
    | Plus                -- ^ > +
    | TextAppend          -- ^ > ++
    | ListAppend          -- ^ > #
    | And                 -- ^ > &&
    | CombineRecordTerms  -- ^ > ∧
    | Prefer              -- ^ > ⫽
    | CombineRecordTypes  -- ^ > ⩓
    | Times               -- ^ > *
    | Equal               -- ^ > ==
    | NotEqual            -- ^ > !=
    | Equivalent          -- ^ > ===
    | Alternative         -- ^ > ?
    deriving (Show)

{-| Data structure used to represent an interpolated @Text@ literal

    A @Text@ literal without any interpolations has an empty list.  For example,
    the @Text@ literal @\"foo\"@ is represented as:

    > TextLiteral [] "foo"

    A @Text@ literal with interpolations has one list element per interpolation.
    For example, the @Text@ literal @\"foo${x}bar${y}baz\"@ is represented as:

    > TextLiteral [("foo", Variable "x" 0), ("bar", Variable "y" 0)] "baz"
-}
data TextLiteral = Chunks [(Text, Expression)] Text
    deriving (Show)

-- | This instance comes in handy for implementing @Text@-related operations
instance Semigroup TextLiteral where
    Chunks xys₀ z₀ <> Chunks [] z₁ =
        Chunks xys₀ (z₀ <> z₁)
    Chunks xys₀ z₀ <> Chunks ((x₁, y₁) : xys₁) z₁ =
        Chunks (xys₀ <> ((z₀ <> x₁, y₁) : xys₁)) z₁

-- | This instance comes in handy for implementing @Text@-related operations
instance Monoid TextLiteral where
    mempty = Chunks [] ""

-- | Builtin values
data Builtin
    = DateShow
    | DoubleShow
    | IntegerClamp
    | IntegerNegate
    | IntegerShow
    | IntegerToDouble
    | ListBuild
    | ListFold
    | ListHead
    | ListIndexed
    | ListLast
    | ListLength
    | ListReverse
    | NaturalBuild
    | NaturalEven
    | NaturalFold
    | NaturalIsZero
    | NaturalOdd
    | NaturalShow
    | NaturalSubtract
    | NaturalToInteger
    | TextReplace
    | TextShow
    | TimeShow
    | TimeZoneShow
    | Bool
    | Bytes
    | Date
    | Double
    | False
    | Integer
    | List
    | Natural
    | None
    | Optional
    | Text
    | Time
    | TimeZone
    | True
    deriving (Show)

-- | Type-checking constants
data Constant
    = Type
    | Kind
    | Sort
    deriving (Eq, Ord, Show)

-- | How to interpret the path to the import
data ImportMode
    = Code      -- ^ The default behavior: import the path as code to interpret
    | RawBytes  -- ^ @as Bytes@: import the path as raw bytes
    | RawText   -- ^ @as Text@: import the path as raw text
    | Location  -- ^ @as Location@: don't import and instead represent the path
                --   as a Dhall expression
    deriving (Show)

-- | Where to locate the import
data ImportType
    = Missing
        -- ^ > missing
    | Remote URL (Maybe Expression)
        -- ^ > https://authority directory file using headers
    | Path FilePrefix File
        -- ^ > /directory/file
        --   > ./directory/file
        --   > ../directory/file
        --   > ~/directory/file
    | Env Text
        -- ^ > env:x
    deriving (Show)

-- | Structured representation of an HTTP(S) URL
data URL = URL
    { scheme    :: Scheme
    , authority :: Text
    , path      :: File
    , query     :: Maybe Text
    }
    deriving (Show)

-- | The URL scheme
data Scheme
    = HTTP  -- ^ > http:\/\/
    | HTTPS -- ^ > https:\/\/
    deriving (Show)

-- | The anchor for a local filepath
data FilePrefix
    = Absolute  -- ^ @/@, an absolute path
    | Here      -- ^ @.@, a path relative to the current working directory
    | Parent    -- ^ @..@, a path relative to the parent working directory
    | Home      -- ^ @~@, a path relative to the user's home directory
    deriving (Show)

{-| Structured representation of a file path

    Note that the directory path components are stored in reverse order,
    meaning that the path @/foo\/bar\/baz@ is represented as:

    > File{ directory = [ "bar", "foo" ], file = "baz" }
-}
data File = File
    { directory :: [Text]  -- ^ Directory path components (in reverse order)
    , file :: Text         -- ^ File name
    }
    deriving (Show)

data PathComponent
    = Label Text
    | DescendOptional
    deriving (Show)
```

repository: dhall-lang/dhall-lang

gha_language: Dhall

repo_name: dhall-lang/dhall-lang


text:
---
title: "Mapping Stats Canada Data with R part 1 of 3"
layout: post
tags: [web scraping, python, BeautifulSoup, Stats Canada]
output: html_document
---
#Introduction
I applied to the [Insight data science program](http://insightdatascience.com/) pretty much immediately after I finished my phD in September. I didn't have much programming experience (still don't) but I was learning R and wanted to do something to showcase what I had learnt. I settled on doing a map of the densities of the different ethnic groups in Canada by census division. I just thought it would be interesting to see where different immigrant communities settle.

There were three basic parts to this project.

1. Get the data from Stats Canada. This was not one simple download. I used [BeautifulSoup](http://www.crummy.com/software/BeautifulSoup/) to scrape the Stats Canada web site.
2. Organize and combine the data along with the actual mapping. This was some simple R code along with learning a little bit of [ggmaps](http://cran.r-project.org/web/packages/ggmap/ggmap.pdf)
3. Construct an interactive map online. I used the [Shiny](http://shiny.rstudio.com/) web application framework for R for this.

Three different parts to that project add up to three different parts to this post.

#Part 1 - Web Scraping Stats Canada

I went to [the Stats Canada web site](http://www.statcan.gc.ca/start-debut-eng.html) to look for this data. Unfortunately the long form census was discontinued in 2011, so I had to rely on the 2006 census. I focused on the ethnic characteristics of the questionnaire. This is a [link](http://www12.statcan.gc.ca/census-recensement/2006/dp-pd/tbt/Rp-eng.cfm?LANG=E&APATH=3&DETAIL=0&DIM=0&FL=A&FREE=0&GC=0&GID=0&GK=0&GRP=1&PID=99015&PRID=0&PTYPE=88971,97154&S=0&SHOWALL=0&SUB=0&Temporal=2006&THEME=70&VID=0&VNAMEE=&VNAMEF=) to the stats that I was looking at aggregated over all of Canada. I wanted the data for each census division which for some reason Stats Canada did not make available as one single download. I would have had to click through each division [here][censusdivisions] in order to retrieve all the data. So of course what I did instead was I scraped the data from that page using python, regular expressions, and BeautifulSoup.

{% highlight python %}
import urllib
from bs4 import BeautifulSoup, SoupStrainer
import re
import os
{% endhighlight %}

I started at the [base page][censusdivisions] and took a look at the html code to see what all the census division links had in common. All the links had tags 'li'. The provinces were of class 'indent-1', the census divisions were of class, "indent-3", and the subdivisions were of class 'indent-5'. And the links are listed in inherited order - provinces -> divisions -> subdivisions. I'm interested in the census divisions along with the provinces (just as placeholders).

I found parsing the page a bit buggy. I had to use the "html5lib" parser to get all the links.

{% highlight python %}
#the base page
url = "http://www12.statcan.gc.ca/census-recensement/2006/dp-pd/tbt/Geo-index-eng.cfm?TABID=5&LANG=E&APATH=3&DETAIL=0&DIM=0&FL=A&FREE=0&GC=0&GID=0&GK=0&GRP=1&PID=99015&PRID=0&PTYPE=88971,97154&S=0&SHOWALL=0&SUB=0&Temporal=2006&THEME=70&VID=0&VNAMEE=&VNAMEF=&D1=0&D2=0&D3=0&D4=0&D5=0&D6=0"

#get the links
soup = BeautifulSoup(requests.get(url).content, "html5lib")
links = soup.find_all("li", class_ = re.compile('indent-[1|3]'))
{% endhighlight %}

I still wasn't there yet. These links just take me to another page where I have the option to click on a link to download the csv files. But I noticed that these new links are of the form begin + PID + "&"" + GID +end, where begin and end are some fixed string and PID and GID are information contained in the link. So I wrote a function to extract the link to download the csv files from the first link.

{% highlight python %}
def get_csv_link(weblink):
    #extract the pid and gid from the link
    PID = re.search("PID=\d+", weblink).group()
    GID = re.search("GID=\d+", weblink).group()
    #construct link to the csv file
    begin = "http://www12.statcan.gc.ca/census-recensement/2006/dp-pd/tbt/File.cfm?S=0&LANG=E&A=R&"
    end = "&D1=0&D2=0&D3=0&D4=0&D5=0&D6=0&OFT=CSV"
    return begin + PID + '&' + GID + end
{% endhighlight %}

Now I just retrieve a dictionary of dictionaries of urls. First level is the name of the province, second level is name of the census division and the final level is url of the csv for that division. This structure helps keep things organized.

{% highlight python %}
list_divs = {}
province = ''
for link in links[1:]: #skip first link Canada
    if (link['class'][0] == 'indent-1'):
        province = re.sub(" /.+", "", link.a.string) #removes french name and /
    else if (link['class'][0] == 'indent-3'):
        if (province != ''):
            list_divs[province][re.sub(" /.+", "", link.a.string)] =
                get_csv_link(link.a['href'])
{% endhighlight %}

The last thing to do is to take this structure and use it to download the csv files into the right folders. For each province I make a folder and put all the census division files of that province in that folder.

{% highlight python  %}
for province in list_divs.keys():
    os.mkdir(province)
    for division in x[province]:
        urllib.urlretrieve(list_divs[province][division], province + "/" + division+".csv")
{% endhighlight %}

Next up: cleaning and combing the csv files to get data I can map

[censusdivisions]: http://www12.statcan.gc.ca/census-recensement/2006/dp-pd/tbt/Geo-index-eng.cfm?TABID=5&LANG=E&APATH=3&DETAIL=0&DIM=0&FL=A&FREE=0&GC=0&GID=0&GK=0&GRP=1&PID=99015&PRID=0&PTYPE=88971,97154&S=0&SHOWALL=0&SUB=0&Temporal=2006&THEME=70&VID=0&VNAMEE=&VNAMEF=&D1=0&D2=0&D3=0&D4=0&D5=0&D6=0


text:
The golang implementation of acous

## Introduction
----
dir **commom** include the web request of this algorithm.
dir **web** include the configuration, api, handler, implement of this algorithm.

## Usage
----
Use `go build main.go` generate main(main.exe in windows), put main(main.exe in windows) and conf.yml in a same dir, modify conf.yml to the real world set, and run `sudo ./main -log %log file path%` in each node, request the source node with json string like.
```
{
	"source_url" : "http://<IP_ADDRESS>:8000",
	"work_chain": "2-3-4-5-6-7"
}
```
source_url is the source of the ant, work_chain is all the dest you want to find.
Or use source code in each node, and `go run main.go -log %log file path%`, and the same with above.


text:
# Angular Star Rating ⭐⭐⭐⭐⭐
#### ⭐ Angular Component written in typescript, based on css only techniques. ⭐

![License](https://img.shields.io/npm/l/angular-star-rating.svg)
![Bower Version](https://img.shields.io/bower/v/angular-star-rating.svg)
[![NPM Version](https://img.shields.io/npm/v/angular-star-rating.svg)](https://www.npmjs.com/package/angular-star-rating)
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/BioPhoton/angular-star-rating)

[![NPM](https://img.shields.io/npm/dt/angular-star-rating.svg)](https://www.npmjs.com/package/angular-star-rating)

[![NPM](https://nodei.co/npm/angular-star-rating.png?downloads=true&downloadRank=true&stars=true)](https://npmjs.org/angular-star-rating)
[![NPM](https://nodei.co/npm-dl/angular-star-rating.png?height=3&months=9)](https://npmjs.org/angular-star-rating)

[![Package Quality](http://npm.packagequality.com/badge/angular-star-rating.png)](http://packagequality.com/#?package=angular-star-rating)

Angular Star Rating is a >2 Angular component written in typescript.
It is based on [css-sar-rating](https://github.com/BioPhoton/css-star-rating), a fully featured and customizable css only star rating component written in scss.

## DEMO
![alt tag](https://raw.githubusercontent.com/BioPhoton/angular-star-rating/master/resources/examples/example-usage.gif)

##Related Projects

| Css | Angular1 (>=1.5)| Angular (>=2) |
|---  |---	    |--- 	       |
|  |  |  |
| [Css Star Rating](https://github.com/BioPhoton/css-star-rating) | [Angular1 Star Rating](https://github.com/BioPhoton/angular1-star-rating) | [Angular Star Rating](https://github.com/BioPhoton/angular-star-rating) |

## Features
This module implements all Features from [CSS-STAR-RATING](https://github.com/BioPhoton/css-star-rating).
It also provides callbacks for all calculation functions used in the component as well as all possible event emitters.

- [x] **id** - The html id attribute of the star rating
- [x] **rating** -  The actual Star rating
- [x] **showHalfStars** - To display half stars or not
- [x] **numOfStars** - The max number of stars you can rate
- [x] **size** - The different sizes of the component
- [x] **spread** - Stars are spreaded over whole width or not
- [x] **color** - A static color for the stars
- [x] **disabled** - Component is in disabled mode
- [x] **starType** - Stars can be displayed as svg, character or icon-font like fontawesome, glyphicons or ionicons
- [x] **text** - The value of the label text
- [x] **labelPosition** - The position of the label
- [x] **speed** - The duration of the animation
- [x] **direction** - The direction of the component i.e. right to left
- [x] **readOnly** - Click event is disabled
- [x] **getColor** - Custom function to calculate the color for a rating
- [x] **getHalfStarVisible** - Custom function to calculate value for displaying half stars or not
- [x] **onClick** - Hook for Click action
- [x] **onRatingChange** - Hook for onRatingChange event

## Browser support

| IE | Firefox | Chrome | Safari | Opera |
|--- |---	   |--- 	|---	 |---|
| >11  	|  >50 	|   >55	|  >10 	|   >41	|
| 	|  |   |   |  |

## Install

**Get Angular Star Rating:**
 - clone & build this repository
 - [download as .zip](https://github.com/BioPhoton/angular-star-rating/releases)
 - via **[npm](https://www.npmjs.org/)**: by running `$ npm install angular-star-rating` from your console
 - via **[bower](https://bower.io/)**: by running `$ bower install angular2-star-rating` from your console

**Load library**
```html
<script src="[bower or npm folder]/angular-star-rating/dist/index.js"></script>
```

**Register module**
```javascript
...
import { StarRatingModule } from 'path/to/star/rating/star-rating.module';
...
@NgModule({
  ...
  imports: [
    ...
    StarRatingModule
    ...
  ]
  ...
})
export class AppModule { }
```

**Use it**
```html
<star-rating-comp
         [size]="'large'"
         [rating]="3"
         [text]="'Rating:'"
         (onRatingChange)="crtl.onRatingChange($event)">
 </star-rating-comp>
```

## Component Properties

### Inputs

**id**: string (Optional)
The html id attribute of the star rating
Default: undefined

```html
<star-rating-comp [id]="'my-id'"></star-rating-comp>
```

**rating**: number (Optional)
The actual star rating value
Default: no

```html
<star-rating-comp [rating]="3"></star-rating-comp>
```

**showHalfStars**: boolean (Optional)
To show half stars or not
Options: true, false
Default: false

```html
<star-rating-comp [showHalfStars]="true"></star-rating-comp>
```

**numOfStars**: number (Optional)
The possible number of stars to choose from
Default: 5

```html
<star-rating-comp [numOfStars]="6"></star-rating-comp>
```

**text**: string (Optional)
The text next to the stars.
Default: undefined

```html
<star-rating-comp [text]="'My text!'"></star-rating-comp>
```

**labelPosition**: starRatingPosition (Optional)
The position of the label
Options: top, right, bottom, left
Default: left

```html
<star-rating-comp [labelPosition]="'top'"></star-rating-comp>
```

**spread**: boolean (Optional)
If the start use the whole space or not.
Default: false

```html
<star-rating-comp [space]="true"></star-rating-comp>
```

**size**: starRatingSizes (Optional)
The height and width of the stars.
Options: small, medium, large
Default: middle

```html
<star-rating-comp [size]="'small'"></star-rating-comp>
```

**color**: starRatingColors (Optional)
Possible color names for the stars.
Options: default, negative, middle, positive
Default: undefined

```html
<star-rating-comp [color]="'positive'"></star-rating-comp>
```

**disabled**: boolean (Optional)
The click callback is disabled, colors are transparent
Default: false

```html
<star-rating-comp [disabled]="true"></star-rating-comp>
```

**direction**: string (Optional)
The direction of the stars and label.
Options: rtl, ltr
Default: rtl

```html
<star-rating-comp [direction]="'ltr'"></star-rating-comp>
```

**readOnly**: boolean (Optional)
The click callback is disabled
Default: false

```html
<star-rating-comp [readOnly]="true"></star-rating-comp>
```

**speed**: starRatingSpeed (Optional)
The duration of the animation in ms.
Options: immediately, noticeable, slow
Default: noticeable

```html
<star-rating-comp [speed]="'slow'"></star-rating-comp>
```

**starType**: starRatingStarTypes (Optional)
The type of start resource to use.
Options: svg, icon
Default: svg

```html
<star-rating-comp [starType]="'icon'"></star-rating-comp>
```

**getColor**: Function (Optional)
Calculation of the color by rating.
Params: rating, number,numOfStars and staticColor
Return: color name

```html
<star-rating-comp [getColor]="ctrl.getColor(rating, numOfStars, staticColor)"></star-rating-comp>
```

**getHalfStarVisible**: Function (Optional)
Calculation for adding the "half" class or not, depending on the rating value.
Params: rating
Return: boolean

```html
<star-rating-comp [getHalfStarClass]="ctrl.getHalfStarClass(rating)" rating="3.2"></star-rating-comp>
```

### Outputs

**onClick**: Function (Optional)
Callback function for star click event
Params: $event
```html
<star-rating-comp (onClick)="ctrl.onClick($event)"></star-rating-comp>
```

**onRatingChange**: Function (Optional)
Callback function for rating change event
Params: $event
```html
<star-rating-comp (onRatingChange)="ctrl.onRatingChange($event)"></star-rating-comp>
```

repository: nithishpeddi/MEAN-STACK

repo_name: nithishpeddi/MEAN-STACK


text:
---
layout: post
section-type: post
title: Iran - Intro
category: Travel
tags: [ 'Iran' ]
---
It's been a while, but I'm back with another set of travel blogs. I've taken a couple of
trips since Easter Island, but mostly to more "vanilla" places that I didn't bother writing up.
This trip is definitely worth blogging though - these posts document my trip to Iran in March of 2019!

Long-time readers of this blog (do those exist?) will know that this was my second attempt at visiting the country. I had tried going in
[Spring 2017]({{ "/travel/2017/03/22/WayToHK1.html" | prepend: site.baseurl}}),
but was foiled by the inconvenient election and subsequent actions of a Mr. Donald J. Trump.
Spoiler alert: second time's the charm! This time, I was traveling with Richard, hereinafter referred to as Dore, a friend from work.
As with previous series, these will mostly be a collection of funny stories, interesting happenings, and thoughts about the country, and less a play-by-play.
Though I may make an effort to give more travel advice than usual though, given how comparatively little info there is about traveling to Iran.

### Background

Iran had been high on my travel bucket list for a while before this trip finally happened.
A couple of things about the country that I think make it particularly worth visiting / interesting:
+ It's one of four U.N. member nations that we don't have diplomatic relations with / is often considered an enemy of the U.S. George Bush famously included it in his
[Axis of Evil](https://en.wikipedia.org/wiki/Axis_of_evil)
as part of his 2002 SOTU.
+ It's been in the news a lot recently due to its nuclear aspirations / worldwide attempts to stop them
+ Its 1979 Islamic Revolution was a shock to the world, and represented a huge change for a country that previously was one of the most liberal in the Middle East. See
[here](https://www.businessinsider.com/iran-before-the-revolution-in-photos-2015-4)
for example.
+ It's the modern day successor of the various Persian Empires / has quite a lot of history (e.g. Xerxes of 300 fame).

### Getting There

Several people have expressed surprise that Americans are even allowed to visit Iran.
Aside from previously mentioned periods of reciprocal banning, we are able to visit as tourists. But, one must go with an officially-sanctioned tour group and guide. This requirement also applies to the Canada and UK. Our company of choice was
[Key2Persia](https://en.key2persia.com/home)
which seemed to have the most favorable reviews on the interwebs. More about them later.

The visa application process started uneventfully, though strangely they required us to send in our resumes. It was my first time updating mine since starting at Jane Street!
I think this is to catch journalists, revolutionaries, and such? I saw some bad stories on the internet about folks working for BBC-affiliated TV series being denied.
Regardless, after some delay, first I then Dore received the all important invitation code from the MFA (Ministry of Foreign affairs).
This is a sort-of pre-approval, after which actually getting the visa is usually a formality. The next and final step was sending our passports to the "Interests Section of the Islamic Republic of Iran in the United States." This is located at the Pakistani embassy, as there hasn't been an Iranian embassy since our countries had a little diplomatic
[spat](https://en.wikipedia.org/wiki/Iran_hostage_crisis)
in 1979.
We received these codes around the 2018 holiday season, so it took us a bit of time to get our passports sent in.
Then, in early February, I received a call from a mysterious number. Googling it revealed that it came from the Pakistani Embassy...this was not a good sign.
And indeed, it turned out we needed to apply for our visas within 30 days of receiving the authorization code. Including the time taken sending in our application, I missed it by something like a single day.
Irritatingly, our tour company had not known about this constraint / told us about it. So, I remained in visa limbo for quite a while, as our they tried to reapply for my authorization code. Given that it'd taken 40+ days the first time, I wasn't particularly optimistic that things were going to work out.
And of course with my luck, the days after I found this out were the 40th anniversary of the Islamic Revolution. This was sort of nice as its resulted in some interesting coverage in the Western news media of the Revolution and its effects. But of course, all governmental offices in Iran were closed for several days.
Thankfully the story has a happy ending, as just two weeks later my visa was reauthorized, and I received my passport in the mail soon after.

The actual business of flying there was more straightforward. We booked an open-jaw itinerary on Qatar Airways flying into Tehran and out of Shiraz, transiting in Doha both ways.


text:
# Learning Clojure with Immutant
A tutorial for learning the Clojure language through the creation of a web application for Immutant.

## Goals

The overall goal is to give the reader enough of an understanding of both Clojure and Immutant to build basic web
applications with confidence. It won't teach you everything about either ecosystem, but hopefully will provide the
necessary foundations. It is assume that the reader has a few years of programming experience with something like
Python or Ruby, but may not have a lot of experience with functional programming ideas. The ideas will be introduced
as needed with pointers to more in-depth material.

## Dependencies

* Clojure v1.6.0
* Leiningen v2.5.1
* Immutant v2.0.0beta2
* IntelliJ v14.1 Community Edition w/Cursive

## Proposed Table-of-Contents

1. Installing Dependencies
2. Tour of Tooling
3. Starting a Clojure Project
4. Hello World

repository: petrilli/learning-clojure-immutant

repo_name: petrilli/learning-clojure-immutant


text:
# nkn-sdk-flutter
## Usage
### install
```dart
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Wallet.install();
  Client.install();
  runApp(MyApp());
}
```

### Wallet

Create wallet:

```dart
Wallet wallet = await Wallet.create(null, config: WalletConfig(password: '123'));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);
```

Export wallet to JSON string, where sensitive contents are encrypted by password provided in config:

```dart
wallet.keystore;
```

By default the wallet will use RPC server provided by nkn.org. Any NKN full node can serve as a RPC server. To create a wallet using customized RPC server:

```dart
Wallet wallet = await Wallet.create(null, config: WalletConfig(password: '123', seedRPCServerAddr: ['http://seed.nkn.org:30003']));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);
```

Load wallet from JSON string, note that the password needs to be the same as the one provided when creating wallet:

```dart
Wallet wallet = await Wallet.restore(w.keystore,
    config: WalletConfig(password: '123'));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);

```

Query asset balance for this wallet:

```dart
double balance = await wallet.getBalance();
```

Transfer asset to some address:

```dart
String txHash = await wallet.transfer(NKN_ADDRESS, '1.23');
```

### Client

NKN Client provides low level p2p messaging through NKN network.

Create a client with a generated key pair:

 ```dart
var client = await Client.create(WALLET_SEED);
```

Listen for connection established:

```dart
client.onConnect.listen((event) {
    print(event.node);
});
```

Receive data from other clients

```dart
client.onMessage.listen((event) {
    print(event.type);
    print(event.encrypted);
    print(event.messageId);
    print(event.data);
    print(event.src);
});
```

Send text message to other clients

```dart
await client.sendText([CLIENT_ADDRESS], jsonEncode({'contentType': 'text', 'content': 'Hello'}));
```

publish a message to a specified topic (see wallet section for subscribing to topics):

```dart
await client.publishText(TOPIC, jsonEncode({'contentType': 'text', 'content': 'Hello'}));
```

Pub/Sub

```dart
var res = await client.subscribe(topic: TOPIC);
var res = await client.unsubscribe(topic: TOPIC);
var res = await client.getSubscribersCount(topic: TOPIC);
var res = await client.getSubscription(topic: TOPIC, subscriber: CLIENT_ADDRESS);
```

repository: iheron/nMobile

repo_name: iheron/nMobile


text:
---
title: OpenTelemetry support
keywords: build, buildx buildkit, opentelemetry
---

Both Buildx and BuildKit support [OpenTelemetry](https://opentelemetry.io/).

To capture the trace to [Jaeger](https://github.com/jaegertracing/jaeger),
set `JAEGER_TRACE` environment variable to the collection address using a
`driver-opt`.

First create a Jaeger container:

```console
$ docker run -d --name jaeger -p "6831:6831/udp" -p "16686:16686" --restart unless-stopped jaegertracing/all-in-one
```

Then [create a `docker-container` builder](../drivers/docker-container.md)
that will use the Jaeger instance via the `JAEGER_TRACE` env var:

```console
$ docker buildx create --use \
  --name mybuilder \
  --driver docker-container \
  --driver-opt "network=host" \
  --driver-opt "env.JAEGER_TRACE=localhost:6831"
```

Boot and [inspect `mybuilder`](../../engine/reference/commandline/buildx_inspect.md):

```console
$ docker buildx inspect --bootstrap
```

Buildx commands should be traced at `http://<IP_ADDRESS>:16686/`:

![OpenTelemetry Buildx Bake](../images/opentelemetry.png)

repository: docker/docs

branch_name: refs/heads/main

gha_language: HTML

repo_name: docker/docs


text:
Setting up Development VM
-------------------------

Use CentOS 7 - minimal as the VM base
specify 2 network adapters
	- bridged (used to get a DHCP address)
	- host-only (used to specify a static IP of <IP_ADDRESS>)
		- specify your host-only addresses to be 192.168.56.XXX

install
	- docker
	- golang
	- git
	- mercurial
	- net-tools
	- bind-utils
	- sysstat

	- yum -y install docker golang git mercurial net-tools bind-utils sysstat

set up network adapters
	- static address is set using nm-tui on the enp0s8 adapter
		- specify <IP_ADDRESS> as IPADDR
		- specify <IP_ADDRESS> as GATEWAY
		- dns <IP_ADDRESS> (this is my routers dns nameserver addr)
	- set both adapters to connect at startup

disable firewalld (for development)
	- systemctl stop firewalld.service
	- systemctl disable firewalld.service

configure docker
	- edit /etc/sysconfig/docker
		- OPTIONS='--selinux-enabled --bip=<IP_ADDRESS>/16 --dns-search=crunchy.lab --dns=<IP_ADDRESS> --dns=<IP_ADDRESS>'
	- systemctl enable docker.service
	- systemctl start docker.service

Install Skybridge
-----------------
	- git clone git@github.com:CrunchyData/skybridge.git
	- edit skybridge/bin/run-skybridge.sh
		- change the static IP address to <IP_ADDRESS>
	- sudo ./skybridge/bin/run-skybridge.sh
	- sudo vi /etc/resolv.conf
		- add <IP_ADDRESS> as a primary DNS nameserver

Setup the CPM Source Environment
---------------------
export GOPATH=~/devproject
export GOBIN=$GOPATH/bin
export PATH=$GOBIN:$PATH

cd devproject

go get github.com/tools/godep
go get github.com/crunchydata/crunchy-postgresql-manager
cd src/github.com/crunchydata/crunchy-postgresql-manager

godep restore
make build

make buildimages

Run CPM
--------------
edit ./sbin/dev-setup.sh
	- change the home directory to the user you are building under

sudo ./sbin/dev-setup.sh

sudo ./run-cpm.sh

Verify your build
-----------------

You should see the following containers running:
~~~~~~~~~~~~~~~~~~~~~~
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS              PORTS                                        NAMES
4b2c682ed159        crunchydata/cpm:latest           "/var/cpm/bin/startn   20 seconds ago      Up 19 seconds       13001/tcp, <IP_ADDRESS>:13050->13000/tcp   cpm
58003cd15731        prom/prometheus:latest           "/bin/prometheus -co   2 minutes ago       Up 2 minutes        9090/tcp, <IP_ADDRESS>:16000->3000/tcp     cpm-prometheus
9a366dab40f3        prom/promdash:latest             "./run ./bin/thin st   2 minutes ago       Up 2 minutes        3000/tcp, <IP_ADDRESS>:15000->8080/tcp     cpm-promdash
2ef2fa68be12        crunchydata/cpm-collect:latest   "/var/cpm/bin/start-   2 minutes ago       Up 2 minutes        5432/tcp, 8080/tcp                           cpm-collect
91ac5a3ce888        crunchydata/cpm-backup:latest    "/var/cpm/bin/start-   2 minutes ago       Up 2 minutes        5432/tcp, 13000/tcp                          cpm-backup
d05f5b7ac614        crunchydata/cpm-admin:latest     "/var/cpm/bin/starta   2 minutes ago       Up 2 minutes        5432/tcp, <IP_ADDRESS>:14000->13000/tcp    cpm-admin
f08c1afc90b3        crunchydata/skybridge:latest     "/var/cpm/bin/start-   3 hours ago         Up 43 minutes       <IP_ADDRESS>:53->53/udp, 53/tcp            skybridge
~~~~~~~~~~~~~~~~~~~~~~

You should be able to ping the following addresses:
~~~~~~~~~~~~~~~~~~~
ping -c 1 cpm.crunchy.lab
ping -c 1 cpm-admin.crunchy.lab
ping -c 1 cpm-backup.crunchy.lab
ping -c 1 cpm-promdash.crunchy.lab
ping -c 1 cpm-prometheus.crunchy.lab
~~~~~~~~~~~~~~~~~~~

Access CPM
----------------

The CPM web interface is located at:
http://cpm.crunchy.lab:13050
http://<IP_ADDRESS>:13050

The CPM REST API is located at:
http://cpm-admin.crunchy.lab:13000
http://<IP_ADDRESS>:14000

The PromDash metrics dashboard is at:
http://cpm-promdash:8080
http://<IP_ADDRESS>:15000

The Prometheus database console is at:
http://cpm-prometheus:3000
http://<IP_ADDRESS>:16000


text:
# Ros Model

[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)

[![Build](https://travis-ci.org/ipa320/ros-model.svg?branch=master)](https://travis-ci.org/ipa320/ros-model) (Travis CI)

Technical Maintainer: [**ipa-nhg**](https://github.com/ipa-nhg/) (**Nadia Hammoudeh Garcia**, **Fraunhofer IPA**) -<EMAIL_ADDRESS>
This repository holds a family of metamodels defined as ecore models that together with its java and Xtext and Xtend grammar implementations facilitates the use of a set of tools and graphical plugins to create models from ROS code, compose and validate the composition of models, autogenerate deployment artifacts and check the use of standard specifications.

For further information about the metamodels, please check the [IRC19 paper](https://ieeexplore.ieee.org/document/8675668)

### Installation

#### Option 1: Using the Release version (Recommended)

In Eclipse, go to *Help* > *Install New Software...*. To install the latest version of the ROS tooling, add the update site URL [http://ros-model.seronet-project.de/updatesite/latest/](http://ros-model.seronet-project.de/updatesite/latest/) in the *Work with* section. If you wish to install an earlier version instead, go to the [the update site](http://ros-model.seronet-project.de/updatesite/), choose the desired version and copy its URL.

![alt text](docu/images/install_updatesite.png)

The category *ROS Model* appears in the *Name* area. Check the box in front of *ROS model* and click *Next* to review the list of items to be installed. Click *Next* again to read and accept the terms of the license agreements and afterwards click *Finish*. Eclipse will then start to install the ROS tooling and its dependencies. If you get a security warning about the authenticity, click OK. Finally, when asked, restart Eclipse to complete the installation process.

To start using the ROS tooling continue with the [step 1](#1-switch-to-the-ros-developer-perspective)

#### Option 2: Using the Eclipse Installer - Source installation (ROS tooling developers)

Download the official [Eclipse Installer](https://www.eclipse.org/downloads/packages/installer) for your preferred operating system. Execute the installer and choose the advanced mode (menu on the right-up corner). Select the Product *Eclipse Modeling tools* package, for the version it is recommended use *2018-12*.

![alt text](docu/images/eclipse_installer1.png)

Press *Next* and add a new *User project* pressing the green button *+*:
```
Catalog: Github Projects
Resource URIs: https://raw.githubusercontent.com/ipa320/ros-model/master/EclipseInstaller/ROSModel.setup
```
![alt text](docu/images/eclipse_installer2.png)

Select the the ROS Model project (under Github Projects -> <User>) and press next.

By default the ROS tooling installation will be saved under the folder *ros-model-master* in your home directory. In case your github credentials are not setup on your machine, change the *Ros model Github repository* to the *HTTPs(read-write)* option.

Follow the installation instructions of the Oompth installer dialog, after the installation eclipse will be restarted to launch the ROS tooling configuration. Finally, when all the startup tasks finished press "Workbench".

To start using the ROS tooling continue with the [step 0](#0-start-the-ros-tooling-application)

### Setup the environment and start the eclipse application

#### 0: Start the ROS tooling application

:bangbang::bangbang: This is only needed if you installed the toolig from [source](#option-2-using-the-eclipse-installer---source-installation-ros-tooling-developers), if you installed the release version please continue directly with the [step 1](#1-switch-to-the-ros-developer-perspective)

select de.fraunhofer.ipa.ros.plugin and press the button *Run*

![alt text](docu/images/run_ros_tooling.png)

#### 1: Switch to the ROS Developer perspective

Go to Menu Window -> Perspective -> Open Perspective -> Other... -> ROS developer. Your application toolbar will be automatically configured.

#### 2: Import the common communication objects project

import the project located under the "ROSCommonObjects" folder of this repository to the workbench of your application:
```
de.fraunhofer.ipa.ros.communication.objects
```

If you have internet a button can clone from GitHub the objects to your workspace and import them automatically:

![alt text](docu/images/clone_and_import.png)

Now that your workspace is setup, you can start creating your [project and defining your ROS system](#Tutorials)

## Tutorials

* [Create new ROS projects and define ROS nodes](docu/NewProject.md)
* [Create a ROS model from cpp code](docu/NewRosModel.md)
* [Generation of code from models](docu/CodeGeneration.md)
* [Define a ROS system as a composition of components](docu/NewSystem.md)
* [Compare your model with a Specification](docu/CompareSpec.md)
* [Add communication objects](docu/NewCommunicationObjects.md)
* [Model extraction using introspection at runtime](https://github.com/ipa-led/ros_graph_parser)
* [Introspection at design time](docu/simulateRuntime.md)
* [Connect your ROS project with SeRoNet](docu/ROSSeRoNet.md)

## Model examples

The [ros-model-experiments](https://github.com/ipa-nhg/ros-model-experiments/) reposirory holds some examples of models autogenerated using the tooling and its facilities.

## Update Release versions (only for administrators)

### 1. Update version

Run the command:

```
mvn org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion=X.Y.0-SNAPSHOT -f plugins/de.fraunhofer.ipa.ros.parent/
```

This will upgrade the *pom.xml* and *MANIFEST.MF* of all the repositories.

### 2. Synchronize the ROS fetuare

Open in eclipse the file *de.fraunhofer.ipa.ros.feature/feature.xml* and under *Overview* press the button *Synchronize* and choose the second option *Copy versions from plug-in, feature and fragment manifest*

![alt text](docu/images/sync_feature.png)

Push to this GitHub repository the status

### 3. Export the updated feature

From the menu *File* select *Export* and choose the option *Deployable features* from *Plug-in Development* category. Select the *de.fraunhofer.ipa.ros.feature* Feature and give a path for destination (e.g. ~/Desktop/export)

The resulted folders and files have to be copied to the *updatesite/latest* folder fo the [Update Site server](http://ros-model.seronet-project.de/updatesite/latest/) and the [site.xml](http://ros-model.seronet-project.de/updatesite/latest/site.xml) file updated to point the new version.

### 4. Add a new release on GitHub

Tag the current point of the history with the release number previously given (X.Y.0). Optionally upgrade the [exported files](#3-export-the-updated-feature) as a zip.

repository: ipa-lth/ros-model

repo_name: ipa-lth/ros-model


text:
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: mdd36

---

**Describe the bug**
A clear and concise description of what the bug is.

**When did you try this?**
Date and approximate time (ie Tues Jan 1, about 11:30pm)

**Error Stacktrace**
The server should have given you a message with the 500 Error page. Please copy and paste it here

**MIPS Code**
If assembling one file, copy it below

`Copy the MIPS here!`

If multiple files, put them all in ONE zip file, and submit it here:

https://www.dropbox.com/request/1wD32iGvEBwGOcoTKu8g

**Desktop (please complete the following information):**
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


text:
## Grid: parallel multiple charts

> *class pyecharts.charts.Grid(Base)*

```python
class Grid(
    ## Initialize configuration items, see ``global_options.InitOpts`''
    init_opts: opts.InitOpts = opts.InitOpts()
)
```

> *func pyecharts.charts.Grid.add*

``` python
def add(
    # Chart instances, only class `Chart` or its subclasses
    chart: Chart,

    # Cartesian grid configuration items, see `GridOpts`
    grid_opts: Union[opts.GridOpts, dict],

    # Cartesian grid index
    grid_index: int = 0,

    # Whether to control the Axis index by itself
    is_control_axis_index: bool = False,
)
```

### GridOpts: right-angle coordinate system grid configuration items
> *class pyecharts.options.GridOpts*

```python
class GridOpts(
    # Whether or not to show right-angle coordinate system grids.
    is_show: bool = False,

    # The zlevel value of all graphs.
    z_level: Numeric = 0,

    # The z value of all graphs of the component.
    z: Numeric = 2,

    # The distance of the grid component from the left side of the container.
    # The value of left can be a specific pixel value like 20, or a percentage relative to the height and width of the container like '20%'.
    # It can also be 'left', 'centre', 'right'.
    # If the value of left is 'left', 'centre', 'right', the component will be automatically aligned according to the corresponding position.
    pos_left: Union[Numeric, str, None] = None,

    # The distance of the grid component from the top side of the container.
    # The value of top can be a specific pixel value like 20, a percentage relative to the height and width of the container like '20%'
    # It can also be 'top', 'middle', 'bottom'.
    # If the value of top is 'top', 'middle', 'bottom', the component will be automatically aligned according to the corresponding position.
    pos_top: Union[Numeric, str, None] = None,

    # The distance of the grid component from the right side of the container.
    The value of # right can be a specific pixel value like 20, or it can be a percentage relative to the container height and width like '20%'.
    pos_right: Union[Numeric, str, None] = None,

    # The distance of the grid component from the lower side of the container.
    The value of # bottom can be a specific pixel value like 20, or a percentage of the container's height and width like '20%'.
    pos_bottom: Union[Numeric, str, None] = None,

    # The width of the grid component. Adaptive by default.
    width: Union[Numeric, str, None] = None,

    # The height of the grid component. Adaptive by default.
    height: Union[Numeric, str, None] = None,

    # Whether or not the grid area contains a scale label for the axes.
    is_contain_label: bool = False,

    # The background colour of the grid, transparent by default.
    background_color: str = "transparent",

    # The border colour of the grid. Supported colours are in the same format as backgroundColor.
    border_color: str = "#ccc",

    # The border line width of the grid.
    border_width: Numeric = 1,

    # The blur size of the graph's shadow
    shadow_blur: Optional[Numeric] = None,

    # Shadow colour
    shadow_color: Optional[str] = None,

    # The horizontal offset distance of the shadow
    shadow_offset_x: Numeric = 0,

    # The offset distance of the shadow vertically
    shadow_offset_y: Numeric = 0,

    # A tooltip setting specific to this coordinate system.
    tooltip_opts: Union[TooltipOpts, dict, None] = None,
)
```

### Demo

[gallery example](http://gallery.pyecharts.org/#/Grid/README)

## Page: sequential multimap

> *class pyecharts.charts.Page*

```python
class Page(
    ## HTML title
    page_title: str = "Awesome-pyecharts",

    # Remote HOST, defaults to "https://assets.pyecharts.org/assets/"
    js_host: str = "",

    # The interval between each legend
    interval: int = 1,

    # Layout configuration items, see `PageLayoutOpts`
    layout: Union[PageLayoutOpts, dict] = PageLayoutOpts()
)
```

> *func pyecharts.charts.Page.add*

``` python
def add(*charts) # charts: any chart instance
```

> *class pyecharts.options.PageLayoutOpts*

``` python
class PageLayoutOpts(
    # Configure all native CSS styles
    justify_content: Optional[str] = None,
    margin: Optional[str] = None,
    display: Optional[str] = None,
    flex_wrap: Optional[str] = None,
)
```

> *func pyecharts.charts.Page.save_resize_html*

For DraggablePageLayout layout re-rendering charts
``` python
def save_resize_html(
    # The html file after the first rendering of the Page
    source: str = "render.html",
    *,
    # Layout configuration file
    cfg_file: types.Optional[str] = None,

    # Layout configuration dict
    cfg_dict: types.Optional[list] = None,

    # path to re-generated .html storage
    dest: str = "resize_render.html",
) -> str
```

Page has the following layouts built in

* SimplePageLayout
* DraggablePageLayout

### Demo

[gallery example](http://gallery.pyecharts.org/#/Page/README)

**Default layout**
```python
page = Page()
page.add(bar_datazoom_slider(), line_markpoint(), pie_rosetype(), grid_mutil_yaxis())
page.render()
```

**SimplePageLayout layout**
```python
page = Page(layout=Page.SimplePageLayout)
# You need to adjust the height/width of each chart yourself, the display may be different on different monitors
page.add(bar_datazoom_slider(), line_markpoint(), pie_rosetype(), grid_mutil_yaxis())
page.render()
```
![](https://user-images.githubusercontent.com/19553554/58749778-c8420a00-84bc-11e9-87e5-2aeab78a8eef.png)

**DraggablePageLayout layout**
```python
page = Page(layout=Page.DraggablePageLayout)
page.add(bar_datazoom_slider(), line_markpoint(), pie_rosetype(), grid_mutil_yaxis())
page.render()
```

Note: DraggablePageLayout requires pyecharts version v.1.4.0+
```python
# DraggablePageLayout makes use of Jquery and Echarts' own resize feature to implement a draggable layout. The steps are as follows
# 1. Specify the Page layout
page = Page(layout=Page.DraggablePageLayout)

# Normal render chart
page.add(bar_datazoom_slider(), line_markpoint(), pie_rosetype(), grid_mutil_yaxis())
page.render()

# Use your browser to open the rendered .html file, which defaults to render.html. drag/resize the chart, and when it is resized to a suitable
# Click on the `Save Config` button at the top left to download the chart_config.json configuration file, assuming the location is
# Render the chart again and specify its layout configuration

# Warning: Please comment out all the rendering code above, which is the following three lines. As the html is already generated, there is no need to render it again.
# page = Page(layout=Page.DraggablePageLayout)
# page.add(bar_datazoom_slider(), line_markpoint(), pie_rosetype(), grid_mutil_yaxis())
# page.render()

# render.html: the original html file generated in the first step
# chart_config.json: the configuration file downloaded in step 2
# my_new_charts.html: path to the new html file
Page.save_resize_html("render.html", cfg_file="~/chart_config.json", dest="my_new_charts.html")

# Or you can use json data
# cfg_dict is the contents of the json file
Page.save_resize_html("render.html", cfg_dict=cfg_dict, dest="my_new_charts.html")

# Question: Can I reuse rendering templates?
# Answer: Yes, the rendering configuration json data uses the chart_id as the unique identifier for a graph, so you only need to specify the chart_id in the
# The first time you render a chart, you can specify the chart_id.
# example:
# bar = bar_datazoom_slider()
# bar.chart_id = "chenjiandongx_is_an_awesome_boy"
# line = line_markpoint()
# line.chart_id = "chenjiandongx_is_an_amazing_boy"
# pie = pie_rosetype()
# pie.chart_id = "chenjiandongx_is_an_adorable_boy"
# pie = pie_rosetype() # pie.chart_id = "chenjiandongx_is_an_adorable_boy" # pie.chart_id = "chenjiandongx_is_an_adorable_boy
# cat chart_config.json, you will see that the chart_id is fixed.
page.add(bar_datazoom_slider(), line_markpoint(), pie_rosetype()))
```

Demo video
* [Oil Tube Video](https://www.youtube.com/watch?v=gizMMGkUt80&feature=youtu.be)
* [Tencent Video](https://v.qq.com/x/page/u0914vsm901.html)

## Tab: tab multimap

> * class pyecharts.charts.Tab*

```python
class Tab(
    ## HTML title
    page_title: str = "Awesome-pyecharts",

    # Remote HOST, defaults to "https://assets.pyecharts.org/assets/"
    js_host: str = ""
)
```

> *func pyecharts.charts.Tab.add*

``` python
def add(
    # arbitrary chart types
    chart,

    # the name of the tab
    tab_name
):
```

### Demo

[gallery example](http://gallery.pyecharts.org/#/Tab/README)

## Timeline: Timeline rotating multiple images

> *class pyecharts.charts.Timeline*

```python
class Timeline(
    ## Initialize configuration items, see ``global_options.InitOpts`''
    init_opts: opts.InitOpts = opts.InitOpts()
)
```

> *func pyecharts.charts.Timeline.add_schema*

``` python
def add_schema(
    # Coordinate axis type. Optional.
    # 'value': numeric axis, for continuous data.
    # 'category': category axis, for discrete category data, for this type the category data must be set via data.
    # 'time': time axis, for continuous temporal data, compared to the numeric axis the time axis is formatted with time and has a different scale calculation.
    # 'log': The time axis, for continuous temporal data, has a formatting of time compared to the numeric axis and differs in the scale calculation, e.g. whether to use a month, week, day or hour scale depending on the span.
    # 'log' logarithmic axis. Applies to logarithmic data.
    axis_type: str = "category",

    # The type of the time axis. Optional:
    # 'horizontal': horizontal
    # 'vertical': vertical
    orient: str = "horizontal",

    # The graph of the timeline marker.
    # The types of markers provided by ECharts include 'circle', 'rect', 'roundRect', 'triangle', 'diamond',
    # 'pin', 'arrow', 'none'
    # Can be set to an image with 'image://url', where URL is the link to the image, or dataURI.
    symbol: Optional[str] = None,

    # The size of the timeline marker, which can be set to a single number such as 10, or an array of separate widths and heights.
    # For example, [20, 10] means the marker is 20 wide and 10 high.
    symbol_size: Optional[Numeric] = None,

    # Indicates the speed of play (the interval between beats) in milliseconds (ms).
    play_interval: Optional[Numeric] = None,

    # Indicates the position of the play button. Optional values: 'left', 'right'.
    control_position: str = "left",

    # Whether to play automatically.
    is_auto_play: bool = False,

    # Whether to loop play.
    is_loop_play: bool = True,

    # Whether to play in reverse.
    is_rewind_play: bool = False,

    # Whether or not to display the timeline component. If set to false, it will not be shown, but the function will still exist.
    is_timeline_show: bool = True,

    # Whether to put the timeline in reverse, if so the first one will be reversed
    is_inverse: bool = False,

    # The distance of the timeline component from the left side of the container.
    # The value of left can be a specific pixel value like 20, or a percentage of the container's height and width like '20%'.
    # It can also be 'left', 'centre', 'right'.
    # If the value of left is 'left', 'centre', 'right', the component will be automatically aligned according to the corresponding position
    pos_left: Optional[str] = None,

    # The distance of the timeline component from the right side of the container.
    The value of # right can be a specific pixel value like 20, or a percentage relative to the container's height and width like '20%'.
    pos_right: Optional[str] = None,

    # The distance of the timeline component from the top side of the container.
    # The value of left can be a specific pixel value like 20, or a percentage of the container's height and width like '20%'.
    # It can also be 'top', 'middle', 'bottom'.
    # If the value of left is 'top', 'middle', 'bottom', the component will be automatically aligned according to the corresponding position
    pos_top: Optional[str] = None,

    # The distance of the timeline component from the lower side of the container.
    The value of # bottom can be a specific pixel value like 20, or a percentage relative to the container height and width like '20%'.
    pos_bottom: Optional[str] = "-5px",

    # The width of the timeline area, affecting the distance between the timeline's axis labels and the axis when vertical
    width: Optional[str] = None,

    # The height of the timeline area
    height: Optional[str] = None,

    # The axis configuration for the timeline, see `series_options.LineStyleOpts`
    linestyle_opts: Union[opts.LineStyleOpts, dict, None] = None,

    # Axis labels for the timeline, refer to `series_options.LabelOpts`
    label_opts: Optional[opts.LabelOpts] = None,

    # The graphical style of the timeline, see `series_options.ItemStyleOpts`
    itemstyle_opts: Union[opts.ItemStyleOpts, dict, None] = None,

    # Graphic styles
    graphic_opts: types.Graphic = None,

    # The graphic style of the 'current item' (checkpoint).
    checkpointstyle_opts: types.TimeLinkCheckPoint = None,

    # The style of the 'control button'. "The 'control buttons' include: 'play button', 'forward button', 'back button'.
    controlstyle_opts: types.TimeLineControl = None,

    # Line styles in the progress bar
    progress_linestyle_opts: types.LineStyle = None,

    # The style of the inflection point in the progress bar.
    progress_itemstyle_opts: types.ItemStyle = None,

    # The style of the label in the progress bar.
    progress_label_opts: types.Label = None,
)
```

> *func pyecharts.charts.Timeline.add*

``` python
def add(
    # chart instance
    chart: Base,

    # time_point
    time_point: str
)
```

### TimeLinkCheckPoint: Timeline checkpoint style configuration

```python
class TimelineCheckPointerStyle(
    # ECharts provides marker types such as 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
    # Can be set to an image with 'image://url', where URL is the link to the image, or dataURI.
    # The icon can be set to an arbitrary vector path by 'path://'.
    # This way you don't have to worry about jaggies or blurring due to scaling compared to using images, and can be set to any colour.
    # The path graphic adapts itself to the right size. See SVG PathData for the format of paths.
    # Can be edited and exported from tools such as Adobe Illustrator.
    symbol: str = "circle",

    # The size of the marker.
    symbol_size: Union[Numeric, Sequence[Numeric]] = 13,

    # The angle of rotation (not radians) of the marker. A positive value indicates a counterclockwise rotation.
    symbol_rotate: Optional[Numeric] = None,

    # If symbol is of the form path://, whether to keep the aspect ratio of the figure when scaling.
    symbol_keep_aspect: bool = False,

    # The offset of the symbol relative to its original position.
    symbol_offset: Optional[Sequence[Union[str, Numeric]]] = None,

    # The colour of the 'current item' (checkpoint).
    color: str = "#c23531",

    # The border width of the 'current item' (checkpoint).
    border_width: Numeric = 5,

    # The border colour of the 'current item' (checkpoint).
    border_color: str = "rgba(194,53,49,0.5)",

    # Whether the movement of the checkpoint in the timeline play switch is animated.
    is_animation: bool = True,

    # The duration of the checkpoint's animation.
    animation_duration: Numeric = 300,

    # The easing effect of the checkpoint's animation.
    animation_easing: str = "quinticInOut",
)
```

### TimelineControlStyle: Timeline control button style

```python
class TimelineControlStyle(
    ### Show or not show 'control buttons'. Set to false to show none.
    is_show: bool = True,

    # Whether or not to show the 'play button'.
    is_show_play_button: bool = True,

    # Whether to show the 'back button' or not.
    is_show_prev_button: bool = True,

    # Whether to show the 'forward button'.
    is_show_next_button: bool = True,

    # The size of the 'control button', in pixels (px).
    item_size: Numeric = 22,

    # The spacing of the 'control button' in pixels (px).
    item_gap: Numeric = 12,

    # The position of the 'control button'.
    # When timeline.orient is 'horizontal', 'left' and 'right' are valid.
    # When timeline.orient is 'vertical', 'top' and 'bottom' are valid.
    position: str = 'left',

    # The graphical representation of the 'playable state' of the 'play button'.
    # Can be set to an image via 'image://url', where URL is the link to the image, or dataURI.
    # The icon can be set to an arbitrary vector path via 'path://'.
    # This way you don't have to worry about jaggedness or blurring due to scaling compared to using images, and can be set to any colour.
    # The path graphic adapts itself to the right size. See SVG PathData for the format of paths.
    # Can be edited and exported from tools such as Adobe Illustrator.
    play_icon: Optional[str] = None,

    # Same as above
    stop_icon: Optional[str] = None,

    # Same as above
    prev_icon: Optional[str] = None,

    # ditto
    next_icon: Optional[str] = None,

    # The button colour.
    color: str = "#304654",

    # The button border colour.
    border_color: str = "#304654",

    # The width of the button border line.
    border_width: Numeric = 1,
)
```

### Demo

[gallery example](http://gallery.pyecharts.org/#/Timeline/README)

repository: pyecharts/website

repo_name: pyecharts/website


text:
---
title: NeighborLocation
fileSource: neighbor-location
tabName: Guide
---

@## Description

**NeighborLocation** is a common component for grouping components. It indicates where the component is in relation to its neighbors.

> 🙃 This violates many principles of building components, but the beautiful API and the necessary functionality outweighed the valuations.

For example, we can group together:

- [Button](/components/button/)
- [Input](/components/input/)
- [Select](/components/select)

You may also need a `flex-box` to align the components. For more information, see the [Spacing system](/layout/box-system/).

@## Grouping buttons

The buttons can be adhered to each other. In this case, a 1px separator appears between them. The color of the separator matches the color of the button border if secondary buttons are adhered. If primary buttons are adhered together, the separator between them is white.

You can "adhere" a button with a text and a button with an icon only for the `primary` and `secondary` types.

![buttons group](static/buttons-group.png)

@example neighbor-location

@## Grouping the input and button

You can "adhere" the input field with a button.

![input & button](static/input-button-group.png)

@example neighbor-location-input

@## Adhering the input and select

You can "adhere" the input field with a selector.

![input & select](static/input-select-group.png)

@example neighbor-location-input-select

@## Grouping the input, select, and button

You can also make a combo — "adhere" the entire input field, selector, and button. In such cases, use the primary button.

![KILL ME PLS](static/combo.png)

@## Adding a wrapper

By default, a `<NeighborLocation/>` does not create an HTML wrapper, but you can pass the component tag you want to it.

> For the correct type mapping in the TC, you must also pass the interface.
> `<NeighborLocation<IFlexProps> tag={Flex} w={200}/>`

@example neighbor-location-with-tag

@page neighbor-location-api
@page neighbor-location-changelog

repository: geoffdonaldson/intergalactic

repo_name: geoffdonaldson/intergalactic


text:
## AWS Transcription Assistant

I am very excited to share with you a project I have been working on that makes it easy for you to transcribe an audio file into text,  live edit that transcript and then save it into a format of your choice such as a Word document.

The application has been built as a *Progressive Web App (PWA)* using the React framework and as you might have guessed already, it makes use of AWS services.

### Solution Architecture
![Solution Architecture](https://raw.githubusercontent.com/cloud-commander/aws-transcription-assistant/master/aws-transcription-assistant-architecture-diagram.png)

So at a high level this is what is going on:

 - User makes a request to the Transcription Assistant domain (it would first hit Route 53 but that isnt reflected in the above diagram)
 - Authentication against Cognito must take place
 - Once authenticated, Cloudfront (which gets its content from S3) delivered the React PWA to the browser
 - User attempts to upload an audio file, but before that can happen, an upload token must be obtained
 - With the upload token available, the client can then upload the audio file to S3 (user must choose how many speakers are in the audio clip, this information is then encoded within the audio filename)
 - The upload event triggers a Lambda function which inserts a new record in a DynamoDB table and publishes an SNS message
 - The SNS message triggers a Lambda function which submits a Transcribe service job
 - When the Transcription is complete, its stored in an S3 bucket
 - When the user attempts to refresh the recordings table, that triggers a Lambda function which checks the transcription job status and updates the DynamoDB table accordingly
 - If the transcription is complete, it is displayed in the interface and the user can play it back
 - The interface allows the user to follow the transcription live as it synchronises the text with the audio being spoken
 - The user has the option to edit the text and then download it if desired

### Install Guide

So, how do you get this code running on your own AWS account?

#### Cognito Authentication

Firstly, we need to sort out the userpool that Cognito will authenticate against.

Make sure you have the AWS CLI installed.

You have the option to:

 - [Configure Cognito on the AWS Console](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-cognito-user-pools.html)
 - Use [AWS Amplify](https://aws.amazon.com/blogs/mobile/amplify-cli-enables-creating-amazon-cognito-user-pool-groups-configuring-fine-grained-permissions-on-groups-and-adding-user-management-capabilities-to-applications/)
 - Use CDK

For this example, I am going to use CDK:

1.    `git clone https://github.com/full-stack-serverless/cdk-authentication.git`
2.    `cd cdk-authentication`
3.    `npm install`
4.    `cdk deploy`

Once the project has been deployed, you'll be given the resources needed to configure the client-side React application.

    Outputs:
    CdkAppsyncChatStack.UserPoolClientId = your_userpool_client_id
    CdkAppsyncChatStack.UserPoolId = us-east-1_your_userpool_id

#### Deploying AWS Transcription Assistant application

Start by cloning the Github repo

    git clone https://github.com/cloud-commander/aws-transcription-assistant.git

Then navigate to the `aws-transcription-assistant/packages/frontend/src/`
and edit `aws-exports-sample.js` by entering the details you obtained from the first step and saving it as `aws-exports.js`

Now you can deploy the CDK stack. Go back to the top folder `aws-transcription-assistant/`

 - Run `yarn` to install all dependencies.
- Run `yarn build` to build both front end and back end.
- Run `yarn bootstrap` to initialise AWS CDK deployment.
- Run `yarn deploy` to do the actual deployment.

 If the deployment is successful, you should see the Cloudfront URL it was deployed at.

You now have the choice to put that behind a domain name with Route 53 like I have, or leave it as is.

### Quick Overview

Lets quickly run through the app

#### Cognito Login Page
![Cognito Login](https://github.com/cloud-commander/aws-transcription-assistant/raw/master/screenshots/Capture.PNG)

#### Home Page
![Cognito Login](https://github.com/cloud-commander/aws-transcription-assistant/raw/master/screenshots/Capture2.PNG)

#### Search for transcriptions
![Cognito Login](https://github.com/cloud-commander/aws-transcription-assistant/raw/master/screenshots/Capture3.PNG)

#### Viewing a transcription
![Cognito Login](https://github.com/cloud-commander/aws-transcription-assistant/raw/master/screenshots/Capture4.PNG)

#### Transcription playback
![Cognito Login](https://github.com/cloud-commander/aws-transcription-assistant/raw/master/screenshots/Capture5.PNG)

#### Export Transcription
![Cognito Login](https://github.com/cloud-commander/aws-transcription-assistant/raw/master/screenshots/Capture6.PNG)

#### Exported Transcription
![Cognito Login](https://github.com/cloud-commander/aws-transcription-assistant/raw/master/screenshots/Capture7.PNG)

### Acknowledgements
I would like to extend my thanks to all those in the open source community that made this project possible, especially [PinkyJie](https://github.com/PinkyJie), the [BBC](https://github.com/bbc/react-transcript-editor) and [stackoverflow](https://stackoverflow.com/).


text:
# Docker on Windows10

## Getting Started

### Prerequisites
* Windows 10 64-bit: Pro, Enterprise, or Education (Build 15063 or later).
* Hyper-V and Containers Windows features must be enabled.
* The following hardware prerequisites are required to successfully run Client Hyper-V on Windows 10:
	- 64 bit processor with Second Level Address Translation (SLAT)
	- 4GB system RAM
	- BIOS-level hardware virtualization support must be enabled in the BIOS settings. For more information, see Virtualization.

### Download Link
https://hub.docker.com/editions/community/docker-ce-desktop-windows/

### Installation
It is as any other exe installation on windows. Double click on setup and follow the wizard.

### What's included in the installer
 * Docker Engine
 * Docker CLI client
 * Docker Compose
 * Notary
 * Kubernetes
 * Credential Helper

### Confirm the Installation
Run hello-world to check
Open Pwershell
```
docker run hello-world
```

### Docker Dashboard
This is how the dashboard will loook like.
![Docker Dashboard](images/docker_dashboard.jpg)

## Notes
* You can toggle between Windows and Linux container.
  switching may take few minutes.

## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details

## Courtesy
[docker for windows](https://docs.docker.com/docker-for-windows/install/)