text:
---
title: "Install K8ssandra on DOKS"
linkTitle: "DigitalOcean DOKS"
weight: 2
description: >
  Complete **production** ready environment of K8ssandra on DigitalOcean Kubernetes (DOKS).
---

[DigitalOcean Kubernetes](https://www.digitalocean.com/products/kubernetes/) or "DOKS" is a managed Kubernetes environment on [DigitalOcean](https://www.digitalocean.com/) (DO). DOKS is a fully managed experience; it handles the management/upgrading of the Kubernetes cluster master as well as autoscaling of "nodes" through "node pools."

{{% alert title="Tip" color="success" %}}
Also available in followup topics are post-install steps and role-based considerations for [developers]({{< relref "/quickstarts/developer">}}) or [Site Reliability Engineers]({{< relref "/quickstarts/site-reliability-engineer">}}) (SREs).
{{% /alert %}}

## Deployment

This topic covers provisioning the following infrastructure resources.

* 1x VPC Network
* 1x DOKS cluster
* 2x Node Pools
  * 3x Cassandra Kubernetes workers
    * 32 vCPUs
    * 64 GB RAM
  * 3x Support Kubernetes workers
    * 2 vCPUs
    * 4 GB RAM
* 3x 2TB Block Storage Volumes (provisioned automatically during installation of K8ssandra)
* 1x DigitalOcean Spaces bucket for backups

{{% alert title="Warning" color="success" %}}
The instance flavors specified here may not be available to all accounts. If these higher capacity instances are unavailable reach out to Digital Ocean support to increase your limits.
{{% /alert %}}

On this infrastructure the K8ssandra installation will consist of the following workloads.

* 3x instance Apache Cassandra cluster
* 3x instance Stargate deployment
* 1x instance Prometheus deployment
* 1x instance Grafana deployment
* 1x instance Reaper deployment

Feel free to update the parameters used during this guide to match your target deployment. This should be considered a minimum for production workloads.

## Provisioning Infrastructure

At this time the K8ssandra project does not have Terraform modules available to assist with provisioning infrastructure. With that being said the steps required to manually provision the infrastructure are outlined below. If you have already provisioned a cluster skip to the [Install K8ssandra](#install-k8ssandra) section.

### Tools

| Tool | Version |
|------|---------|
| [kubectl](https://kubernetes.io/docs/tasks/tools/) | 1.17.17 |
| [doctl](https://docs.digitalocean.com/reference/doctl/how-to/install/) | 1.61.0 |

Make sure to authenticate `doctl` as we will be using it later.

```console
doctl auth init
```

**Output:**

```console
Please authenticate doctl for use with your DigitalOcean account. You can generate a token in the control panel at https://cloud.digitalocean.com/account/api/tokens

Enter your access token:
Validating token... OK
```

### VPC Network

Before creating our DOKS cluster we should create VPC network. It is possible to skip this step, but ultimately this network will be created for you anyway. From the DO console navigate to `Networking` in the left sidebar then `VPC`. Click the `Create VPC Network` button to start the process.

From here choose a `datacenter region` and configure the `Private IP range`.

![Create VPC form](vpc-create.png)

In our example we are using `NYC3` and `Generate an IP range for me`.

### Kubernetes Cluster

Next, we navigate to `Kubernetes` in the sidebar navigation and click `Create`. First, choose a `Kubernetes version` and `VPC Network`.

![DOKS version and network](doks-create-1.png)

With that selected we now focus on creating our first node pool. In this case we will create a node pool for the Cassandra nodes. This node pool should match the recommended instance size for production. Here we used `CPU-optimized nodes` with `32 vCPUs` and `64 GB RAM`.

![DOKS initial node pool](doks-create-2.png)

Finally, click `Create Cluster` to start the provisioning process.

### Node Pool(s)

At this point the cluster is provisioning. We need to create a second node pool for running our supporting tools like Reaper, Prometheus, and Grafana.

From the cluster detail screen navigate to the `Nodes` tab. Next, click the `Add Node Pool` button.

![Add node pool dialog](node-pool-create.png)

Note that these nodes do not need to be as large as the C* nodes. For our example we selected `Basic nodes` with `4 GB RAM` and `2 vCPUs`. We chose `3` nodes for this pool. After selecting the appropriate values here click the `Add Node Pool(s)` button.

### Spaces

While these droplets spin up we can head over to the `Spaces` section of the sidebar and create a bucket for our Medusa backups. Click the `Create` button to start the process. Make sure to select a region where your DOKS cluster is running to minimize traffic ingress/egress costs.

![Spaces wizard](spaces-create.png)

{{% alert title="Important" color="primary" %}}
The bucket name must be unique across all of DigitalOcean. Copying the value here will most likely result in a conflict.
{{% /alert %}}

With a bucket created click the `Spaces` link in the sidebar again and navigate to the `Manage Keys` button. In the `Spaces Access Keys` section create a key that Medusa will use to access our Space.

![Spaces key](spaces-key.png)

After creating the key note the key id and secret. We will use these values later when configuring Medusa. Failure to do so will require regenerating the secret later.

## Retrieve `kubeconfig`

After provisioning the DOKS cluster we must request a copy of the `kubeconfig`. This provides the `kubectl` command with all connection information including TLS certificates and IP addresses for Kube API requests.

```console
# NOTE your kubeconfig command WILL BE DIFFERENT, retrieve the command from the DO console interface.
doctl kubernetes cluster kubeconfig save REDACTED
```

**Output**:

```bash
Notice: Adding cluster credentials to kubeconfig file found in "~/.kube/config"
Notice: Setting current-context to do-nyc3-k8s-1-20-7-do-0-nyc3-1623165482131
```

With `kubectl` configured let's check connectivity to the cluster and verify versions.

```bash
kubectl cluster-info
```

**Output**:

```bash
Kubernetes control plane is running at https://f10bb874-562f-4328-8910-e0e2f6efa78b.k8s.ondigitalocean.com
CoreDNS is running at https://f10bb874-562f-4328-8910-e0e2f6efa78b.k8s.ondigitalocean.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```

```bash
kubectl version
```

**Output**:

```bash
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.1", GitCommit:"5e58841cce77d4bc13713ad2b91fa0d961e69192", GitTreeState:"clean", BuildDate:"2021-05-12T14:18:45Z", GoVersion:"go1.16.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.7", GitCommit:"132a687512d7fb058d0f5890f07d4121b3f0a2e2", GitTreeState:"clean", BuildDate:"2021-05-12T12:32:49Z", GoVersion:"go1.15.12", Compiler:"gc", Platform:"linux/amd64"}
```

### Taint Nodes

With mixed node types available we should apply taints to each node type in order to facilitate scheduling. The larger instances will be tainted with the value `app=cassandra:NoSchedule` effectively blocking the scheduling of Pods unless they have the taint `app=cassandra`. In our example deployment here Cassandra nodes are part of the pool named `pool-hluacyqq4`.

{{% alert title="Important" color="primary" %}}
Your node pool names will most likely not match the values above. Make sure you adjust the commands / values appropriately for your environment.
{{% /alert %}}

```console
kubectl taint node -l doks.digitalocean.com/node-pool=pool-hluacyqq4 app=cassandra:NoSchedule
```

**Output:**

```console
node/pool-hluacyqq4-8edt2 tainted
node/pool-hluacyqq4-8edtl tainted
node/pool-hluacyqq4-8edtt tainted
```

## Install K8ssandra

With all of the infrastructure provisioned we can now focus on installing K8ssandra. This will require configuring a service account for the backup and restore service and creating a set of Helm variable overrides.

### Create Backup / Restore Service Account Secrets

In order to allow for backup and restore operations, we must create a service account for the Medusa operator which handles coordinating the movement of data to and from DigitalOcean Spaces. As part of the provisioning section a key was generated for this purpose. Plug in the key and secret from the provisioning section in the following file and save the file as `medusa_s3_credentials`.

{{< readfilerel file="spaces.secret.yaml" highlight="yaml" >}}

Next submit this file to Kubernetes as a secret.
```bash
kubectl create secret generic prod-k8ssandra-medusa-key --from-file=medusa_s3_credentials=./medusa_s3_credentials
```

**Output**:

```bash
secret/prod-k8ssandra-medusa-key created
```

{{% alert title="Important" color="primary" %}}
The name of the key file within the secret MUST be `medusa_s3_credentials`. _Any_ other value will result in Medusa not finding the secret and backups failing.
{{% /alert %}}

This secret, `prod-k8ssandra-medusa-key`, can now be referenced in our K8ssandra configuration to allow for backing up data to DigitalOcean Spaces with Medusa.

### Create `WaitForFirstConsumer` Storage Class

K8ssandra requires a Kubernetes Storage Class that has `volumeBindingMode: WaitForFirstConsumer`. The default preinstalled `do-block-storage` storage class has `volumeBindingMode: Immediate`. We will create a new storage class with the required mode based on the existing version.

{{< readfilerel file="do-block-storage-wait.yaml" highlight="yaml" >}}

Submit this file to the Kubernetes cluster with:

```console
kubectl apply -f do-block-storage-wait.yaml
```

**Output:**

```console
storageclass.storage.k8s.io/do-block-storage-wait created
```

### Generate `doks.values.yaml`

Here is a reference Helm `doks.values.yaml` file with configuration options for running K8ssandra in DigitalOcean on DOKS.

{{< readfilerel file="doks.values.yaml"  highlight="yaml" >}}

{{% alert title="Important" color="primary" %}}
Take note of the comments in this file. If you have changed the name of your secret, are deploying in a different region, or have tweaked any other values it is imperative that you update this file before proceeding.
{{% /alert %}}

### Deploy K8ssandra with Helm

With a `values.yaml` file generated which details out specific configuration overrides we can now deploy K8ssandra via Helm.

```bash
helm install prod-k8ssandra k8ssandra/k8ssandra -f doks.values.yaml
```

**Output**:

```bash
NAME: prod-k8ssandra
LAST DEPLOYED: Sat Apr 24 01:15:46 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
```

### Retrieve K8ssandra superuser credentials {#superuser}

You'll need the K8ssandra superuser name and password in order to access Cassandra utilities and do things like generate a Stargate access token.

{{% alert title="Tip" color="success" %}}
In `kubectl get secret` commands, be sure to prepend the environment name. In this topic's examples, we have used `prod-k8ssandra`. Notice how it's prepended in the examples below. Also, save the displayed superuser name and the generated password for your environment. You will need the credentials when following the
[Quickstart for developers]({{< relref "/quickstarts/developer" >}}) or [Quickstart for Site Reliability Engineers]({{< relref "/quickstarts/site-reliability-engineer" >}}) post-install steps.
{{% /alert %}}

To retrieve K8ssandra superuser credentials:

1. Retrieve the K8ssandra superuser name:

    ```bash
    kubectl get secret prod-k8ssandra-superuser -o jsonpath="{.data.username}" | base64 --decode ; echo
    ```

    **Output**:

    ```bash
    prod-k8ssandra-superuser
    ```

1. Retrieve the K8ssandra superuser password:

    ```bash
    kubectl get secret prod-k8ssandra-superuser -o jsonpath="{.data.password}" | base64 --decode ; echo
    ```

    **Output**:

    ```bash
    PGo8kROUgAJOa8vhjQrE49Lgruw7s32HCPyVvcfVmmACW8oUhfoO9A
    ```

## Cleanup Resources

If this cluster is no longer needed you may optionally uninstall K8ssandra or delete all of the infrastructure.

### Uninstall K8ssandra

```console
helm uninstall prod-k8ssandra
```

**Output**:

```bash
release "prod-k8ssandra" uninstalled
```

### Destroy Infrastructure

Similar to our provisioning section visit the following console sections (in order) to destroy the underlying infrastructure used during this guide.

1. Kubernetes cluster
2. Spaces
3. Networking => VPC. _Note_ if this is the only VPC in your account it is considered the default and may not be destroyed. You will not be billed for the VPC, just resources within it.

## Next steps

With a freshly provisioned cluster on DOKS, consider visiting the [developer]({{< relref "/quickstarts/developer" >}}) and [Site Reliability Engineer]({{< relref "/quickstarts/site-reliability-engineer" >}}) quickstarts for a guided experience exploring your cluster.

Alternatively, if you want to tear down your DOKS cluster and / or infrastructure, refer to the section above that covers [cleaning up resources]({{< relref "#cleanup-resources" >}}).


text:
Translator: Joseph Geni

Reviewer: Morton Bast
We live in an incredibly busy world.
The pace of life is often frantic,
our minds are always busy,
and we're always doing something.
So with that in mind,
I'd like you just to take a moment
to think, when did you last take
any time to do nothing?
Just 10 minutes, undisturbed?
And when I say nothing, I do mean nothing.
So that's no emailing,
texting, no Internet,
no TV, no chatting, no eating, no reading.
Not even sitting there
reminiscing about the past
or planning for the future.
Simply doing nothing.
I see a lot of very blank faces.

(Laughter)

You probably have to go a long way back.
And this is an extraordinary thing, right?
We're talking about our mind.
The mind, our most valuable
and precious resource,
through which we experience
every single moment of our life.
The mind that we rely upon
to be happy, content,
emotionally stable as individuals,
and at the same time,
to be kind and thoughtful
and considerate
in our relationships with others.
This is the same mind that we depend upon
to be focused, creative, spontaneous,
and to perform at our very best
in everything that we do.
And yet, we don't take
any time out to look after it.
In fact, we spend more time
looking after our cars,
our clothes and our hair than we --
okay, maybe not our hair,

(Laughter)

but you see where I'm going.
The result, of course,
is that we get stressed.
You know, the mind whizzes away
like a washing machine
going round and round,
lots of difficult, confusing emotions,
and we don't really know
how to deal with that.
And the sad fact
is that we are so distracted
that we're no longer present
in the world in which we live.
We miss out on the things
that are most important to us,
and the crazy thing
is that everybody just assumes,
that's the way life is, so we've just
kind of got to get on with it.
That's really not how it has to be.
So I was about 11 when I went along
to my first meditation class.
And trust me, it had all the stereotypes
that you can imagine,
the sitting cross-legged on the floor,
the incense, the herbal tea,
the vegetarians, the whole deal,
but my mom was going and I was intrigued,
so I went along with her.
I'd also seen a few kung fu movies,
and secretly I kind of thought
I might be able to learn how to fly,
but I was very young at the time.
Now as I was there, I guess,
like a lot of people,
I assumed that it was just
an aspirin for the mind.
You get stressed, you do some meditation.
I hadn't really thought that it could be
sort of preventative in nature,
until I was about 20, when a number
of things happened in my life
in quite quick succession,
really serious things
which just flipped my life upside down
and all of a sudden
I was inundated with thoughts,
inundated with difficult emotions
that I didn't know how to cope with.
Every time I sort of pushed one down,
another one would pop back up again.
It was a really very stressful time.
I guess we all deal with stress
in different ways.
Some people will bury themselves in work,
grateful for the distraction.
Others will turn to their friends,
their family, looking for support.
Some people hit the bottle,
start taking medication.
My own way of dealing with it
was to become a monk.
So I quit my degree,
I headed off to the Himalayas,
I became a monk, and I started
studying meditation.
People often ask me
what I learned from that time.
Well, obviously it changed things.
Let's face it, becoming a celibate monk
is going to change a number of things.
But it was more than that.
It taught me -- it gave me
a greater appreciation,
an understanding for the present moment.
By that I mean not being lost in thought,
not being distracted,
not being overwhelmed
by difficult emotions,
but instead learning how to be
in the here and now,
how to be mindful, how to be present.
I think the present moment
is so underrated.
It sounds so ordinary,
and yet we spend so little time
in the present moment
that it's anything but ordinary.
There was a research paper that came
out of Harvard, just recently,
that said on average, our minds
are lost in thought
almost 47 percent of the time.
47 percent.
At the same time, this sort
of constant mind-wandering
is also a direct cause of unhappiness.
Now we're not here for that long anyway,
but to spend almost half
of our life lost in thought
and potentially quite unhappy,
I don't know, it just kind
of seems tragic, actually,
especially when there's something
we can do about it,
when there's a positive,
practical, achievable,
scientifically proven technique
which allows our mind to be more healthy,
to be more mindful and less distracted.
And the beauty of it is that even though
it need only take about 10 minutes a day,
it impacts our entire life.
But we need to know how to do it.
We need an exercise.
We need a framework
to learn how to be more mindful.
That's essentially what meditation is.
It's familiarizing ourselves
with the present moment.
But we also need to know
how to approach it in the right way
to get the best from it.
And that's what these are for,
in case you've been wondering,
because most people assume
that meditation
is all about stopping thoughts,
getting rid of emotions,
somehow controlling the mind,
but actually it's quite
different from that.
It's more about stepping back,
sort of seeing the thought clearly,
witnessing it coming and going,
emotions coming and going
without judgment,
but with a relaxed, focused mind.
So for example, right now,
if I focus too much on the balls,
then there's no way I can relax
and talk to you at the same time.
Equally, if I relax too much
talking to you,
there's no way I can focus on the balls.
I'm going to drop them.
Now in life, and in meditation,
there'll be times when the focus
becomes a little bit too intense,
and life starts to feel a bit like this.
It's a very uncomfortable
way to live life,
when you get this tight and stressed.

Of course in meditation --
(Snores)
we're going to end up falling asleep.
So we're looking for a balance,
a focused relaxation
where we can allow thoughts to come and go
without all the usual involvement.
Now, what usually happens
when we're learning to be mindful
is that we get distracted by a thought.
Let's say this is an anxious thought.
Everything's going fine,
and we see the anxious thought.
"Oh, I didn't realize
I was worried about that."
You go back to it, repeat it.
"Oh, I am worried.
I really am worried.
Wow, there's so much anxiety."
And before we know it, right,
we're anxious about feeling anxious.

(Laughter)

You know, this is crazy.
We do this all the time,
even on an everyday level.
If you think about the last time
you had a wobbly tooth.
You know it's wobbly,
and you know that it hurts.
But what do you do every 20, 30 seconds?
(Mumbling)
It does hurt.
And we reinforce the storyline, right?
And we just keep telling ourselves,
and we do it all the time.
And it's only in learning
to watch the mind in this way
that we can start to let go
of those storylines and patterns of mind.
But when you sit down
and you watch the mind in this way,
you might see many different patterns.
You might find a mind
that's really restless and --
the whole time.

You might find a mind that's very dull
and boring, and it's just,
almost mechanical,
it just seems it's as if you're
getting up, going to work,
eat, sleep, get up, work.
Or it might just be
that one little nagging thought
that just goes round and round your mind.
Well, whatever it is,
meditation offers the opportunity,
the potential to step back
and to get a different perspective,
to see that things aren't always
as they appear.
We can't change every little thing
that happens to us in life,
but we can change
the way that we experience it.
That's the potential
of meditation, of mindfulness.

All you need to do
is to take 10 minutes out a day
to step back, to familiarize yourself
with the present moment
so that you get to experience
a greater sense
of focus, calm and clarity in your life.
Thank you very much.

(Applause)

license: MIT

repository: prewittdavon/TEDVis

branch_name: refs/heads/master

extension: md

gha_language: Python

gha_license_id: MIT

license_type: permissive

repo_name: prewittdavon/TEDVis


text:
# Advanced usage

svelte-spa-router is simple by design. A minimal router is easy to learn and implement, adds minimum overhead, and leaves more control in the hands of the developers.

Thanks to the many features of Svelte 3 or other components in the ecosystem, svelte-spa-router can be used to get many more "advanced" features. This document explains how to achieve certain results with svelte-spa-router beyond what's offered by the component itself.

- [Route transitions](#route-transitions)
- [Querystring parsing](#querystring-parsing)
- [Nested routers](#nested-routers)
- [Route groups](#route-groups)

## Route transitions

It's easy to add a nice transition between routes, leveraging the built-in [transitions](https://svelte.dev/docs#Transitions) of Svelte 3.

For example, to make your components fade in gracefully, you can wrap the markup in a container (e.g. `<div>`, or `<section>`, etc) and attach a Svelte transition to that. For example:

````svelte
<div in:fade="{{duration: 500}}">
    <h2>Component's code goes here</h2>
</div>

<script>
import {fade} from 'svelte/transition'
</script>
````

When you apply the transition to multiple components, you can get a smooth transition effect:

![Example of transitions](/img/transitions.gif)

For more details: [official documentation](https://svelte.dev/docs#Transitions) on Svelte transitions.

## Querystring parsing

As the main documentation for svelte-spa-router mentions, you can extract parameters from the "querystring" in the hash of the page. This allows you to build apps that navigate to pages such as `#/search?query=hello+world&sort=title`.

The router has built-in support for returning the value of the "querystring", but it only returns the full string and doesn't perform any parsing. Components can access the "querystring" part of the hash from the `$querystring` store in the svelte-spa-router component. For example:

````svelte
<script>
import {location, querystring} from 'svelte-spa-router'
</script>
<p>The current page is: {$location}</p>
<p>The querystring is: {$querystring}</p>
````

When visiting the page `#/search?query=hello+world&sort=title`, this would generate:

````text
The current page is: /search
The querystring is: query=hello+world&sort=title
````

Most times, however, you might want to parse the "querystring" into a dictionary, to be able to use those values inside your application easily. There are multiple ways of doing that (some as simple as [a few lines of JavaScript](https://stackoverflow.com/questions/2090551/parse-query-string-in-javascript)), but a good, robust and safe solution is to rely on the popular library [qs](https://www.npmjs.com/package/qs).

For example, changing the component above to:

````svelte
<script>
import {parse} from 'qs'
import {querystring} from 'svelte-spa-router'

// Use a reactive statement to ensure parsed
// is updated every time $querystring changes
$: parsed = parse($querystring)
</script>
<code>{JSON.stringify(parsed)}</code>
````

With the same URL as before, the result would be:

````text
{"query":"hello world","sort":"title"}
````

qs supports advanced things such as arrays, nested objects, etc. Check out their [README](https://github.com/ljharb/qs) for more information.

## Nested routers

The `<Router>` component of svelte-spa-router can be nested without issues.

For example, consider an app with these four components:

````svelte
<!-- App.svelte -->
<Router {routes}/>
<script>
import Router from 'svelte-spa-router'
import Hello from './Hello.svelte'
// Routes for the "outer router"
const routes = {
    '/hello/*': Hello,
}
</script>

<!-- Hello.svelte -->
<h2>Hello!</h2>
<Router {routes}/>
<script>
import Router from 'svelte-spa-router'
import FullName from './FullName.svelte'
import ShortName from './ShortName.svelte'
// Routes for the "inner router"
// Note that the path is still the absolute one!
const routes = {
    '/hello/:first/:last': FullName,
    '/hello/:first': ShortName
}
</script>

<!-- FullName.svelte -->
<p>You gave us both a first name and last name!</p>
<p>First: {params.first}</p>
<p>Last: {params.last}</p>
<script>
export let params = {}
</script>

<!-- ShortName.svelte -->
<p>You shy person, giving us a first name only!</p>
<p>First: {params.first}</p>
<script>
export let params = {}
</script>
````

This works as you would expect:

- `#/hello/John` will show the `ShortName` component and pass "John" as `params.first`
- `#/hello/Jane/Doe` will show the `FullName` component, pass "Jane" as `params.first`, and "Doe" as `params.last`
- Both routes will also display the `Hello!` header.

Both routes first load the `Hello` route, as they both match `/hello/*` in the outer router. The inner router then loads the separate components based on the path.

Features like highlighting active links will still work, regardless of where those links are placed in the page (in which component).

However, keep in mind that routes are still defined in absolute terms also in inner routers, and whatever route you define must match the full path. For example, had we defined the inner route as `/:first/:last` without `/hello` as a prefix, we would get unexpected results.

## Route groups

You can get route groups by creating a Svelte component which nests the other components. For example:

````svelte
<!-- RouteA.svelte -->
<h2>This is route A</h2>

<!-- RouteB.svelte -->
<h2>This is route B</h2>

<!-- GroupRoute.svelte -->
<RouteA />
<RouteB />
<script>
import RouteA from './RouteA.svelte'
import RouteB from './RouteB.svelte'
</script>
````

When you add `GroupRoute` as a component in your router, you will render both `RouteA` and `RouteB`.

repository: hmmhmmhm/svelte-spa-router

path: /Advanced Usage.md

filename: Advanced Usage.md

repo_name: hmmhmmhm/svelte-spa-router


text:
# 🌐 emoji-countries
The list of the typical emojis of all countries

This emojis list will be used by the [Emoji Homepage](http://emojihomepage.com) 👀.
However, as it is an open source initiative, all other emoji keyboards, websites and tools,
can and are welcome to adopt it 🛠. That way, we can easily find and use the relevant emojis for each country 🎉.

# Contributions

Changes and improvements are more than welcome! Feel free to fork and open a pull request against `master`.
When adding new emojis to the list you should add them both to this `README.md` and to `emoji-countries.json` file.

Ideas of what should be included:
* Food
* Animals
* Flowers
* Activities
* Anything else that you know that people associate the country with 👻

Please, when opening a pull request, consider adding the reason why each emojis is associated with the specific country.

# Countries

Ordered alphabetically

| Country | Emojis |
| --------|--------|
| 🇦🇺 Australia | 🐨🦈😎☀🌇🏖🏜🏄🏊👙🍞🌴🌳🍺🏘🏙🌉💰🃏⛏🚁🕷🐊🐍⚓🌊 |
| 🇧🇪 Belgium | 💎🧀🍫🍟🍲🍺🍻🎨🖼💶🇪🇺 |
| 🇧🇷 Brazil | ☕⚽👙🏖💃🎭🙌 |
| 🇧🇬 Bulgaria | 🦁🌹🌻🏖🏋⛷🏂🍷🥗🍅🥒🌯🏕🏞🍇👙⛰🏔☃🇪🇺 |
| 🇨🇦 Canada | 🍁🌲🦌🐿🏔🌨❄🎿☃⛄⛷🏂🥓🏒⚓🌊 |
| 🇨🇳 China | 🍚🐼🎍🐲🐉🀄 |
| 🇨🇷 Costa Rica | 🐊🐦🐠🐸🦋🦎👙🌴🍍🍹☕☀🌋🏖🌊 |
| 🇫🇷 France | 🧀🍟🍆🍮🐌🍞🥖🥞🥐🍾🍇🍷🐸🏛🏰🎨⚽🖼😍💋💕💘💄💅👗👒🛍💶🇪🇺🎿⚜🐓 |
| 🇩🇪 Germany | ⚽🍺🍻🍞🍟🍰🌭🧀🍫🏰💶🇪🇺 |
| 🇭🇺 Hungary | 🌶🍲🏰🌉🇪🇺 |
| 🇮🇳 India | 🐮🐄🐘🍛🍵🌴🐍🌶🐯🐅🍌🐒🕉☸ |
| 🇮🇪 Ireland | ☘🍀🍺🍻🥃🏰🐏🐑🎶💶🇪🇺 |
| 🇮🇹 Italy  | 👗👙🛍👞👠👡👢👒💄💍🍇🍊🍕🍝🍦🍨☕🍷🌋🏖🏛🏰🎨🖼⚓⚽💶🇪🇺🎿🧀😎🕶🌳 |
| 🇯🇵 Japan | 👘👹👺💮🍱⛩💴🐟🍤🍣🍥🍢🍘🍙🍚🍜🍡🍵🍶🍷🗾🗻🏙🏯🗼🎋🎍🎎🎏🎐🎑🐲🐉🥋 |
| 🇰🇪 Kenya | ☕🐘🦁🐯🐅🐆👟🐊 |
| 🇲🇽 Mexico | 🌶🌮🌯🌵🏖👙🎸🎙🎶🎨🖼🐢💀💃🦅 |
| 🇳🇱 Netherlands | 🌷🚲🧀⚓🍟🌬💶🇪🇺😱 |
| 🇷🇺 Russia | 🚀🐻⛪⛸🐰🐺🚇🚢✈🛰❄🏒 |
| 🇿🇦 South Africa | 🐘🦁🐯🐅🐆🐗🌳 |
| 🇪🇸 Spain | 🐂🌴🍊🍹🏖👙🏛🏰🎨🖼⚓🐟⚽💃💶🇪🇺 |
| 🇸🇪 Sweden | 🐟🐎❄☃🎸🚢🦌🌳💶🇪🇺 |
| 🇨🇭 Switzerland | ⌚🏦🏔⛰🍫🐮🐄🧀⛷🏂🚠🎿🤑💰 |
| 🇬🇧 UK | 💂💷🏰🌂☔🎡🍵🌉⚽🐿 |
| 🇺🇸 USA  | 🗽🦅🐻🐍🎥🎬🍿🥓🌭🍔🍟🍏📱🏈⚾⛹🚀💵💸💰🏙🌉🎰⚓🦈🏞☃🌊🐊🐿🌽🥞🌪🎷🗞🤳🛰🎲 |

# License

**emoji-countries** is licensed under the [MIT license](https://github.com/EmojiHomepage/emoji-countries/blob/master/LICENSE).

Please, if you use the JSON provided in this repo, add a relevant link to it.

repository: EmojiHomepage/emoji-countries

repo_name: EmojiHomepage/emoji-countries


text:
# Flickster_ios
# Project 1 - Flickster

Flickster is a movies app using the [The Movie Database API](http://docs.themoviedb.apiary.io/#).

Time spent: 18 hours spent in total

## User Stories

The following **required** functionality is completed:

- [x] User can view a list of movies currently playing in theaters. Poster images load asynchronously.
    * API call to fetch movies using the Movie Database API
- [x] User can view movie details by tapping on a cell.
    * Standard Navigation controller functionality to segue to movie details view
- [x] User sees loading state while waiting for the API.
    * To prevent any pop ups and cleaner UI I added a progress bar at the top that displays when an API call is in progress
- [x] User sees an error message when there is a network error.
    * When API call returns an error, offline view will display

    ![Network Error Screenshot](errorScreenshot.png)

- [x] User can pull to refresh the movie list.
    * UIRefreshControl connected to tableView

The following **optional** features are implemented:

- [x] Add a tab bar for **Now Playing** and **Top Rated** movies.
    * implemented a tab bar, tableView will update depending on which tab is selected
- [x] Add a search bar.
    * movies are searchable in either Now Playing or Top Rated tab option
- [x] All images fade in.
    * standard animations functionality to fade images in as they are loading on screen
- [x] Customize the navigation bar.
    * Styling to match color scheme

The following **additional** features are implemented:

- [x] Star ratings
    * I wanted to have an easy visual for users to see the ratings of movies instead of just a rating number.  I utilized [Cosmos CocoaPods](https://github.com/marketplacer/Cosmos) to accomplish this.
- [x] View animations for movie details
    * User can expand/contract overview text in movie details view
## Video Walkthrough

Here's a walkthrough of implemented user stories:

![Video Walkthrough](flicksterGiphy_2.gif)

GIF created with [LiceCap](http://www.cockos.com/licecap/).

## Notes

The two biggest challenges were implementing the search bar and implementing a gradient view for the bottom of each cell.  The search bar was difficult to implement since there were lots of variables to consider with the filtered data, and edge cases for when the user clicks the cancel button, the search button, etc.  I also spent a long time with the gradient view and animations for the movie details view since it took me a while to grasp an understanding of CGRect.  Additionally, I spent some time figuring out the dimensions of the poster images in the table view cell and in the details view as to not distort the image yet still maintain an appropriate crop of the poster image in the views.

## License

    Copyright [2016] [Priscilla Lok]

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

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

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


text:
---
layout: post
title:      "Thanks, ItMemesAlot"
date:       2020-03-20 03:59:20 +0000
permalink:  thanks_itmemesalot
---

**Project Introduction**

Hello, my name is Naya Willis. The rails project that I've done is called ItMemesAlot. It's a social media web application that curates Memes posted by many different individuals. This would be the typical flow, 1. A user would sign up, and then once logged in they will be redirected to their show page. On that show page, they'll have a notification section, and a posts section showing all of the posts that they've uploaded.

**Authentication**

Three words for you, "I used Devise". Need I say any more?

**My Models**

My models include the following

1. User
2. Post
3. Comment
4. Like

A user is a person interacting with the application, such as uploading the meme, and commenting or liking a meme. The association is a user who has many posts, has many posts through likes, and comments. A post would be the actual meme, and it belongs to a user. It has many users through comments and likes and has many comments and likes. A comment is an interest left on a post and it belongs to a Post and a User. Lastly, a Like is also another way of showing interest. That model belongs to a Post and a User.

**My Controllers**

For each model above, I created a controller. I created the necessary actions in each controller to reflect the correct paths and direction throughout the use of the application. For example, I used a new and create action in the posts controller that enables a user to upload a post. It went a little something like this (with the user being logged in of course).

```
def new
	@post = current_user.posts.build
end
```

```
def create
	@post = current_user.posts.build(post_params)
	if @post.save
		redirect_to user_post_path(current_user, @post)
	end
end
```

This is only part of what building this project entailed. Many other actions assisted in making this program run correctly and smoothly.

**My Views**

Certain actions required there be associated view templates. A new action required a new.html.erb file, a show action required a show.html.erb file, so and so forth. Throughout my view templates, I also utilized what you would call renders and partials with locals. You'll often see them used for forms, e.g. (`posts/_form.html.erb ==  <%= render "posts/form" %>`). Or, a partial, e.g. (`posts/_comment.html.erb == <%= render partial: "posts/comment, locals: { comment: @comment }" %>`). Then, I had a little fun with the styling part of it by using Tailwind-CSS which is a utility-first CSS framework. It is way less opinionated than Bootstrap!

**In Conclusion**

This project has been a blast to work on. I appreciate all that I learned so far with using Rails for Software Development. It's a very involved Web Framework, and I feel that I barely scratched the surface of all of the magic that it offers. Coming up, Javascript!

extension: markdown


text:
Gradle Git version plugin
================================================================================

This plugin automatically sets the version of a Gradle project based on the
current git revision.

## Features and description

### Version format

Versions are based on the output of `git describe`. A typical version set by
the plugin will look something like:

    0.2.3-23-gabcabcf-SNAPSHOT

The first part is the most recent git tag (in this case `0.2.3`), then comes
the number of revisions since that tag (`23`), and the abbreviated hash of the
current commit prepended with a 'g' (`gabcabcf`). As of v1.0, the plugin always
appends the '-SNAPSHOT' designator.

### Submodule support

The plugin can be used on a normal git repository, or from within a submodule.
If it finds it is in a submodule, it will locate the correct `.git` directory
within the parent repository.

### Multi-project support

If you have multiple projects within a directory, it is often desirable to
version them independently. For projects that are not at the root of a
repository, the plugin will use the version of the last commit *in that
project's directory*. That is, if you have the following folder structure and
last commits:

    myRepository
    `-- .git
    `-- project1                    # 0.3-329-gabc1234
        `-- src                     # 0.6-1-g2342345
    `-- project2                    # 1.0
        `-- src                     # 1.1-17-g009911c

If project1 and project2 both apply this plugin, project 1's version will be
set to `0.6-1-g2342345-SNAPSHOT`, while project 2's version will be set to
`1.1-17-g009911c-SNAPSHOT`, as they are the two most recent commits within
those projects.

## How to use

The plugin is available through the
[Gradle plugins repo](https://plugins.gradle.org/plugin/com.dmdirc.git-version).
If you are using Gradle 2.1 or newer, you can use the new plugin mechanism to
use this plugin by simply adding:

    plugins {
      id "com.dmdirc.git-version" version "1.1"
    }

to the top of your `build.gradle`. Alternatively, the plugin can be obtained
from the jcenter repository and applied manually:

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath group: 'com.dmdirc', name: 'git-version', version: '1.1'
        }
    }

    apply plugin: 'com.dmdirc.git-version'

It's generally best to apply the version plugin before other plugins (such as
the maven-publish plugin) as they may try and use the version.

repository: DMDirc/gradle-git-version-plugin

gha_language: Groovy

repo_name: DMDirc/gradle-git-version-plugin


text:
---
title: Location
---

import SnackEmbed from '~/components/plugins/SnackEmbed';

This module allows reading geolocation information from the device. Your app can poll for the current location or subscribe to location update events.

You must request permission to access the user's location before attempting to get it. To do this, you will want to use the [Permissions](../permissions/) API. You can see this in practice in the following example.

<SnackEmbed snackId="H14SNiW3g" />

### `Expo.Location.getCurrentPositionAsync(options)`

Get the current position of the device.

#### Arguments

-   **options (_object_)** --

      A map of options:

    -   **enableHighAccuracy (_boolean_)** -- Whether to enable high-accuracy mode. For low-accuracy the implementation can avoid geolocation providers that consume a significant amount of power (such as GPS).
    -   **maximumAge (_number_)** -- (Android only). If specified, allow returning a previously cached position that is at most this old in milliseconds. If not specified, always gets a new location. On iOS this option is ignored and a new location is always returned.

#### Returns

Returns a promise resolving to an object with the following fields:

-   **coords (_object_)** -- The coordinates of the position, with the following fields:
    -   **latitude (_number_)** -- The latitude in degrees.
    -   **longitude (_number_)** -- The longitude in degrees.
    -   **altitude (_number_)** -- The altitude in meters above the WGS 84 reference ellipsoid.
    -   **accuracy (_number_)** -- The radius of uncertainty for the location, measured in meters.
    -   **altitudeAccuracy (_number_)** -- The accuracy of the altitude value, in meters (iOS only).
    -   **heading (_number_)** -- Horizontal direction of travel of this device, measured in degrees starting at due north and continuing clockwise around the compass. Thus, north is 0 degrees, east is 90 degrees, south is 180 degrees, and so on.
    -   **speed (_number_)** -- The instantaneous speed of the device in meters per second.
-   **timestamp (_number_)** -- The time at which this position information was obtained, in milliseconds since epoch.

### `Expo.Location.watchPositionAsync(options, callback)`

Subscribe to location updates from the device. Please note that updates will only occur while the application is in the foreground. Background location tracking is [planned](https://expo.canny.io/feature-requests/p/background-location-tracking), but not yet implemented.

#### Arguments

-   **options (_object_)** --

      A map of options:

    -   **enableHighAccuracy (_boolean_)** -- Whether to enable high accuracy mode. For low accuracy the implementation can avoid geolocation providers that consume a significant amount of power (such as GPS).
    -   **timeInterval (_number_)** -- (Android only) Minimum time to wait between each update in milliseconds. On iOS this option is ignored.
    -   **distanceInterval (_number_)** -- Receive updates only when the location has changed by at least this distance in meters.

-   **callback (_function_)** --

      This function is called on each location update. It is passed exactly one parameter: an object with the following fields:

    -   **coords (_object_)** -- The coordinates of the position, with the following fields:
        -   **latitude (_number_)** -- The latitude in degrees.
        -   **longitude (_number_)** -- The longitude in degrees.
        -   **altitude (_number_)** -- The altitude in meters above the WGS 84 reference ellipsoid.
        -   **accuracy (_number_)** -- The radius of uncertainty for the location, measured in meters.
        -   **altitudeAccuracy (_number_)** -- The accuracy of the altitude value, in meters (iOS only).
        -   **heading (_number_)** -- Horizontal direction of travel of this device, measured in degrees starting at due north and continuing clockwise around the compass. Thus, north is 0 degrees, east is 90 degrees, south is 180 degrees, and so on.
        -   **speed (_number_)** -- The instantaneous speed of the device in meters per second.
    -   **timestamp (_number_)** -- The time at which this position information was obtained, in milliseconds since epoch.

#### Returns

Returns a promise resolving to a subscription object, which has one field:

-   **remove (_function_)** -- Call this function with no arguments to remove this subscription. The callback will no longer be called for location updates.

### `Expo.Location.getProviderStatusAsync()`

Check status of location providers.

#### Returns

Returns a promise resolving to an object with the following fields:

-   **locationServicesEnabled (_boolean_)** -- Whether location services are enabled.
-   **gpsAvailable (_boolean_)** (android only) -- If the GPS provider is available, if yes, location data will be from GPS.
-   **networkAvailable (_boolean_)** (android only) -- If the network provider is available, if yes, location data will be from cellular network.
-   **passiveAvailable (_boolean_)** (android only) -- If the passive provider is available, if yes, location data will be determined passively.

### `Expo.Location.getHeadingAsync()`

Gets the current heading information from the device

#### Returns

Object with:

- **magHeading (_number_)** — measure of magnetic north in degrees
- **trueHeading (_number_)** — measure of true north in degrees (needs location permissions, will return -1 if not given)
- **accuracy (_number_)** — level of callibration of compass.
  - 3: high accuracy, 2: medium accuracy, 1: low accuracy, 0: none
  - Reference for iOS: 3: < 20 degrees uncertainty, 2: < 35 degrees, 1: < 50 degrees, 0: > 50 degrees

### `Expo.Location.watchHeadingAsync(callback)`

Suscribe to compass updates from the device

#### Arguments

- **callback (_function_)** --

    This function is called on each compass update. It is passed exactly one parameter: an object with the following fields:

    - **magHeading (_number_)** — measure of magnetic north in degrees
    - **trueHeading (_number_)** — measure of true north in degrees (needs location permissions, will return -1 if not given)
    - **accuracy (_number_)** — level of callibration of compass.
    	- 3: high accuracy, 2: medium accuracy, 1: low accuracy, 0: none
    	- Reference for iOS: 3: < 20 degrees uncertainty, 2: < 35 degrees, 1: < 50 degrees, 0: > 50 degrees

#### Returns

Returns a promise resolving to a subscription object, which has one field:

- **remove (function)** — Call this function with no arguments to remove this subscription. The callback will no longer be called for location updates.

### `Expo.Location.geocodeAsync(address)`

Geocode an address string to latitiude-longitude location.

> **Note**: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error so they have to be managed properly.
>
> On Android, you must request a location permission (`Expo.Permissions.LOCATION`) from the user before geocoding can be used.

#### Arguments

- **address (_string_)** -- A string representing address, eg. "Baker Street London"

#### Returns

Returns a promise resolving to an array (in most cases its size is 1) of geocoded location objects with the following fields:

-   **latitude (_number_)** -- The latitude in degrees.
-   **longitude (_number_)** -- The longitude in degrees.
-   **altitude (_number_)** -- The altitude in meters above the WGS 84 reference ellipsoid.
-   **accuracy (_number_)** -- The radius of uncertainty for the location, measured in meters.

### `Expo.Location.reverseGeocodeAsync(location)`

Reverse geocode a location to postal address.

> **Note**: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error so they have to be managed properly.

> On Android, you must request a location permission (`Expo.Permissions.LOCATION`) from the user before geocoding can be used.

#### Arguments

-   **location (_object_)** -- An object representing a location:

    -   **latitude (_number_)** -- The latitude of location to reverse geocode, in degrees.
    -   **longitude (_number_)** -- The longitude of location to reverse geocode, in degrees.

#### Returns

Returns a promise resolving to an array (in most cases its size is 1) of address objects with following fields:

-   **city (_string_)** -- City name of the address.
-   **street (_string_)** -- Street name of the address.
-   **region (_string_)** -- Region/area name of the address.
-   **postalCode (_string_)** -- Postal code of the address.
-   **country (_string_)** -- Localized country name of the address.
-   **name (_string_)** -- Place name of the address, for example, "Tower Bridge".

### `Expo.Location.setApiKey(apiKey)`

Sets a Google API Key for using Geocoding API. This method can be useful for Android devices that do not have Google Play Services, hence no Geocoder Service. After setting the key using Google's API will be possible.

#### Arguments

-   **apiKey (_string_)** -- API key collected from Google Developer site.

gha_language: Objective-C


text:
**[overview](#overview) | [launching the notebooks](#launching-the-notebooks) | [running the notebooks](#running-the-notebooks) | [issues](#issues) | [contributing](#for-contributors)**

# gpgLabs

[![Syzygy](https://img.shields.io/badge/launch-syzygy-important)](https://ubc.syzygy.ca/jupyter/hub/user-redirect/git-pull?repo=https%3A%2F%2Fgithub.com%2Fgeoscixyz%2FgpgLabs&urlpath=tree%2FgpgLabs%2Fnotebooks%2Findex.ipynb)
[![binder](http://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/geoscixyz/gpgLabs/main?filepath=notebooks%2Findex.ipynb)
[![SimPEG](https://img.shields.io/badge/powered%20by-SimPEG-blue.svg)](http://simpeg.xyz)

## Overview

This is a repo of interactive examples for http://gpg.geosci.xyz.

The notebooks are available on
- [Binder](https://mybinder.org/v2/gh/geoscixyz/gpgLabs/main?filepath=notebooks%2Findex.ipynb)

<!-- <img src="https://em.geosci.xyz/_images/DC_LayeredEarth_notebook.png" width=60% align="center">
 -->

## Launching the notebooks

The notebooks can be run online through [Binder](#Binder), or [downloaded and run locally](#Locally).

### UBC Open JupyterHub

These instructions are for running the notebooks on the UBC open JupyterHub: https://open.jupyter.ubc.ca

1. Login to the JupyterHub using your cwl

2. Under "Other" open a terminal

![open-jupyterhub-terminal](https://user-images.githubusercontent.com/6361812/186590219-7c8a5cab-adbb-42cb-b848-2f0ede3f5698.png)

3. Copy-paste the following line and hit enter to clone this repository
```
git clone https://github.com/geoscixyz/gpgLabs.git
```

4. From the same terminal, run the following line of code to enter the gpgLabs directory
```
cd gpgLabs
```

5. Run the following line to setup the environment we need for running the notebooks
```
sh setup.sh
```

6. Now you should be able to run the notebooks! You can close the terminal and navigate to the index notebook

![image](https://user-images.githubusercontent.com/6361812/186591509-18bc8302-a230-48c3-9827-38efa08865a3.png)

7. For all notebooks, you will need to set the kernel to `e350`

![image](https://user-images.githubusercontent.com/6361812/186592503-6d4f7f3d-5c79-45f6-8954-af4a74f67a31.png)

### Binder

[![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/geoscixyz/gpgLabs/main?filepath=notebooks%2Findex.ipyn)

1. Launch the binder by clicking on the badge above or going to: https://mybinder.org/v2/gh/geoscixyz/gpgLabs/main?filepath=notebooks%2Findex.ipynb.
   This can sometimes take a couple minutes, so be patient...

2. Select the notebook of interest from the contents

3. [Run the Jupyter notebook](#Running-the-notebooks)

![Binder-steps](https://em.geosci.xyz/_images/binder-steps.png)

### Locally

To run them locally, you will need to have python installed, preferably through [anaconda](https://www.anaconda.com/download/).

You can then clone this reposiroty. From a command line, run

```
git clone https://github.com/geoscixyz/gpgLabs.git
```

Then `cd` into `gpgLabs`

```
cd gpgLabs
```

To setup your software environment, we recommend you use the provided conda environment

```
conda env create -f environment.yml
conda activate geosci-labs
```

alternatively, you can install dependencies through pypi
```
pip install -r requirements.txt
```

You can then launch Jupyter
```
jupyter notebook
```

Jupyter will then launch in your web-browser.

## Running the notebooks

Each cell of code can be run with `shift + enter` or you can run the entire notebook by selecting `cell`, `Run All` in the toolbar.

![cell-run-all](https://em.geosci.xyz/_images/run_all_cells.png)

For more information on running Jupyter notebooks, see the [Jupyter Documentation](https://jupyter.readthedocs.io/en/latest/)

## Issues

If you run into problems or bugs, please let us know by [creating an issue](https://github.com/geoscixyz/gpgLabs/issues/new) in this repository.

## For Contributors

We are glad you are interested in contributing!

This repo tracks [geosci-labs](https://github.com/geoscixyz/geosci-labs). To contribute code, ideas or bug-fixes, please head over to the [geosci-labs](https://github.com/geoscixyz/geosci-labs) repository.

repository: geoscixyz/gpgLabs

branch_name: refs/heads/main

gha_language: Jupyter Notebook

repo_name: geoscixyz/gpgLabs


text:
[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-SimpleGCM-green.svg?style=true)](https://android-arsenal.com/details/1/3248)
# SimpleGCM

Simple Google Cloud Messaging(GCM) integration library for Android.

# Why
Sometimes we want to send notifications to our users to notify them about something.
If we don't have a perfectly working example in our code library, we are always digging stackoverflow or etc. to see which permissions, classes, broadcast receivers, services, listeners that we need to implement our apps with google cloud messaging functionality.
But sometimes, things get messy.

With this library we can easily integrate GCM to our application with simpliest steps.

Receiving notification is only thing we care about, right?

# Library Features

* Receive GCM push messages.
* Get registrationId in background

# Usage
Add dependency and plugin to project level build.gradle.
```groovy
dependencies {
    compile 'com.cuneytayyildiz:simplegcm:1.0'
}
apply plugin: 'com.google.gms.google-services'
```

Add classpath and repository to root level build.gradle.
```groovy
dependencies {
    classpath 'com.google.gms:google-services:2.+'
}

repositories {
  mavenCentral()
}

```
* In your `Application` class implement [GcmListener](https://github.com/Swisyn/SimpleGCM/blob/master/app/src/main/java/com/cuneytayyildiz/simplegcm/GcmListener.java) interface with two methods:
  * `onMessage()`
  * `sendRegistrationIdToBackend()`

* In your `MainActivity` `onCreate()`, call `SimpleGcm.init(this);`

If you want to access the `registrationId` after the registration has finished, you can use `SimpleGcm.isRegistered(Context context)`, `SimpleGcm.getRegistrationId(Context context)`

**IMPORTANT STEP**  Download your google-services.json file and copy to app module. GCM will use this .json file to get senderID and other informations. ([Download it from here](https://developers.google.com/mobile/add?platform=android&cntapi=gcm&cnturl=https:%2F%2Fdevelopers.google.com%2Fcloud-messaging%2Fandroid%2Fclient&cntlbl=Continue%20Adding%20GCM%20Support&%3Fconfigured%3Dtrue))

# References

[Developers Google GCM](https://developers.google.com/cloud-messaging/android/client)

[GCM github page](https://github.com/google/gcm)

# Licence
```
The MIT License (MIT)

Copyright (c) 2016 Cüneyt Ayyıldız

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

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

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

repository: Swisyn/SimpleGCM

gha_language: Java

repo_name: Swisyn/SimpleGCM


text:
# Terminal Progress bar with image Resizing

Here I just take example of image resizing for displaying progress bar.
when we convert lots of images at time we can use progress bar to show how many images are resized.

### For this purpose I am using tqdm librabry
` pip install tqdm `

This Library is for showing progress bar

### For Resizing images
` pip install Pillow `

repository: Ruth-ikegah/python-mini-projects

repo_name: Ruth-ikegah/python-mini-projects


text:
---
title: Private Key Not Working
description: Private Keys & Passwords
tags:
  - Private Keys
priority: 70
date_published: '2017-07-05'
date_modified: '2020-07-01'
---

Be sure there is no space at the beginning or end of your private key. We validate based on the number of characters. If you saved another version (for example, the UTC / Keystore file) it may also be worth trying that file as well.

Please be sure that you are **carefully and accurately** typing your private key. A single wrong character will open a different wallet than "yours".

Some wallets, like Exodus, may export a private key that begins with `0x`. If you remove these two characters from the beginning, you may be able to access your account.

For reference private key looks like this: `afdfd9c3d2095ef696594f6cedcae59e72dcd697e2a7521b1578140422a4f890`

## Related articles

[Lost Private Key](/troubleshooting/accessing-wallet/lost-eth-private-key)
[Private Key vs Keystore File](/general-knowledge/ethereum-blockchain/difference-between-wallet-types)


text:
# Clean Architecture

## Humble Object Pattern

根据可测试性，将容易测试的部分和难测试的部分分开，形成明显的边界（boundary）

Presenter -> View (Humble Object)
Database gateway -> DataBase (Humble Object)

## 系统设计策略

怎么在高成本整洁架构与不过度设计中寻找平衡，渐进式的策略。

1. 一开始不注意架构设计的话，后续添加成本很高
1. YAGNI you aren't going to need it. 设计、实现组件边界成本很高

系统是不断变化的，根据变化的趋势不断调整组件与边界。

But this is not a one-time decision. You don’t simply decide at the start of a project which boundaries to implement and which to ignore. Rather, you watch. You pay attention as the system evolves. You note where boundaries may be required, and then carefully watch for the first inkling of friction because those boundaries don’t exist.
At that point, you weigh the costs of implementing those boundaries versus the cost of ignoring them—and you review that decision frequently. Your goal is to implement the boundaries right at the inflection point where the cost of implementing becomes less than the cost of ignoring.
It takes a watchful eye.

## Partial Boundary

One way to construct a partial boundary is to do all the work necessary to create independently compilable and deployable components, and then simply keep them together in the same component. The reciprocal interfaces are there, the input/output data structures are there, and everything is all set up—but we compile and deploy all of them as a single component.

做好分层分模块设计，但是暂时仍然作为整个组件发布。

1. Skip Last Step
1. One-Dimensional Boundaries
1. Facades

## Layers and Boundaries 25

1. Hunt The Wumpus 用这个例子分析，如何拆分模块，定义边界

gha_language: JavaScript


text:
---
published: true
layout: default
title: FontForge's math
---

*Being a brief description of the mathematics underlying various of
FontForge's commands
 It is presumed that you understand about parameterized splines, if not
look at the description of [Bézier curves](../../reference/bezier/).*

-   [Linear Transformations](#Linear)
-   [Finding maxima and minima of a spline](#maxima)
-   [Rasterizing a Glyph](#Rasterizing)
    -   finding intersections
    -   removing overlap
-   [Removing overlap (new algorithm proposal)](../../reference/overlap/)
-   [Approximating a spline](#Approximating)
-   [Stroking a spline](#Stroke)
-   [Approximating a cubic spline by a series of quadratic
    splines](../../reference/bezier/#ps2ttf)

* * * * *

Linear Transformations
----------------------

A linear transformation is one where the spline described by
transforming the end and control points will match the transformed
spline. This includes most of the common transformations you might wish:

-   translation
      ------ --- ----------
      *x'*   =   *x + dx*
      *y'*   =   *y + dy*
      ------ --- ----------

-   scaling
      ------ --- -------------
      *x'*   =   *s~x~ \* x*
      *y'*   =   *s~y~ \* y*
      ------ --- -------------

-   rotation
      ------ --- --------------------------
      *x'*   =   *cos(A)\*x + sin(A)\*y*
      *y'*   =   *-sin(X)\*x + cos(A)\*y*
      ------ --- --------------------------

-   skewing
      ------ --- -----------------
      *x'*   =   *x + sin(A)\*y*
      *y'*   =   *y*
      ------ --- -----------------

* * * * *

Finding maxima and minima of a spline
-------------------------------------

The maximum or minimum of a spline (along either the x or y axes) may be
found by taking the first derivative of that spline with respect to t.
So if we have a spline

>         x = ax*t3 + bx*t2 + cx*t +dx
>         y = ay*t3 + by*t2 + cy*t +dy

and we wish to find the maximum point with respect to the x axis we set:

>         dx/dt = 0
>         3*ax*t2 + 2*bx*t + cx = 0
>

and then using the quadratic formula we can solve for t:

t=

-2\*b~x~± sqrt(4\*b~x~^2^ - 4\*3\*a~x~\*c~x~)

-----------------------------------

2\*3\*a~x~

* * * * *

Finding points of inflection of a spline
----------------------------------------

A point of inflection occurs when d^2^y/dx^2^==0 (or infinity).

Unfortunately this does not mean that d^2^y/dt^2^==0 or d^2^x/dt^2^==0.

  -------------- ---------------------------------------------------------------------
  d^2^y/dx^2^=   d/dt ((dy/dt)/(dx/dt)) / dx/dt
                 ( ((dx/dt) \* d^2^y/dt^2^) - ((dy/dt) \* d^2^x/dt^2^)) / (dx/dt)^3^
  -------------- ---------------------------------------------------------------------

After a lot of algebra this boils down to the quadratic in t:

  --------------------------------- ------------------------------------ --
                                    3\*(a~x~\*b~y~-a~y~\*b~x~)\*t^2^ +
  3\*(c~x~\*a~y~-c~y~\*a~x~)\*t +
  c~x~\*b~y~-c~y~\*b~x~             = 0
  --------------------------------- ------------------------------------ --

If you examine this closely you will note that a quadratic spline
(a~y~==a~x~==0) can never have a point of inflection.

* * * * *

Rasterizing a glyph
-------------------

* * * * *

Approximating a spline
----------------------

Many of FontForge's commands need to fit a spline to a series of points.
The most obvious of these are the Edit-\>Merge, and Element-\>Simplify
commands, but many others rely on the same technique. Let us consider
the case of the Merge command, suppose we have the following splines and
we wish to remove the middle point and generate a new spline that
approximates the original two:

      ![](img/mergepre.png) =\> ![](img/mergepost.png)

FontForge uses a least squares approximation to determine the new
spline. It calculates the locations of several points along the old
splines, and then it guesses^[1](#guess-t)^ at t values for those
points.

Now a cubic [Bézier](../../reference/bezier/) spline is determined by its two end
points (P~0~ and P~1~) and two control points (CP~0~ and CP~1~, which
specify the slope at those end points). Here we know the end points, so
all we need is to find the control points. The spline can also be
expressed as a cubic polynomial:

> S(t) = a\*t^3^ + b\*t^2^ + c\*t +d
>      -- with --
>  d = P0
>  c = 3\*CP0 - 3\*P0
>  b = 3\*CP1 - 6\*CP0 + 3\*P0
>  a = P1 - 3\*CP1 + 3\*CP0 - P0
>      substituting
>  S(t) = (P1 - 3\*CP1 + 3\*CP0 - P0)\*t^3^ +
>    (3\*CP1 - 6\*CP0 + 3\*P0)\*t^2^ +
>    (3\*CP0 - 3\*P0)\*t +
>    P0
>      rearranging
>  S(t) = (-3\*t^3^ + 3\*t^2^) \* CP1 +
>    (3\*t^3^ - 6\*t^2^ + 3\*t) \* CP0 +
>    (P1-P0)\*t^3^ + 3\*P0\*t^2^ - 3\*P0\*t + P0

Now we want to minimize the sum of the squares of the difference between
the value we approximate with the new spline, S(t~i~), and the actual
value we were given, P~i~.

  --------- --------------------- ----------------------
            ![](img/Sigma28x33.png)   [ S(t~i~) - P~i~]^2^
  --------- --------------------- ----------------------

Now we have four unknown variables, the x and y coordinates of the two
control points. To find the minimum of the above error term we must take
the derivative with respect to each variable, and set that to zero. Then
we have four equations with four unknowns and we can solve for each
variable.

  --------- --------------------- ------------------------------------------------------------
            ![](img/Sigma28x33.png)   2\* (-3\*t^3^ + 3\*t^2^)\*[ S~x~(t~i~) - P~i.x~] = 0
            ![](img/Sigma28x33.png)   2\* (-3\*t^3^ + 3\*t^2^)\*[ S~y~(t~i~) - P~i.y~] = 0
            ![](img/Sigma28x33.png)   2\* (3\*t^3^ - 6\*t^2^ + 3\*t)\*[ S~x~(t~i~) - P~i.x~] = 0
            ![](img/Sigma28x33.png)   2\* (3\*t^3^ - 6\*t^2^ + 3\*t)\*[ S~y~(t~i~) - P~i.y~] = 0
  --------- --------------------- ------------------------------------------------------------

Happily for us, the x and y terms do not interact and my be solved
separately. The procedure is the same for each coordinate, so I shall
only show one:

  --------- --------------------- ------------------------------------------------------------ -------------------------------------------------------------------------- -----
            ![](img/Sigma28x33.png)   2\* (-3\*t^3^ + 3\*t^2^)\*[ S~x~(t~i~) - P~i.x~] = 0

            ![](img/Sigma28x33.png)   2\* (3\*t^3^ - 6\*t^2^ + 3\*t)\*[ S~x~(t~i~) - P~i.x~] = 0

  =\>

            ![](img/Sigma28x33.png)   (-3\*t^3^ + 3\*t^2^)\*                                       [ (-3\*t^3^ + 3\*t^2^) \* CP1~x~ +\                                        = 0
                                                                                (3\*t^3^ - 6\*t^2^ + 3\*t) \* CP0~x~ +\
                                                                                (P1~x~-P0~x~)\*t^3^ + 3\*P0~x~\*t^2^ - 3\*P0~x~\*t + P0~x~ - P~i.x~ ]
  --------- --------------------- ------------------------------------------------------------ -------------------------------------------------------------------------- -----

  --------- -------- --------------------- -------------------------------------------- --- --- --------------------- ------------------------ --------------------------------------------------------------------------
            CP1~x~   ![](img/Sigma28x33.png)   (-3\*t^3^ + 3\*t^2^)\*(-3\*t^3^ + 3\*t^2^)   =   -   ![](img/Sigma28x33.png)   (-3\*t^3^ + 3\*t^2^)\*   [ (3\*t^3^ - 6\*t^2^ + 3\*t) \* CP0~x~ +
                                                                                (P1~x~-P0~x~)\*t^3^ + 3\*P0~x~\*t^2^ - 3\*P0~x~\*t + P0~x~ - P~i.x~ ]
  --------- -------- --------------------- -------------------------------------------- --- --- --------------------- ------------------------ --------------------------------------------------------------------------

CP1~x~

=

-

![](img/Sigma28x33.png)

(-3\*t^3^ + 3\*t^2^)\*

[ (3\*t^3^ - 6\*t^2^ + 3\*t) \* CP0~x~ +
   (P1~x~-P0~x~)\*t^3^ + 3\*P0~x~\*t^2^ - 3\*P0~x~\*t + P0~x~ - P~i.x~ ]

* * * * *

  --------------------- --------------------------------------------
  ![](img/Sigma28x33.png)   (-3\*t^3^ + 3\*t^2^)\*(-3\*t^3^ + 3\*t^2^)
  --------------------- --------------------------------------------

Now this can be plugged into the other equation

  --------- --------------------- ------------------------------ -------------------------------------------------------------------------- -----
            ![](img/Sigma28x33.png)   (3\*t^3^ - 6\*t^2^ + 3\*t)\*   [ (-3\*t^3^ + 3\*t^2^) \* CP1~x~ +\                                        = 0
                                                                    (3\*t^3^ - 6\*t^2^ + 3\*t) \* CP0~x~ +\
                                                                    (P1~x~-P0~x~)\*t^3^ + 3\*P0~x~\*t^2^ - 3\*P0~x~\*t + P0~x~ - P~i.x~ ]
  --------- --------------------- ------------------------------ -------------------------------------------------------------------------- -----

And we can solve for CP0~x~ and then CP1~x~. The algebra becomes very
messy, with lots of terms, but the concepts are simple.

Thus we know where the control points are. We know where the end points
are. We have our spline.

### Why that didn't (quite) work

The above matrix yields a curve which is a good approximation to the
original two. But it has one flaw: There is no constraint placed on the
slopes, and (surprisingly) the slopes at the end-points of the above
method are not close enough to those of the original, and the human eye
can now detect the join between this generated spline and the two that
connect to it.

Generally we will know the slopes at the end points as well as the end
points themselves.

Let's try another approach, based on better geometry. Givens:

-   the start point
-   the slope at the start point
-   the end point
-   the slope at the end point

We want to find the two control points. Now it may seem that specifying
the slope specifies the control point but this is not so, it merely
specifies the direction in which the control point lies. The control
point may be anywhere along the line through the start point in that
direction, and each position will give a different curve.

So we can express the control point by saying it is CP~0~ = P~0~ + r~0~
![](img/delta0.png) where ![](img/delta0.png) is a vector in the direction of
the slope, and r~0~ is the distance in that direction. Similarly for the
end point: CP~1~ = P~1~ + r~1~ ![](img/delta1.png)

We want to find r~0~ and r~1~.

Converting from bezier control points into a polynomial gives us
 S(t) = a\*t^3^ + b\*t^2^ + c\*t + d

-   d = P~0~
-   c = 3\*(CP~0~ - P~0~)
-   b = 3\*(CP~1~ - CP~0~) - c
-   a = P~1~-P~0~ - c - b

Substituting we get

-   d = P~0~
-   c = 3\*r~0~\*![](img/delta0.png)
-   b = 3\*(P~1~-P~0~+r~1~\*![](img/delta1.png)-2\*r~0~![](img/delta0.png))
-   a = 2\*(P~0~-P~1~) + 3\*(r~0~![](img/delta0.png) -
    r~1~\*![](img/delta1.png))

For least squares we want to minimize ![](img/Sigma13x16.png)(S(t~i~) -
P~i~)^2^.
 taking derivatives with both r0 and r1 we get:

  --------- --------------------- ------------------------------------------------------------------------ ------------------------------------------------ --------- --------------------- ------------------------------- ------------------------------------------------------------------- ------- --------- --------------------- ------------------------- ------------------------------------------------------------------- -------
            ![](img/Sigma28x33.png)   2\* (3\*t^3^ - 6\*t^2^ + 3\*t)\*![](img/delta0.png)\*[ S(t~i~) - P~i~] = 0

            ![](img/Sigma28x33.png)   2\* (-3\*t^3^ + 3\*t^2^)\*![](img/delta1.png)\*[ S(t~i~) - P~i~] = 0         dividing by constants and substituting, we get             ![](img/Sigma28x33.png)   (3\*t^3^ - 6\*t^2^ + 3\*t)\*[   P~0~ - P~i~ + 3 \* (P~1~-P~0~\*t^2^ + 2 \* (P~0~ - P~1~)\*t^3^ +\   ] = 0             ![](img/Sigma28x33.png)   (-3\*t^3^ + 3\*t^2^)\*[   P~0~ - P~i~ + 3 \* (P~1~-P~0~\*t^2^ + 2 \* (P~0~ - P~1~)\*t^3^ +\   ] = 0
                                                                                ![](img/delta0.png)\*(3\*t - 6\*t^2^ + 3\*t^3^) \* r~0~ + \                                                                               ![](img/delta0.png)\*(3\*t - 6\*t^2^ + 3\*t^3^) \* r~0~ + \
                                                                                ![](img/delta1.png)\*(3\*t^2^ - 3\*t^3^) \* r~1~ +                                                                                ![](img/delta1.png)\*(3\*t^2^ - 3\*t^3^) \* r~1~ +
  --------- --------------------- ------------------------------------------------------------------------ ------------------------------------------------ --------- --------------------- ------------------------------- ------------------------------------------------------------------- ------- --------- --------------------- ------------------------- ------------------------------------------------------------------- -------

Again we have two linear equations in two unknowns (r0, and r1), and
(after a lot of algebraic grubbing) we can solve for them. One
interesting thing here is that the x and y terms do not separate but
must be summed together.

### Singular matrices

Very occasionally, a singular matrix will pop out of these equations.
Then what I do is calculate the slope vectors at the endpoints and then
try many reasonable lengths for those vectors and see which yields the
best approximation to the original curve (this gives us our new control
points).

This is very, very slow.

* * * * *

#### ^1^Guessing values for t

FontForge approximates the lengths of the two splines being merged. If
Point~i~= Spline1(old-t~i~), then we approximate ti by
     t~i~ = old-t~i~ \*len(spline1)/(len(spline1)+len(spline2)
 and if Point~i~= Spline2(old-t~i~)
     t~i~ = len(spline1)/(len(spline1)+len(spline2) + old-t~i~
\*len(spline2)/(len(spline1)+len(spline2)
 That is we do a linear interpolation of t based on the relative lengths
of the two splines.

* * * * *

Calculating the outline of a stroked path
-----------------------------------------

### A circular pen

PostScript supports several variants on the theme of a circular pen, and
FontForge tries to emulate them all. Basically PostScript "stroke"s a
path at a certain width by:

at every location on the curve
     find the normal vector at that location
     find the two points which are width/2 away from the curve
     filling in between those two points
 end

This is essentially what a circular pen does. The only aberrations
appear at the end-points of a contour, or at points where two splines
join but their slopes are not continuous. PostScript allows the user to
specify the behavior at joints and at end-points.

    ![](img/expand-pre.png) =\> ![](img/expand-post.png)

FontForge can't deal with an infinite number of locations, so it samples
the curve (approximately every em unit), and finds the two normal
points. These are on the edge of the area to be stroked, so FontForge
can approximate new contours from these edge points (using the [above
algorithm](#Approximating)).

PostScript pens can end in

-   A flat edge -- this is easy, we just draw a line from the end of one
    spline to the end of the other
-   A rounded edge -- here we just draw a semi-circle (making sure it
    goes in the right direction).
-   A butt edge -- just draw lines continuing the two splines, moving
    with the same slope and width/2 units long, and then join those
    end-points with a straight line.

Things are a bit more complex at a joint ![](img/expand-joint-pre.png) =\>
![](img/expand-joint-post.png), the green lines in the right image show
where the path would have gone had it not been constrained by a joint,
so on the inside of the joint FontForge must figure out where this
intersection occurs. While on the outside FontForge must figure out
either a round, miter or bevelled edge.

Unfortunately, the normal points are not always on the edge of the
filled region. If the curve makes a sharp bend, then one of the normal
points may end up inside the pen when it is centered somewhere else on
the original contour (similar to the case of a joint above).

So FontForge makes another pass through the edge points and figures out
which ones are actually internal points. After that it will approximate
contours.

Now if we start with an open contour, (a straight line, for example)
then we will end up with one closed contour. While if we start with a
closed contour we will end up with two closed contours (one on the
inside, and one on the outside). Unless there are places where the curve
doubles back on itself, then when can get arbetrarily many closed
contours.

### An elliptical pen

This is really just the same as a circular pen. Let us say we want an
ellipse which is twice as wide as it is high. Then before stroking the
path, let's scale it to 50% in the horizontal direction, then stroke it
with a circular pen, and then scale it back by 200% horizontally. The
result will be as if we had used an elliptical pen.

Obviously if the ellipse is at an angle to the glyph's axes, we must
apply a more complicated transformation which involves both rotation and
scaling.

### A rectangular pen (a calligraphic pen)

Things are subtly different between a rectangular pen and a circular
pen. We can no longer just find the points which are a given distance
away and normal to the curve. Except where the spline is parallel to one
edge of the pen, a the outer contour of a rectangular pen will be
stroked by one of its end-points. So all we need do is figure out where
a spline is parallel to the pen's sides, and look at the problem in
little chunks between those difficult points.

If we are between difficult points then life is very simple indeed. The
edge will always be stroked by the same end-point, which is a fixed
distance from the center of the pen, so all we need to do is translate
the original spline by this distance (and then fix it up so that t goes
from [0,1], but that's another easy transformation).

When we reach a point where the spline's slope is parallel to one edge
of the pen, then on the outside path we draw a copy of that edge of of
the pen, and on the inside edge we calculate a join as above.

### An arbitrary convex polygonal pen

The same method which works for a rectangle can be extended without too
much difficulty to any convex polygon. (MetaFont fonts can be drawn with
such a pen. I don't know if any are)

### A pen of variable width

FontForge does not currently support this (some of the assumptions
behind this algorithm are broken if the pen changes shape too rapidly).

### A pen at a varying angle

FontForge does not support this.


text:
# wcl-events
Parses WCL fights and converts it into SimC events

## How to use

```
python parse.py REPORTID FIGHTID [--print]
```

e.g. `python parse.py DCXQbaV8j26mxfwJ 237`

- REPORTID: Report ID for the log
- FIGHTID: Specific Fight ID that corresponds to the dungeon fight of a log.

### Secret
Create `api_secrets.py` in the root directory with the following contents:

```python
api_key = 'XXX'
```

You can go to [WCL](https://www.warcraftlogs.com/profile) to get your api key (scroll down on your profile page).

## Results
You can see the output raid event file in `output/raid_events.simc`. It will contain the following:
- first event that makes the default boss of simc invulnerable (similar to Dungeonslice)
- set the sim time to the duration of the dungeon based on the FIGHTID given
- list of raid events for each add wave corresponding to each dungeon pull

repository: WarcraftPriests/wcl-events

repo_name: WarcraftPriests/wcl-events


text:
# StarFlight

 - A simple dodge the rock space flight game
 - Play link: https://cocky-aryabhata-d7d419.netlify.com/

![playVideo](./starflightplay.gif)

## Instructions

 - Use WASD to move up, left, down, right

## Built With

 - Javascript
 - Webpack
 - Three.js (with FBXLoader and OBJLoader)

## About The Project

 - This is my first personal game project using Javascript and Three.js
 - Got more used to vanilla Javascript, a brief idea of Three.js and how I might use it on web pages
 - Tried out coding style of Three.js reference codes

## Author

 - Simon Jee

## License
 - This project is licensed under the MIT License - see the LICENSE.md file for details
 - Music from https://www.bensound.com

repository: sijeecodes/starflight

repo_name: sijeecodes/starflight


text:
Mercurial hook for jira
==================================

A Mercurial hook that checks if commit messages contain JIRA keys.

The expected JIRA project is based on the name of the repository, and is configured in `~/.config/jirakeycheck.json`
See example_jirakeycheck.json for an example

Installation
------------
1. Copy `jirakeycheck.py` and `commitwrapper.py` to ~/.hg (or any dir you like)
2. Add the following lines to $HOME/.hgrc:

    ```
    [extensions]
       # wrapper so that only manual commits will use the manualpre(txn)commit hooks
       manualcommithook = ~/.hg/commitwrapper.py
    [hooks]
       #check all manual outgoing commits
       manualpretxncommit = python:~/.hg/jirakeycheck.py:checkCommitMessage
    ```

3. Copy example_jirakeycheck.json to ~/.config/jirakeycheck.json
4. Set your JIRA projects and repo names in ~/.config/jirakeycheck.json

Configuration
-------------
This plugin is configuring by defining "projects" in
~/.config/jirakeycheck.json.

"projects" should be a dictionary that maps JIRA board names to a list of
regular expressions.  During a commit, the commit hook tries to match each of
the regular expressions in order.  If there is a match, then the script
verifies that a JIRA issue id for the associated board is included in the
commit message.

See example_jirakeycheck.json for an example.


text:
---
layout: default
---

# 1996-02-17 - Re: Computer unmasks Anonymous writer...

## Header Data

From: "Mark M."<EMAIL_ADDRESS>To: jim bell<EMAIL_ADDRESS>Message Hash: f3a1eef60d3e783d6fc2a4173469c4adb44a4a3102cc8f6368e117f223a00397

Message ID: \<Pine.LNX.3.91.960216225636.2782A-100000@gak\>

Reply To<EMAIL_ADDRESS>UTC Datetime: 1996-02-17 04:54:56 UTC

Raw Date: Sat, 17 Feb 1996 12:54:56 +0800

## Raw message

```
{% raw  %}From: "Mark M."<EMAIL_ADDRESS>Date: Sat, 17 Feb 1996 12:54:56 +0800
To: jim bell<EMAIL_ADDRESS>Subject: Re: Computer unmasks Anonymous writer...
In-Reply-To<EMAIL_ADDRESS>Message-ID: <Pine.LNX.3.91.960216225636.2782A-100000@gak>
MIME-Version: 1.0
Content-Type: text/plain

-----BEGIN PGP SIGNED MESSAGE-----

On Fri, 16 Feb 1996, jim bell wrote:

> At 09:20 AM 2/16/96 -0800, Alexander Chislenko wrote:
> >  I ran my essays through Word grammar checker a while ago,
> >and was surprised how stable the grammar statistics were.
> >Complexity of the text (grade level) was the same to the decimal point,
> >average length of sentences was consistent, etc.
> >People also use the same styles of smileys or *highlights*, make
> >consistent spelling errors, have their habits of indentation, etc.
>
> What's the next step?  Writing a program which "fakes" somebody's style,
> right?

It's been done already.  A program was posted here a while ago that could
actually fake a person's writing style by analyzing word patterns.  It does
a pretty good job, too.  I can e-mail it to anyone who is interested.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
<EMAIL_ADDRESS>            | finger -l for PGP key 0xf9b22ba5
http://www.voicenet.com/~markm/ | bd24d08e3cbb53472054fa56002258d5

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3
Charset: noconv

iQCVAwUBMSVSmbZc+sv5siulAQEbTwQAh8+e51WN10DN6P4aLYoWrmLKLN3NWAJa
TW6hvckc/zq8SnFvsRg9TbwLgVon3uxi+OByYyBR98tLEOSKjNVwv/5XZ5M216Zs
UFk/a4fwWq/eJ2qnYkA9ultP7YQjPovJQCI+r+orJ6uLgoMiw4oLCbggpkpqET+X
lADi5zJncaY=
=+wAT
-----END PGP SIGNATURE-----

{% endraw %}
```

## Thread

+ Return to [February 1996](/archive/1996/02)

+ Return to "[jim bell <jimbell@pacifier.com>](/authors/jim_bell_jimbell_at_pacifier_com_)"
+ Return to "["Mark M." <markm@voicenet.com>](/authors/mark_m__markm_at_voicenet_com_)"
+ Return to "[Sean Gabb <cea01sig@gold.ac.uk>](/authors/sean_gabb_cea01sig_at_gold_ac_uk_)"

+ 1996-02-17 (Sat, 17 Feb 1996 11:35:08 +0800) - [Re:  Computer unmasks Anonymous writer...](/archive/1996/02/f5d8a80776fe17ff13a466b55a557cf0c74a2e7177db98597defc38641b49b37) - _jim bell<EMAIL_ADDRESS>  + 1996-02-17 (Sat, 17 Feb 1996 12:54:56 +0800) - Re: Computer unmasks Anonymous writer... - _"Mark M."<EMAIL_ADDRESS>  + 1996-02-17 (Sun, 18 Feb 1996 04:35:09 +0800) - [Re: Computer unmasks Anonymous writer...](/archive/1996/02/f6b23f16e04726206f5c3a3a9fe0c0b644c2264c3f1111b46097fc29e1675b67) - _Sean Gabb<EMAIL_ADDRESS>


text:
Confluence Favorites Sync Chrome Extension

This extensions keeps a local copy your Confluence Wiki Favorites in your chrome bookmarks.

This allows you to organize your Confluence favorites, something you cannot do within Confluence.

Accessing to your 'My Favorites' page in Confluence will automatically update your chrome bookmarks.

repository: pbarbier/conflu-favs-sync

repo_name: pbarbier/conflu-favs-sync


text:
+++
# Experience widget.
widget = "experience"  # Do not modify this line!
active = true  # Activate this widget? true/false

title = "Experience"
subtitle = "Automotive Industry"

# Order that this section will appear in.
weight = 8

# Date format for experience
#   Refer to https://sourcethemes.com/academic/docs/customization/#date-format
date_format = "January 2006"

# Experiences.
#   Add/remove as many `[[experience]]` blocks below as you like.
#   Required fields are `title`, `company`, and `date_start`.
#   Leave `date_end` empty if it's your current employer.
#   Begin/end multi-line descriptions with 3 quotes `"""`.
[[experience]]
  title = "Intern- Verification and Validation"
  company = "Volvo Group Trucks Technology"
  company_url = "https://www.volvogroup.com/en-en/about-us/organization/our-global-presence/hagerstown.html"
  location = "Hagerstown, Maryland, USA"
  date_start = "2017-08-14"
  date_end = "2017-12-15"
  description = """Verification and Validation Intern
  Responsibilities include:

  * Demo testing of diagnostic system through fault introduction and detection under field trials
  * Collaborated with different functional owners for setting up new tests and for resolving conflicts
  * Contributed to improving the fidelity of MATLAB Simulink model of full Diesel engine system which was created as Virtual Test Cell
  * Ran simulations on VTC using driving conditions and compared the outputs with actual for debugging and showing improvements
  """

[[experience]]
  title = "Manager - Customer Services"
  company = "Daimler India Commercial Vehicles"
  company_url = "http://daimler-trucksasia.in/index.php/english"
  location = "Chennai, India"
  date_start = "2014-07-07"
  date_end = "2016-07-29"
  description = """Handled Field Service Operation for the region of West Gujarat, India which included support to 13 models of
  BharatBenz trucks 9-49 tonnes range and around 200 active customers
  Responsibilities include:

  * Dealer management
  * Customer management
  * Product Support
  * Technical Support (Diagnostics)
  * Warranty claims management
  * Service marketing
  * Reach and Recovery
  * Field trials
  * New Product monitoring
  """
+++

repository: ksivasan/academic-kickstart

repo_name: ksivasan/academic-kickstart


text:
iSwift is the kernel IPython/Notebook implementation for Swift programming language.

It can:
  + Execute swift code on the Jupyter Notebook web editor, Jupyter console as well as Jupyter qtconsole.
  + Import Foundatation/Dispatch and other Buildin libraries.
  + Autocomplete swift code by pressing tab ↹.
  + Support encryption.
  + Support Linux/macOS

This project is based off [KelvinJin/iSwift](https://github.com/KelvinJin/iSwift) but makes a few changes:
  + Updates to support Swift 4.1
  + Base the docker image off jupyter/minimal-notebook

Note: This is rough work-in-progress. What you're looking at is
unlikely to be the latest and greatest. I'd suggest checking the
[Swift for TensorFlow google
group](https://groups.google.com/a/tensorflow.org/forum/?utm_source=digest&utm_medium=email/#!topic/swift/5fr5h1SWzzE),
and the [fork tree](https://github.com/KelvinJin/iSwift/network) from
KelvinJin's original verison, to understand what is the best version of this.

## Quick Start

The easiest way of using this is via the [docker image](https://hub.docker.com/r/algalgal/swift-notebook/), which is already built and hosted on docker hub. Assuming you have docker installed on your machine, all you need to do is run:

```bash
$ docker run -t -i -p 8888:8888 --privileged algalgal/swift-notebook:b767ba373ced
```

This will download the image if needed, and then run it, starting Jupyter. (FYI, this runs an image based roughly on the github repo commit `6a08a20`.)

Then copy and paste the URL from the console into your browser to access the notebook. From there you can select `New` -> `Swift`.

To build and run images locally, you can use the helper scripts `build-jupyter-swift-notebook.sh` and `run-jupyter-swift-notebook.sh`.

## Requirements

These are requirement if you do not want to use docker:

  + macOS/Linux
  + Swift 4.1
  + ZMQ
  + Jupyter 5.0

## macOS Installation

Clone this repo locally. And:

1. Follow [this](https://github.com/Zewo/ZeroMQ/blob/master/setup_env.sh) script to install the libzmq on your machine.

2. Build the project.

```
swift build
```

3. Currently, in order to run swift kernel locally, you need to create a file named
`kernel.json`. Put the following content to the file and replace the `Path/to/iSwift`
with your local clone path.

```json
{
 "argv": ["Path/to/iSwift/.build/debug/iSwift", "-f", "{connection_file}"],
 "display_name": "Swift",
 "language": "swift"
}
```

4. Install Jupyter kernel: (replace the `Folder/that/has/kernel/json` with
  the path of the folder that contains the `kernel.json` file)

```
jupyter-kernelspec install Folder/that/has/kernel.json
```

5. Run Jupyter Notebook (token needs to be empty):
```
jupyter notebook --NotebookApp.token=
```

## Linux Installation

1. Install Swift 3.0.
2. Check if you have libzmq installed.
3. Continue from step 2 in the section above.

## Docker Installation

Simply clone this repo and run `docker build -t iswift .`. It will build the docker image.

## Author

[Jin Wang](https://twitter.com/jinw1990)

## Contribution

Contributions are welcome. Simply create an issue if you have ideas on how we
can improve iSwift.

## License
MIT

repository: vguerra/iSwift

repo_name: vguerra/iSwift


text:
The [Auth0 hosted login page](/hosted-pages/login) is the easiest way to set up authentication in your application. We recommend using the Auth0 hosted login page for the best experience, best security and the fullest array of features.

::: note
You can also embed the Lock widget directly in your application. If you use this method, some features, such as single sign-on, will not be accessible.
To learn how to embed the Lock widget in your application, follow the [Embedded Login sample](https://github.com/auth0-samples/auth0-ios-swift-sample/tree/embedded-login/01-Embedded-Login).
:::

::: note
Read the [Browser-Based vs. Native Login Flows on Mobile Devices](/tutorials/browser-based-vs-native-experience-on-mobile) article to learn how to choose between the two types of login flows.
:::

<%= include('../../_includes/_ios_dependency_centralized') %>

## Add the Callback

For Auth0 to handle the authentication callback, update your `AppDelegate` file.

First, import the `Auth0` module:

${snippet(meta.snippets.setup)}

Then, add the following `UIApplicationDelegate` method:

```swift
// AppDelegate.swift

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
    return Auth0.resumeAuth(url, options: options)
}
```

::: note
To configure callback, you must configure your callback URL first. Read about the Callback URL in the [Configure Callback](/quickstart/native/ios-swift/getting-started#configure-callback-urls) step.
:::

## Implement Login

First, import the `Auth0` module in the file where you want to present the hosted login page:

${snippet(meta.snippets.setup)}

Then, present the hosted login screen:

${snippet(meta.snippets.use)}

This adds the `profile` scope to enable [retrieving the User Profile](/quickstart/native/ios-swift/03-user-sessions#fetch-the-user-profile).

You need to make sure you get a response compliant with the OpenID Connect protocol. You can choose between two options:

* Set the audience
* Turn on the **OIDC conformant** switch in your Auth0 dashboard

This example sets the `audience` parameter to get an OIDC-compliant response.

::: note
To turn on the **OIDC conformant** switch, in your [Client Settings](${manage_url}/#/applications/${account.clientId}/settings), click on **Show Advanced Settings** > **OAuth**. For more information, read [How to use the new flows](/api-auth/intro#how-to-use-the-new-flows).
:::

After the user authenticates, their information is returned in a `credentials` object.

::: note
To learn more about the `credentials` object, read the [Credentials](https://github.com/auth0/Auth0.swift/blob/master/Auth0/Credentials.swift) article.
:::

repository: rkhoriander/docs

gha_language: HTML

repo_name: rkhoriander/docs