text:
---
title:  top-nested operator
description: Learn how to use the top-nested operator to produce a hierarchical aggregation.
ms.reviewer: alexans
ms.topic: reference
ms.date: 03/12/2023
---
# top-nested operator

Produces a hierarchical aggregation and top values selection, where each level is a refinement of the previous one.

```kusto
T | top-nested 3 of Location with others="Others" by sum(MachinesNumber), top-nested 4 of bin(Timestamp,5m) by sum(MachinesNumber)
```

The `top-nested` operator accepts tabular data as input, and one or more aggregation clauses.
The first aggregation clause (left-most) subdivides the input records into partitions, according
to the unique values of some expression over those records. The clause then keeps a certain number of records
that maximize or minimize this expression over the records. The next aggregation clause then
applies a similar function, in a nested fashion. Each following clause is applied to the partition produced
by the previous clause. This process continues for all aggregation clauses.

For example, the `top-nested` operator can be used to answer the following question: "For a table containing sales
figures, such as country/region, salesperson, and amount sold: what are the top five countries/regions by sales? What are the top three salespeople in each of these countries/regions?"

## Syntax

*T* `|` `top-nested` *TopNestedClause* [`,` `top-nested` *TopNestedClause2*]...

Where *TopNestedClause* has the following syntax:

[ *N* ] `of` [*ExprName* `=`] *Expr* [`with` `others` `=` *ConstExpr*] `by` [*AggName* `=`] *Aggregation* [`asc` | `desc`]

## Parameters

|Name|Type|Required|Description|
|--|--|--|--|
|*T*|string|✓|The input tabular expression.|
|*N*|long||The number of top values to return for this hierarchy level. If omitted, all distinct values will be returned.|
|*ExprName*|string||If specified, sets the name of the output column corresponding to the values of *Expr*.|
|*Expr*|string|✓|An expression over the input record indicating which value to return for this hierarchy level. Typically it's a column reference from *T*, or some calculation, such as `bin()`, over such a column.
|*ConstExpr*|string||If specified, for each hierarchy level, 1 record will be added with the value that is the aggregation over all records that didn't "make it to the top".|
|*AggName*|string||If specified, this identifier sets the column name in the output for the value of *Aggregation*.|
|*Aggregation*|string||The aggregation function to apply to all records sharing the same value of *Expr*. The value of this aggregation determines which of the resulting records are "top". For the possible values, see [supported aggregation functions](#supported-aggregation-functions).|
|`asc` or `desc`|string||Controls whether selection is actually from the "bottom" or "top" of the range of aggregated values. The default is `desc`.|

### Supported aggregation functions

The following aggregation functions are supported:
* [sum()](sum-aggfunction.md)
* [count()](count-aggfunction.md)
* [max()](max-aggfunction.md)
* [min()](min-aggfunction.md)
* [dcount()](dcountif-aggfunction.md)
* [avg()](avg-aggfunction.md)
* [percentile()](percentiles-aggfunction.md)
* [percentilew()](percentiles-aggfunction.md)

> [!NOTE]
> Any algebraic combination of the aggregations is also supported.

## Returns

This operator returns a table that has two columns for each aggregation clause:

* One column holds the distinct values of the clause's *`Expr`* calculation (having the
  column name *ExprName* if specified)

* One column holds the result of the *Aggregation*
  calculation (having the column name *AggregationName* if specified)

## Notes

Input columns that aren't specified as *`Expr`* values aren't outputted.
To get all values at a certain level, add an aggregation count that:

* Omits the value of *N*
* Uses the column name as the value of *`Expr`*
* Uses `Ignore=max(1)` as the aggregation, and then ignore (or project-away)
   the column `Ignore`.

The number of records may grow exponentially with the number of aggregation clauses
((N1+1) \* (N2+1) \* ...). Record growth is even faster if no *N* limit is specified. Take into account that this operator may consume a considerable amount of resources.

If the distribution of the aggregation is considerably non-uniform,
limit the number of distinct values to return (by using *N*) and use the
`with others=` *ConstExpr* option to get an indication for the "weight" of all other
cases.

## Examples

> [!div class="nextstepaction"]
> Run the query

```kusto
StormEvents
| top-nested 2 of State       by sum(BeginLat),
  top-nested 3 of Source      by sum(BeginLat),
  top-nested 1 of EndLocation by sum(BeginLat)
```

**Output**

|State|aggregated_State|Source|aggregated_Source|EndLocation|aggregated_EndLocation|
|---|---|---|---|---|---|
|KANSAS|87771.2355000001|Law Enforcement|18744.823|FT SCOTT|264.858|
|KANSAS|87771.2355000001|Public|22855.6206|BUCKLIN|488.2457|
|KANSAS|87771.2355000001|Trained Spotter|21279.7083|SHARON SPGS|388.7404|
|TEXAS|123400.5101|Public|13650.9079|AMARILLO|246.2598|
|TEXAS|123400.5101|Law Enforcement|37228.5966|PERRYTON|289.3178|
|TEXAS|123400.5101|Trained Spotter|13997.7124|CLAUDE|421.44|

Use the option 'with others':

> [!div class="nextstepaction"]
> Run the query

```kusto
StormEvents
| top-nested 2 of State with others = "All Other States" by sum(BeginLat),
  top-nested 3 of Source by sum(BeginLat),
  top-nested 1 of EndLocation with others = "All Other End Locations" by sum(BeginLat)
```

**Output**

|State|aggregated_State|Source|aggregated_Source|EndLocation|aggregated_EndLocation|
|---|---|---|---|---|---|
|KANSAS|87771.2355000001|Law Enforcement|18744.823|FT SCOTT|264.858|
|KANSAS|87771.2355000001|Public|22855.6206|BUCKLIN|488.2457|
|KANSAS|87771.2355000001|Trained Spotter|21279.7083|SHARON SPGS|388.7404|
|TEXAS|123400.5101|Public|13650.9079|AMARILLO|246.2598|
|TEXAS|123400.5101|Law Enforcement|37228.5966|PERRYTON|289.3178|
|TEXAS|123400.5101|Trained Spotter|13997.7124|CLAUDE|421.44|
|KANSAS|87771.2355000001|Law Enforcement|18744.823|All Other End Locations|18479.965|
|KANSAS|87771.2355000001|Public|22855.6206|All Other End Locations|22367.3749|
|KANSAS|87771.2355000001|Trained Spotter|21279.7083|All Other End Locations|20890.9679|
|TEXAS|123400.5101|Public|13650.9079|All Other End Locations|13404.6481|
|TEXAS|123400.5101|Law Enforcement|37228.5966|All Other End Locations|36939.2788|
|TEXAS|123400.5101|Trained Spotter|13997.7124|All Other End Locations|13576.2724|
|KANSAS|87771.2355000001|||All Other End Locations|24891.0836|
|TEXAS|123400.5101|||All Other End Locations|58523.2932000001|
|All Other States|1149279.5923|||All Other End Locations|1149279.5923|

The following query shows the same results for the first level used in the example above.

> [!div class="nextstepaction"]
> Run the query

```kusto
StormEvents
| where State !in ('TEXAS', 'KANSAS')
| summarize sum(BeginLat)
```

**Output**

|sum_BeginLat|
|---|
|1149279.5923|

Request another column (EventType) to the top-nested result.

> [!div class="nextstepaction"]
> Run the query

```kusto
StormEvents
| top-nested 2 of State       by sum(BeginLat),
  top-nested 2 of Source      by sum(BeginLat),
  top-nested 1 of EndLocation by sum(BeginLat),
  top-nested   of EventType   by tmp = max(1)
| project-away tmp
```

**Output**

|State|aggregated_State|Source|aggregated_Source|EndLocation|aggregated_EndLocation|EventType|
|---|---|---|---|---|---|---|
|KANSAS|87771.2355000001|Trained Spotter|21279.7083|SHARON SPGS|388.7404|Thunderstorm Wind|
|KANSAS|87771.2355000001|Trained Spotter|21279.7083|SHARON SPGS|388.7404|Hail|
|KANSAS|87771.2355000001|Trained Spotter|21279.7083|SHARON SPGS|388.7404|Tornado|
|KANSAS|87771.2355000001|Public|22855.6206|BUCKLIN|488.2457|Hail|
|KANSAS|87771.2355000001|Public|22855.6206|BUCKLIN|488.2457|Thunderstorm Wind|
|KANSAS|87771.2355000001|Public|22855.6206|BUCKLIN|488.2457|Flood|
|TEXAS|123400.5101|Trained Spotter|13997.7124|CLAUDE|421.44|Hail|
|TEXAS|123400.5101|Law Enforcement|37228.5966|PERRYTON|289.3178|Hail|
|TEXAS|123400.5101|Law Enforcement|37228.5966|PERRYTON|289.3178|Flood|
|TEXAS|123400.5101|Law Enforcement|37228.5966|PERRYTON|289.3178|Flash Flood|

Give an index sort order for each value in this level (per group) to sort the result by the last nested level (in this example by EndLocation):

> [!div class="nextstepaction"]
> Run the query

```kusto
StormEvents
| top-nested 2 of State  by sum(BeginLat),    top-nested 2 of Source by sum(BeginLat),    top-nested 4 of EndLocation by  sum(BeginLat)
| order by State , Source, aggregated_EndLocation
| summarize EndLocations = make_list(EndLocation, 10000) , endLocationSums = make_list(aggregated_EndLocation, 10000) by State, Source
| extend indicies = range(0, array_length(EndLocations) - 1, 1)
| mv-expand EndLocations, endLocationSums, indicies
```

**Output**

|State|Source|EndLocations|endLocationSums|indices|
|---|---|---|---|---|
|TEXAS|Trained Spotter|CLAUDE|421.44|0|
|TEXAS|Trained Spotter|AMARILLO|316.8892|1|
|TEXAS|Trained Spotter|DALHART|252.6186|2|
|TEXAS|Trained Spotter|PERRYTON|216.7826|3|
|TEXAS|Law Enforcement|PERRYTON|289.3178|0|
|TEXAS|Law Enforcement|LEAKEY|267.9825|1|
|TEXAS|Law Enforcement|BRACKETTVILLE|264.3483|2|
|TEXAS|Law Enforcement|GILMER|261.9068|3|
|KANSAS|Trained Spotter|SHARON SPGS|388.7404|0|
|KANSAS|Trained Spotter|ATWOOD|358.6136|1|
|KANSAS|Trained Spotter|LENORA|317.0718|2|
|KANSAS|Trained Spotter|SCOTT CITY|307.84|3|
|KANSAS|Public|BUCKLIN|488.2457|0|
|KANSAS|Public|ASHLAND|446.4218|1|
|KANSAS|Public|PROTECTION|446.11|2|
|KANSAS|Public|MEADE STATE PARK|371.1|3|

The following example returns the two most-recent events
for each US state, with some information per event.
Note the use of the `max(1)` (which is then projected away)
for columns which just require propagation through the operator
without any selection logic.

> [!div class="nextstepaction"]
> Run the query

```kusto
StormEvents
| top-nested of State by Ignore0=max(1),
  top-nested 2 of StartTime by Ignore1=max(StartTime),
  top-nested of EndTime by Ignore2=max(1),
  top-nested of EpisodeId by Ignore3=max(1)
| project-away Ignore*
| order by State asc, StartTime desc
```

### Retrieve the latest records per identity

If you have a table with an ID column and a timestamp column, you can use the top-nested operator to query the latest two records for each unique value of ID. The latest records are defined by the highest value of timestamp.

> [!div class="nextstepaction"]
> Run the query

```kusto
datatable(id: string, timestamp: datetime, otherInformation: string)
[
    "Barak", datetime(2015-01-01), "1",
    "Barak", datetime(2016-01-01), "2",
    "Barak", datetime(2017-01-20), "3",
    "Donald", datetime(2017-01-20), "4",
    "Donald", datetime(2017-01-18), "5",
    "Donald", datetime(2017-01-19), "6"
]
| top-nested of id by dummy0=max(1),
top-nested 2 of timestamp by dummy1=max(timestamp),
top-nested of otherInformation by dummy2=max(1)
| project-away dummy0, dummy1, dummy2
```

**Output**

| id | timestamp | otherInformation |
|---|---|---|
| Barak | 2016-01-01T00:00:00Z | 2 |
| Donald | 2017-01-19T00:00:00Z | 6 |
| Barak | 2017-01-20T00:00:00Z | 3 |
| Donald | 2017-01-20T00:00:00Z | 4 |

Here's a step-by-step explanation of the query:

1. The `datatable` creates a test dataset.
1. The first `top-nested` clause returns all distinct values of `id`.
1. The second `top-nested` clause selects the top two records with the highest `timestamp` for each id.
1. The third `top-nested` clause adds the `otherInformation` column for each record.
1. The `project-away` operator removes the dummy columns introduced by the top-nested operator.

repository: microsoft/Kusto-Query-Language

repo_name: microsoft/Kusto-Query-Language


text:
## [DISCONTINUED] - 24.05.2021
* While this widget was useful in the early days of Flutter, the Flutter team introduced an own way to zoom and pan, see [`InteractiveViewer`](https://api.flutter.dev/flutter/widgets/InteractiveViewer-class.html).
## [1.1.2] - 01.08.2019
* fix: Fixed to flutter 1.7.8+hotfix.4 (issue #1)
## [1.1.1] - 25.04.2018
* Added type (ImageProvider) to imageProvider in scalable_image.dart
* Fixed library name
## [1.1.0] - 25.04.2018
* Added an option which allows to wrap the image in an AspectRatio
* Added an option to lock scaling
## [1.0.0] - 20.04.2018
* Initial release

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
Module zenml.core.utils
=======================

Functions
---------

`define_json_config_settings_source(config_dir: str, config_name: str) ‑> Callable`
:   Define a function to essentially deserialize a model from a serialized
    json config.

    Args:
        config_dir: A path to a dir where we want the config file to exist.
        config_name: Full name of config file.

    Returns:
        A `json_config_settings_source` callable reading from the passed path.

`generate_customise_sources(file_dir: str, file_name: str)`
:   Generate a customise_sources function as defined here:
    https://pydantic-docs.helpmanual.io/usage/settings/. This function
    generates a function that configures the priorities of the sources through
    which the model is loaded. The important thing to note here is that the
    `define_json_config_settings_source` is dynamically generates with the
    provided file_dir and file_name. This allows us to dynamically generate
    a file name for the serialization and deserialization of the model.

    Args:
        file_dir: Dir where file is stored.
        file_name: Name of the file to persist.

    Returns:
        A `customise_sources` class method to be defined the a Pydantic
        BaseSettings inner Config class.

repository: alexander-manley/zenml

branch_name: refs/heads/main

repo_name: alexander-manley/zenml


text:
# Change Log

All notable changes to this project will be documented in this file.

## [2.1.0] - 2015-03-02
### Changed

- Default quote_style is now single quotes

## [2.0.0] - 2015-03-02
### Changed

- Renamed known module setting to snake case (`knownModulesByVariableName => known_modules_by_variable_name`)

## [1.1.0] - 2015-03-02
### Added

- Custom variable/module mappings with the knownModulesByVariableName setting

## [1.0.0] - 2015-02-11
### Added

- Guess module name from lowercase, constructor case and camel case variables.
- Change quotes with the quote_style setting.

license: MIT

repository: psalaets/QuickRequire

gha_language: Python

repo_name: psalaets/QuickRequire


text:
# Product Usage Guidelines

When using this data in a publication or presentation, we ask that you include the
acknowledgement provided with each product. DOIs are also provided for citation
when discussing the HyP3 software or plugins.

- For multi-file products, the acknowledgement and relevant DOIs are included in
  the `*.README.md.txt` file.
- For netCDF products, the acknowledgement is included in the `source` global attribute
  and the DOIs are included in the `references` global attribute.

{% include 'citing-snippet.md' %}

branch_name: refs/heads/develop


text:
# mkcluster

A github based chrome plugin which will cluster the pull requests automatically using the text taken from the pr and uses the Latent Dirichlet allocation algorithm to form the clusters.

repository: sainitishkumar/mkcluster

gha_language: Jupyter Notebook

gha_license_id: MIT

repo_name: sainitishkumar/mkcluster


text:
## `license` command
```
zigmod license
```

This will print a listing of all of your dependencies (deeply)' licenses. Any code is valid for the `license` field in `zig.mod` but should it match a valid SPDX identifier, a URL to learn more about the license will also be printed so the user can learn more about it.

Should one of your dependencies not have a `license` field in their `zig.mod` manifest, an `Unspecified:` list will appear at the bottom of the output.

Running this command on Zigmod itself (as of this writing) produces such output:
```
MIT:
= https://opensource.org/licenses/MIT
- This
- v/git/github.com/yaml/libyaml/tag-0.2.5
- v/git/github.com/nektro/zig-ansi/commit-25039ca
- v/git/github.com/ziglibs/known-folders/commit-f0f4188
- v/git/github.com/Vexu/zuri/commit-41bcd78
- v/git/github.com/alexnask/iguanaTLS/commit-1767e48
- v/git/github.com/nektro/zig-licenses/commit-1a19e4b
```

repository: tawawhite/zigmod

repo_name: tawawhite/zigmod


text:
## Principles in Construction

Remember, remember, the principles to be a member.

- Autonomy
    - Social Contracts
    - Code of Conduct/Principles
        - We are a family, community, crowd-owners of a social company with diversity.
	- Trust first, but keep track of what happens.
        - Be bold, look for radical solution!
        - Be modest, `I know that I know nothing`.
        - Be honest and embrace changes, open source and open management based on credibility.
- Open Source, no NCA, NDA
    - Open Meeting
    - Open Decision
    - Open Development
- Open Management
    - Peer Review
    - Jury Decision
    - Liquid Democracy

`One can make the shape, but it is all together that can fill the gap.`

### Openness and Trustworthy

My Two Cents

- Open Source
   - Self-awareness: I know what I know.
   - Self-confidence: I admit what I don't know.
   - Self-challenge: I embrace to learn what I don't know.
- Open Management
   - Team-awareness: nothing new under the Sun. What cannot tell is what cannot improve.
   - Team-confidence: ideas can be stolen but minds cannot. The more to share gets the more to admire.
   - Team-challenge: one long leg doesn't make a stable table. Keep people informed to land informed decisions.
- Open Equity
    - Social-awareness: we stand on the shoulder of giants. `Nothing comes from nothing.`
    - Social-confidence: with giants we stand. Share with the team is multiplying the power.
    - Social-challenge: `more power comes with more responsibility. ` Share with the market is exponentiating the world.

`Superorganism` is the ultimate form of `Effective Altruism` to archive `Co-Prosperity`.

### Call For Help

1. [Effective Altruism Principles](https://docs.google.com/document/d/1tvw5HsxNvAMNyITOy78bN7Jmfw7-XDNjhSAXd5jDMJg/edit#heading=h.x29zl4zf974z)
    1. Commitment to Others
    2. Scientific Mindset
    3. Openness
    4. Integrity
    5. Collaborative Spirit

2. [Canonical Debate Lab Principles](https://github.com/canonical-debate-lab/paper#Principles): how to abstract it to be adaptive?
    1. how to make it brief to the point?
    2. how to make it self-explainable with expandable deeper reasoning?
    3. how to make it a trust-first and learn as practice process?
    4. how to make it traceable to evaluate the value alignment?

repository: marwahaha/LibertyEarth

repo_name: marwahaha/LibertyEarth


text:
---
date: 2016-12-22T20:04:40.407Z
title: Passing Data Between Components in Angular
---
Passing data between different components is very similar to VueJS.
Both use a publisher/subscriber pattern.

Below we will demonstate how to accomplish this:

1. Create three new components: GameControl, Odd and Even

2. The GameControl Component should have buttons to start and stop the game

3. When starting the game, an event (holding a incrementing number) should get emitted each second (ref = setInterval())

  gameNumber = 0;
  interval;
  constructor() {}

  ngOnInit() {}

  startGame() {
    this.interval = setInterval(() => {
      this.gameNumber++;
      this.sendNumber.emit(this.gameNumber);
    }, 1000);
  }

4. The event should be listenable from outside the component.

  @Output() sendNumber = new EventEmitter<number>();

5. When stopping the game, no more events should get emitted (clearInterval(ref))

  stopGame() {
    clearInterval(this.interval);
  }

6. A new Odd component should get created for every odd number emitted, the same should happen for the Even Component (on even numbers)

  @Input() element: { incrementingValue: number };

7. Simply output Odd - Number or Even - Number in the two components.

  Odd - NUMBER

 even - NUMBER

8. Style the element (e.g. paragraph) holding your output text differently in both component

  p {
  color: blue;
}

repository: tmoodley/strata-cms-template

repo_name: tmoodley/strata-cms-template


text:
# Scope

This repostory contains demo notebooks using the PDS API (see https://github.com/NASA-PDS/pds-api).

# Prerequisites

- python 3.7

# Quickstart

    python -m venv venv
    pip install -r requirements.txt
    jupyter-lab

Enjoy the jupyter notebook provided there (under progress, mean nothing works yet !)

repository: michaelaye/pds-api-notebook

repo_name: michaelaye/pds-api-notebook


text:
---
layout: default
---

# 1996-01-07 - Re: Mixmaster On A $20 Floppy?

## Header Data

From<EMAIL_ADDRESS>(Futplex)

To<EMAIL_ADDRESS>(Cypherpunks Mailing List)

Message Hash: b06c73e3a82c10deca74d83036376c549d06b68d157fba041a1e25685838648f

Message ID<EMAIL_ADDRESS>Reply To<EMAIL_ADDRESS>UTC Datetime: 1996-01-07 23:59:42 UTC

Raw Date: Mon, 8 Jan 1996 07:59:42 +0800

## Raw message

```
{% raw  %}From<EMAIL_ADDRESS>(Futplex)
Date: Mon, 8 Jan 1996 07:59:42 +0800
To<EMAIL_ADDRESS>(Cypherpunks Mailing List)
Subject: Re: Mixmaster On A $20 Floppy?
In-Reply-To<EMAIL_ADDRESS>Message-ID<EMAIL_ADDRESS>MIME-Version: 1.0
Content-Type: text/plain

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

I wrote:
# I suppose that a site that escapes detection as a Mixmaster will throw off
# the correlation stats (i.e. because a message from that site to B won't be
# identified as a remailed message). But such sites are elusive objects I
# think. On the one hand, the site can't endure for long, or else its
# throughput traffic will likely give it away as an anonymizer (i.e. it gets
# lots of mail from the Mix network, and sends out similar amounts of mail to
# all sorts of people and the network). On the other hand, it had better last,
# or else it will look suspicious as a transient account receiving mail from
# the Mix network, sending a few messages, and quickly vanishing.

Lance writes:
> The second paragraph seems to deal with the issue of being known as an
> anonymous remailer or regular remailer user. I am not sure exactly what the
> concern with that is.

I was trying to explore possible ways to beat TA with less bandwidth, in the
context of transient (w.r.t. network address) anonymizers. I indicated doubt
about the possibility of any real gain, and as I think about it more I'm
not able to convince myself that there's any real value at all in that
regard.

Futplex<EMAIL_ADDRESS>- "IBM ?"
				- "All the girls are doing it"

-----BEGIN PGP SIGNATURE-----
Version: 2.6.2

iQEVAwUBMPBbEynaAKQPVHDZAQGm7wf+LbaZeZqI8/qwBQi+6vS4bzvtSkdf9i1v
aD8I0jlNLAmFsPQ6dJ0mOBObPz8b+3PbJ1/TCyr5w0vWcb6XpEemblqNf1H+SdY+
nP6Xbmdoyie2cObGjYOz8HHvhg+qANnanIqtax/CPd9smPMcLnl20pyLJPhlFRPG
MUQX33yIrxXEGY0os725Q1lQDWHaMpbt65+quzVZYFAfaNzBzQ99vy4ZrzsBPZIK
GLiqPcygWt3Kxfk7O0WjI2Gic3nrrpP1X5SxWwFnGQmlm9Zd9FwJxhpLsW4s+0B0
CNAI8c1ASA9AebLVVYVP4riQRkVDK/BYYSJLcXQfp2TzDSgPXg32JQ==
=coNU
-----END PGP SIGNATURE-----

{% endraw %}
```

## Thread

+ Return to [January 1996](/archive/1996/01)

+ Return to<EMAIL_ADDRESS>(Futplex)](/authors/futplex_at_pseudonym_com_futplex_)"
+ Return to<EMAIL_ADDRESS>(Lance Cottrell)](/authors/loki_at_obscura_com_lance_cottrell_)"

+ 1996-01-07 (Sun, 7 Jan 1996 14:44:17 +0800) - [Re: Mixmaster On A $20 Floppy?](/archive/1996/01/a0d67daf7ef6711758e0ef37045e6978ed02071c534f0fb553baa24c44d95fd3) -<EMAIL_ADDRESS>(Lance Cottrell)_
  + 1996-01-07 (Mon, 8 Jan 1996 07:59:42 +0800) - Re: Mixmaster On A $20 Floppy? -<EMAIL_ADDRESS>(Futplex)_


text:
# Suro: Netflix's Data Pipeline

Suro is a data pipeline service for collecting, aggregating, and dispatching large volume of application events including log data. It has the following features:

- It is distributed and can be horizontally scaled.
- It supports streaming data flow, large number of connections, and high throughput.
- It allows dynamically dispatching events to different locations with flexible dispatching rules.
- It has a simple and flexible architecture to allow users to add additional data destinations.
- It fits well into NetflixOSS ecosystem
- It is a best-effort data pipeline with support of flexible retries and store-and-forward to minimize message loss

Learn more about Suro on the Suro Wiki and the Netflix TechBlog post where Suro was introduced.

## Master Build Status

## Pull Request Build Status

Build
-----

NetflixGraph is built via Gradle (www.gradle.org). To build from the command line:

    ./gradlew build

See the `build.gradle` file for other gradle targets, like `distTar`, `distZip`, `installApp`, and `runServer`.

Running the server
------------------

You can run the server locally by just running `./gradlew runServer`.

More more advanced usage you may wish to run `./gradlew installApp` and then:

	cd suro-server
	java -cp "build/install/suro-server/lib/*" com.netflix.suro.SuroServer -m conf/routingmap.json -s conf/sink.json -i conf/input.json

To enable basic logging you can downloaded `slf4j-simple-1.7.7.jar` and copy it into `suro-server` then run:

	cd suro-server
	java -cp "build/install/suro-server/lib/*:slf4j-simple-1.7.7.jar" com.netflix.suro.SuroServer -m conf/routingmap.json -s conf/sink.json -i conf/input.json
## [Netflix by APKFolks](https://android-apk.org/com.battlenet.showguidf/)
## [APKFolks Netflix](https://aapks.com/apk/netflix-by-apkfolks/)
Support
-----

We will use the Google Group, Suro Users, to discuss issues: https://groups.google.com/forum/#!forum/suro-users

repository: androidappsss/suro

repo_name: androidappsss/suro


text:
# Grafana Plugin PerfCurve

## Overview
PerfCurve is a grafana panel plugin to plot operation point of rotating machine, such as pump, compressor and etc., on a canvas with its performance curves.
You can draw multiple performance curves on the canvas only by giving sample points on the performance curve. The panel plugin connects sample points smoothly.

![Panel Example](https://github.com/SSKGo/perfcurve-panel/blob/master/docs/img/panel_example.png "Panel Example")

## Getting started
### Axes
Specify Min., Max., Label, Unit and Decimals of X-axis amd Y-axis.

![Axes](https://github.com/SSKGo/perfcurve-panel/blob/master/docs/img/axes_setting.png "Axes")

### Static curve
Add performance curves to the canvas by specifying sample points in comma separated value format.
The number of values in X input box and Y input Box shall be same.
Natural curves are drawn based on the sample points.

![Static curve](https://github.com/SSKGo/perfcurve-panel/blob/master/docs/img/static_curve_setting.png "Static curve")

### Dynamic curve (Advanced)
In case performance curve data is availble in database, they can be used to draw peformance curve which dynamically move based on the data.

![Dynamic curve](https://github.com/SSKGo/perfcurve-panel/blob/master/docs/img/dynamic_curve_setting.png "Dynamic curve")
![Query for dynamic curve](https://github.com/SSKGo/perfcurve-panel/blob/master/docs/img/query_dynamic_curve.png "Query for dynamic curve")

### Operation points
Set field names for X box and Y box to plot operating points.
Set Label, Color and Point Radius, too.
Table format is recommended as query option.

![Operation points](https://github.com/SSKGo/perfcurve-panel/blob/master/docs/img/plot_setting.png "Operation points")
![Query example](https://github.com/SSKGo/perfcurve-panel/blob/master/docs/img/query_example.png "Query example")

repository: gil-storedot/perfcurve-panel

repo_name: gil-storedot/perfcurve-panel


text:
# Steam Keys Storage
This is a tool I made to help myself to store Steam games keys in an easy way and make trading easier. It is made in C# using Windows Forms and stores the data in
a SQLite based database file.

I made this tool some time ago for personal use, but I am sharing it now as it can be useful for others. This is why you can find some weird things on
it, it was just made to suit personal needs. Also, if you wanna check the code, I should warn you: it is really ugly.

If you want to try it just download it from the [releases page](https://github.com/jaks97/Steam-Keys-Storage/releases/latest).

It requires [.NET Framework 4.5.1](https://www.microsoft.com/en-us/download/details.aspx?id=40779) or greater to run. It only works on Windows.

## How to use it?
Just launch the .exe you have downloaded and it should open a window like this:
![](https://i.imgur.com/m1Ms1As.png)

You can also see that two files were created in the running directory of the app: `Keys.db` and `Keys.bak`.

`Keys.db` is where all your data will be stored. `Keys.bak` is just a backup file that I will explain more about below.

---

To start adding keys press the `Add` button. There you will be asked for an app name, an AppID, and a SubID. Filling an AppID will make the
tool to try to get the other items. Same happens when filling a SubID. AppID is a unique numeric identifier for Steam apps. SubID is a
unique numeric identifier for Steam packages. A Steam key gives a license to own an specific package. This tool will map an AppID with a SubID. (I know, this is someway wrong, as a SubID may grant access to
access to multiple AppIDs).

![](https://i.imgur.com/1Xs5LJj.png)

If you don't know what to fill in SubID, just fill an AppID and the tool should gather a valid SubID. But check out that the tool will have
troubles to do this with games that were removed from Steam. That's where `Removed` checkbox is useful. When checked, the tool won't try to connect to Steam and fetch any data.

You can put anything on the keys box. So feel free to use this to store your giftlinks aswell (or just whatever you want).

The `Details` text box can be filled with anything you want. Those details will be stored for each of the keys you just added. They are stored per key, not per package.

---

To grab keys from there you should move them to the right table of the main window. You can do that by double clicking a game or just selecting it and pressing the `>>` button. You can do this multiple times if you want more copies.

Then click `Copy` and a new window with the keys should appear. The keys were also coppied to your clipboard.
![](https://i.imgur.com/Us2cFcf.png)

When you click `Mark used` those keys will be deleted from the database. If you don't want to delete them all, just untick the ones you don't want to delete from the list.

The keys are given in a first come first serve basis.

---

If you have a list of games in text, you can use the `Find games` button and paste it there so the tool will try to match them and add the games automatically.

---

You can export your games list clicking the propper button. In the window that it opens you can specify a custom format.

![](https://i.imgur.com/AwCOLFL.png)

To do so you have some "tags" that you can use. These are the following:
* {SUBID}
* {NAME}
* {APPID}
* {DETAILS}
* {CARDS}
* {APPURL}
* {PACKAGEURL}
* {COUNT}

So, for example, if you want them on markdown, you can specify the following format:
`[{GAME}]({APPURL})`

Same applies for keys export. Just the available tags are a bit different. Here they are:
* {SUBID}
* {NAME}
* {APPID}
* {DETAILS}
* {CARDS}
* {APPURL}
* {PACKAGEURL}
* {KEY}

---

Then you have the option to ecrypt your data with a password:

![](https://i.imgur.com/KCzHpvW.png)

Once you encrypted your data you will be asked for the password each time you open the program.

If you don't specify a new password, then encryption will be disabled.

---

### Why it asks for password when I haven't set up one? / It says my password is wrong?
There is a rare possibility that your `.db` file became corrupted. Sorry, your data is lost. Well, not all of it. You can use the backup file to restore it to a working point.

### How do I use the backup file to restore my data?
Just rename `Keys.bak` to `Keys.db` and launch the program.

`Keys.bak` contains the data that was saved the last time that you started the program without any failures. It doesn't includes the data you wrote in that launch.

### I just downloaded the tool and it doesn't starts
Check out if it has permission to write in its actual directory. Otherwise it won't be able to do anything.

### There will be updates? / Can I request a feature/modification?
There are no plans for me to update this. Doesn't mean you can't request a feature, feel free to do it. I will maybe add it if I find it easy to add or I personally find it useful.

If you wanna contribute with code, feel free to submit a pull request. I will check it and merge it if it doesn't breaks anything :P

repository: dkrusky/Steam-Keys-Storage

repo_name: dkrusky/Steam-Keys-Storage


text:
# GemFire and Greenplum with Gemfire-Greenplum connector(GGC) examples

This is the home of examples that are bundled with the project. Contributions[2] and corrections are welcome. Please send your questions/suggestions to [kochan<EMAIL_ADDRESS>
## Contents
1. [Overview](#overview)
2. [How to Get GemFire and GemFire-Greenplum connector](#obtaining)
3. [How to install GemFire and GemFire-Greenplum connector](#install)
3. [Examples](#examples)
4. [Documentation](#documentation)

## Overview
[Pivotal Gemfire-Greenplum Connector](https://pivotal.io/pivotal-gemfire) enables users to more easily tackle use cases that require a blend of analytical and transactional processing, such as fraud detection, recommendation and IoT data collection system

Use Cases:
*  Cache data reads in Gemfire
*  High speed data ingestion into Greenplum DB

## How to get GemFire and GGC

Please visit Pivotal Network at https://network.pivotal.io for the latest versions of this Pivotal product.

*  Login to https://network.pivotal.io/
*  Access GemFire product link at  https://network.pivotal.io/products/pivotal-gemfire
*  Download Pivotal GemFire zip and GemFire-Greenplum connector

## How to install GemFire and GGC (TBD)

* GemFire installation, follow this [link](http://gemfire.docs.pivotal.io/geode/getting_started/installation/install_standalone.html#concept_0129F6A1D0EB42C4A3D24861AF2C5425)

* GemFire-Greenplum connector, follow this [link](http://ggc.docs.pivotal.io/ggc/installation.html)

Or you can use this [script]](README_DOWNLOAD.md) to automatically download those binaries from Pivotal Network.

## How to run docker-compose for this demo (TBD)
1. Run this command to load docker-compose.yml. This task assumes you have preinstalled docker-compose
```
$ docker-compose up
office-4-39:gemfire-greenplum-examples kochan$ docker-compose up
Recreating gemfiregreenplumexamples_gemfire_1 ...
Recreating gemfiregreenplumexamples_gemfire_1 ... done
Recreating gemfiregreenplumexamples_gpdb_1 ...
Recreating gemfiregreenplumexamples_gpdb_1 ... done
Attaching to gemfiregreenplumexamples_gemfire_1, gemfiregreenplumexamples_gpdb_1
...
```

2. Verify the docker compose processes are running by following this command.

```
$ docker-compose ps
               Name                             Command               State                                                                                Ports
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
gemfiregreenplumexamples_gemfire_1   gfsh                             Up      <IP_ADDRESS>:10334->10334/tcp, <IP_ADDRESS>:1099->1099/tcp, <IP_ADDRESS>:40404->40404/tcp, <IP_ADDRESS>:7070->7070/tcp, <IP_ADDRESS>:8080->8080/tcp
gemfiregreenplumexamples_gpdb_1      /bin/sh -c echo "<IP_ADDRESS> ...   Up      <IP_ADDRESS>:9022->22/tcp, <IP_ADDRESS>:40000->40000/tcp, <IP_ADDRESS>:40001->40001/tcp, <IP_ADDRESS>:40002->40002/tcp, <IP_ADDRESS>:5005->5005/tcp, <IP_ADDRESS>:5010->5010/tcp, <IP_ADDRESS>:5432->5432/tcp
```

3. You can access GemFire/Geode docker by following the command below.

```
$ docker exec -it gemfiregreenplumexamples_gemfire_1 bin/bash
```

4. Use another shell, in order to execute the Greenplum docker

```
$ docker exec -it gemfiregreenplumexamples_gpdb_1 bin/bash
```

## Examples
You can run these examples once you have successfully executed docker-compose.
For example, follow the example-[Basic](basic/README.md)

### Basics
*  [Basic](basic/README.md)
*  [Export](export/README.md)

## Documentation
* Greenplum documentation(http://gpdb.docs.pivotal.io/43120/common/welcome.html)
* GemFire - gfsh Commands (http://gemfire.docs.pivotal.io/gemfire/tools_modules/gfsh/gfsh_quick_reference.html)
* GemFire-GreenPlum connector documentation(http://ggc.docs.pivotal.io/ggc/about_ggc.html)


text:
---
layout: post
title:  "Determine ClickOnce UpdateUri / Install Address"
date:   2011-04-06 13:02:00
categories: Work DotNet
---

Its hard to find Informations about the place where the UpdateUri is saved on a windows machine.
The only information i was found is where the binaries of a ClickOnce application is stored.

This whould be:
`C:\Users\UserName\AppData\Local\Apps\2.0\` (Vista)
`C:\Documents and Settings\UserName\Local Settings\Apps\2.0\` (XP)

The UpdateUri of a particular application can be found in the registry:

`HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall\[APP-ID]\UrlUpdateInfo`

The key will contain a string like this:
http://somedomain.com/ApplicationName/ApplicationName.application

If this address is called in the browser (InternetExplorer or Firefox with AddOn), the application starts to install.

If you change the `ApplicationName.application` to `publish.htm`, a install page will be displayed.


text:
#BooksFamily

[![Join the chat at https://gitter.im/vira-lytvyn/BooksFamily](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/vira-lytvyn/BooksFamily?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

This is not just another tools for sharing books experience and activities. This service will help you wear whole your home library right in the pocket)) It also gives you an opportunity to create own Books Family. How? Join it and you will find out)

There are going to be a responsive web app, but it will share server side with Android app.
So user will be able to choose what is more suitable for him.
It is also possible, that first version of webapp will be only for desktop(it means not responsive).

##Browsers support

- Chrome (latest version)
- Firefox (latest version)
- Chrome for Mobile (latest version)
- Firefox for Mobile (latest version)

repository: vira-lytvyn/BooksFamily

gha_language: JavaScript

repo_name: vira-lytvyn/BooksFamily


text:
Hangman game: description
-------------------------

Hangman is a paper and pencil guessing game for two or more players.
One player thinks of a word, phrase or sentence and the other tries to guess it by suggesting letters or numbers,
 within a certain number of guesses.

The word to guess is represented by a row of dashes, representing each letter of the word.
If the guessing player suggests a letter which occurs in the word, the other player writes it in all its correct positions.
If the suggested letter or number does not occur in the word, the other player draws one element of a hanged man stick figure as a tally mark.

Dictionaries:
------------

1. Fruits
2. Sports

Questions and answers are stored in JSON
{"Question" : "Answer", ...}
format in separate files: Assets/Resources/FruitsDictionary.json and Assets/Resources/SportsDictionary.json.

Rules:
-------
user can make up to MAX_ERRORS=7 mistakes before hangman diagram is complete.
Word is selected at random from the input dictionaries.

Pictures:
----

Simple 2D images:
Assets/HangmanDiagram/[0,7].jpg

UI flow:
--------
1. MainScene: WordDashesView + HangmanDiagram + ControlPanel
2. FinalDialogue

Tech stack:
----------

Unity 5.6.1f1

Target platform:
---------------

PC, win 10, 64bit

repository: ivan-golubev/unityhangman

gha_language: C#

repo_name: ivan-golubev/unityhangman


text:
# masking-agent-plus
UserAgent changer extension for Firefox based on MaskingAgent addon

# Original
https://addons.mozilla.org/ja/firefox/addon/masking-agent/

# How to use
This addon is not signed. So you can enable this addon only temporarily by using Firefox's "Debug addon" feature.

repository: Cosmostrix/masking-agent-plus

repo_name: Cosmostrix/masking-agent-plus


text:
# Receiving Sorting and Sending Physical Mail

## Receiving

Our mailing address is:

4327 Butler St
Pittsburgh PA 15201

We have mail cubbies in the front of the office with numbers and names. If you'd like a mailbox, put your name on it. If you'd like to get mail, add the number of the box to incoming mail, like this:

Some One
4327 Butler St
Suite 12
Pittsburgh PA 15201

## Sorting

The mail is community sorted. If you see mail in front of the mail cubbies, pick up the stack and put mail with Suite numbers in to cubbies with matching numbers. No one is currently responsible for sorting mail. Sometimes mail piles up unsorted. Be warned.

## Sending Physical Mail

Since we have so many members, on most days we have a UPS employee come to the space.  Again, this is an ad-hock system.

## Why this way?

The numbers are to make it easier to find the correct box. Previously, we just had user names, and matching a letter with a sea of un-sorted names was very difficult. Having number facilitates community sorting. The numbers also facilitate better google foo. If one exact address has too many business names attached to it, google penalized those companies as they seem less real. If you care about people finding you on the inter-webs, because use a number.

The mail is community sorted for the simple fact that it keeps costs down.

repository: catsheane/main

repo_name: catsheane/main


text:
# Morpheus Python Module

[![Documentation Status](https://readthedocs.org/projects/pymorpheus/badge/?version=latest)](https://pymorpheus.readthedocs.io/en/latest/?badge=latest)

## Installation

`pip install pymorpheus`

## Usage

MorpheusClient() will either retrieve a token (with username and password args), or use an existing token (with token arg)
Use `sslverify=False` to bypass certificate validation.

MorpheusClient.call() accepts the following vars:
- Required (positional):
  - method: one of string: get, post, put, delete
  - path: api call path after /api/
- Optional:
  - options: list of tuples eg. `[('max','50')]`
  - jsonpayload: JSON string of payload for POST/PUT methods

Reference at https://bertramdev.github.io/morpheus-apidoc

```from pymorpheus import MorpheusClient

morpheus = MorpheusClient("https://yoururl", username="youruser", password="yourpass")
results = morpheus.call("get", path="instances")
print(results)
# JSON Output of results
```

repository: tryfan/pymorpheus

repo_name: tryfan/pymorpheus


text:
This folder generates Figs. 4 and S5.

This folder visualizes factor compositions of the subjects for K = 2, 3 and 4.

---

## What Does Each File Do?

1. `CBIG_wrapper.m` shows how to call the rest two functions.
2. `CBIG_visualize_factorComp.m` visualizes factor compositions in a histogram (for K = 2), a triangle (K = 3), or a tetrahedron (K = 4).
3. `CBIG_visualize_factorComp_mixedAmyloid.m` does basically the same thing, but this time also using colors to show amyloid status.
4. The rest PDF files are our raw figures.

repository: ThomasYeoLab/CBIG

gha_language: MATLAB

repo_name: ThomasYeoLab/CBIG


text:
# Discover module

The discover npm module is a collection of utilities for discovering and registering services.

When a service is first launched, it can use the discover module to register itself to the service registry. As it runs, it can use the discover module to find instances of services that meet specified criteria, enabling it to call a service using a symbolic name rather than its host and port. This level of indirection can be very helpful in a dynamic system where services are created and modified and restarted frequently.

## Invoking the discover module

A node.js service can require the discover module as follows:

```json
const dc = require('@bishopcais/discover');
```

### Registration

If the node.js service wishes to register itself, it can invoke

```json
dc().init({"port": "port at which service is running"});
```

The registration information needed to allow discovery by other services must be provided under the `register` key in the `package.json` file. Here is an example:

```js
{
  "name": "<service-name>",
  // oter information...,
  "register": {
    "instanceName": "m2a2-orchestrator",
    "serviceType": "m2a2-orchestrator",
    "testRoute": "/test",
    "testInterval": 20,
    "launchInvocation": "nohup node m2a2-orchestrator.js -port 55535 -level 2 > orch001.log &",
    "lcManagerRegister": {
      "host": "disembodied-ai.sl.cloud9.ibm.com",
      "port": 1111
    },
    "lcManagerDiscover": {
      "host": "disembodied-ai.sl.cloud9.ibm.com",
      "port": 1111
    }
  }
}
```

In the example above,

* `instanceName` is the name of the instance of the service that will be registered. This is typically not used.
* `serviceType` is the symbolic name that other services should use to refer to this service.
* `testRoute` is the name of a test route that the service registry can ping periodically to tell whether the service is responsive. By default, this route is called `test`, but it can be overridden by the user if desired.
* `testInterval` is the frequency (in seconds) with which the service should be tested for responsiveness.
* `launchInvocation` is a string that could be executed on the command line to invoke the service; it tends not to be used much.
* `lcManagerRegister` is an object that specifies the host and port of the service registry to which the service should register.
* `lcManagerDiscover` is an object that specifies the host and port of the service registry that this service wants to use to find other services.

### Installing the discover routes and functions

For services that use express, a common useful pattern is:

```js
const app = express();
// other code
const server = http.createServer(app);
server.listen(app.get('port'), () => {
  logExpression('Express server listening on port ' + app.get('port'), 1);
  dc().init({
    port: myPort,
  });
  dc().installExpressRoutes(app);
});
```

where `myPort` is the port at which the service is running, and `dc().installExpressRoutes(app)` installs some routes that support pinging the service (which the service registry uses to check whether it is alive) and registration and de-registration.

When dc(init) runs, it installs several service discovery functions and makes them available to the service by exporting them. The next section describes these functions in detail.

## Service discovery functions

All service discovery functions are provided as callbacks, with the callback function denoted as `cb`. In all cases, the callback is of the form

`cb(err, resultJSON)`

where

* `err` is an error object if the function call fails, and
* `resultJSON` is a JSON structure returned by calling the specified host, port and path if the function call succeeds.

If you want the services to return promises instead of callbacks, then you can simply use promisify in the body of the service that is using the discover module, e.g.

```
const getDataFromServiceTypePromise = promisify(dc().getDataFromServiceType);
```

An example of promisification can be found in the file `service-functions.js` of `m2a2-orchestrator`.

### getURL(options, cb)

Options is an object of the following form:

```js
{
  "host": "<host>",
  "port": 1234,
  "path": "<path>"
}
```

where `host`, `port`, and `path` together constitute a known specific address.

`resultJSON` is the JSON that would be returned by calling a `GET` of the host, port and path provided in the `options` object.

### findAgent(serviceType, cb)

`serviceType` is a string that provides the symbolic name of the service to be called.

`resultJSON` is an options object (in the format described under `getURL` above) that contains the host and port that is registered under the symbolic name specified by `serviceType`.

### getDataFromServiceType(serviceType, path, cb)

`serviceType` is a string that provides the symbolic name of the service to be called.

`path` is the path, which will be added to the host and port information once the service registry determines these from the serviceType.

`resultJSON` is the JSON that would be returned by calling a `GET` of the host, port and path derived from the input parameters.

### postDataToService(json, options, cb)

`json` is an object `POST`ed to the service specified in the `options` object.

`resultJSON` is the JSON that would be returned by `POST`ing to the host, port and path specified in `options`.

### postDataToServiceType(json, serviceType, path, cb)

`json` is an object `POST`ed to the service specified by the serviceType and path.

`resultJSON` is the JSON that would be returned by `POST`ing to the host, port and path derived from the input parameters `serviceType` and `path`.

### putDataToService(json, options, cb)

This function is exactly like `postDataToService`, except that it is designed for `PUT` operations rather than `POST`.

### putDataToServiceType(json, serviceType, path, cb)

This function is exactly like `postDataToServiceType`, except that it is designed for `PUT` operations rather than `POST`.

### deleteDataFromService(json, options, cb)

This function is exactly like `postDataToService`, except that it is designed for `DELETE` operations rather than `POST`.

### deleteDataFromServiceType(json, serviceType, path, cb)

This function is exactly like `postDataToServiceType`, except that it is designed for `DELETE` operations rather than `POST`.

repository: bishopcais/discover

repo_name: bishopcais/discover


text:
# Zodiac-Calculator
program that determines zodiac sign based on input given by the user

Created this program using Spyder on a Friday (11/16/18)
Took me some time to figure out how to ensure that the date that can be inputed stays with the range of the days in the month
first tried using range function, but it did not work and would end up print both possible zodiac signs for the given month
went with a if and statement along with elif and else
also had to figure out how to make sure the birth day would be stored as an int and not a str
because i kept of getting prompts that i cannot do for example: 1>=22 because the input was stored as a str so that took most of my time developing this
hope you enjoy
-Shannon Livingstone

repository: s-livingstone/Zodiac-Calculator

repo_name: s-livingstone/Zodiac-Calculator


text:
# Velvethat
A short puzzle game that includes 9 minigames and an in-game currency exchange market. The user interface is implemented in Kivy.
The game's folder structure follows the folders specified here.

sources:
* The sudoku generator is based on this stackoverflow answer: https://stackoverflow.com/questions/45471152/how-to-create-a-sudoku-puzzle-in-python
* The boids algorithm is based on this article: https://alan-turing-institute.github.io/rsd-engineeringcourse/ch01data/084Boids.html

repository: gdies/Velvethat

repo_name: gdies/Velvethat


text:
---
layout: default
---

# 1994-05-20 - Re: Why PGP 2.5 sucks...

## Header Data

From<EMAIL_ADDRESS>(Ray)

To<EMAIL_ADDRESS>Message Hash: 5dc9ce2c7d6fc88c0b6c9ab044ef568bc72c43a3a5001c5a7249bae0c2f2e0bf

Message ID<EMAIL_ADDRESS>Reply To<EMAIL_ADDRESS>UTC Datetime: 1994-05-20 10:04:14 UTC

Raw Date: Fri, 20 May 94 03:04:14 PDT

## Raw message

```
{% raw  %}From<EMAIL_ADDRESS>(Ray)
Date: Fri, 20 May 94 03:04:14 PDT
To<EMAIL_ADDRESS>Subject: Re: Why PGP 2.5 sucks...
In-Reply-To<EMAIL_ADDRESS>Message-ID<EMAIL_ADDRESS>MIME-Version: 1.0
Content-Type: text/plain

Ray Cromwell writes:
> PGP 2.5 really sucks...
>
> Why?
>  - You can't use your old secret key. So you have to build a new one.
>    Why? I don't know. But PGP 2.5 don't recognize your pass phrase anymore.
>    Maybe that new RSA algoritme is easier to crack. So they force everybody
>    to create a new key...

   Seems like it should be a simple task to code up a utility to convert
old format keys to new ones.

-Ray

{% endraw %}
```

## Thread

+ Return to [May 1994](/archive/1994/05)

+ Return to<EMAIL_ADDRESS>(Ray)](/authors/rjc_at_gnu_ai_mit_edu_ray_)"

+ _Unknown thread root_
  + 1994-05-20 (Fri, 20 May 94 03:04:14 PDT) - Re: Why PGP 2.5 sucks... -<EMAIL_ADDRESS>(Ray)_


text:
---
layout: default
title: About
permalink: /about
---

About Spacecraft
================

The Pattern
-----------

Spacecraft came about because I was the guy left with integrating registers
definitions from all over the place and formatting them into coherent views
for simulations, validation benches, driver software, and the engineering &
customer docs.  Since the tool I was using didn't handle every input and output
I needed I wrote a lot of scripts to "move" the definitions along from where
they were to where they needed to go.

Script after script after script had the same pattern:

1. Read definitions in some format and construct a "model"
2. Write out the definitions in some other format

In many cases the input format was line based, and constructing "the model" was
as trivial as splitting a line into variables.  But those were the easy cases
where all the structural information had been stripped away - i.e. a flat space.

The Problem: Logical Representations
------------------------------------

Eventually the transformations needed the structural information because I was
no longer managing flat spaces, but **logical representations**, which I define
as: a selected subset of the physical implementation.

A flat space is one logical representation.  However a flat space does not
convey any hardware reuse information, so it is not conveyed to software.  A
fully elaborated physical implementation is another logical representation.
This representation carries the hardware reuse information, but carries it to
the extreme, as it also includes all the "dirty laundry" of the physical
implementation (such as the regioning of the space by design assignment - a
logically irrelevant regioning to everybody other than the assigned designers,
*especially customers*).

A **good logical representation** lies somewhere in between the fully flattened
and fully elaborated representations. A good logical representation, however,
does not just happen: **it must be designed**.

Managing logical represenations made each transformation more complex, as the
structural information needed to find it's way from the input to the output
at each stage.  This, in turn, made the model for each transformation more and
more complex.  And as one transformation lead to the next, I'd have start from
scratch and create a new model for each transformation.  What a pain.

The Genesis: Model Abstraction
------------------------------

The model needed abstraction.  But since the model is memory resident and
run-time transient, it needed a clear definition and API for interfacing
with it.

Most tools only support the extremes of logical representation: fully flattened
or fully elaborated, so the model was designed to manage the logical
representation above and beyond the physical implementation.  The result was
the minimalist model and it's API now in Spacecraft, albeit in script format.

Soon after abstracting the model into a reusable package, the pattern of the
scripts become even more evident. Now every script had:

1. A read function that used the API to construct the model.
2. A write function that used the API to write out the model.

It was immediately obvious that the read & write functions should be moved to
into a library so the the inputs and outputs could be mixed and matched.

The Refinement: Porting for Performance
---------------------------------------

The thing was: implementing the model in script format meant it was slow - really
slow.  Especially as the volume of information to be transformed became large.
So before I could push the I/O functions into a library, I needed to deal with
speed.

I moved the API and the model into C and swigged the API.  This improved the
performance by orders of magnitude, so was well worth the effort.

The Side Effects: An Embedded Interpretter Extension & A Native Parser
----------------------------------------------------------------------

While mucking around with extending the interpretter with C, it also occured to
me that if I could embedded the extended interpretter and pass the model between
scripts, I could build a library of read and write _scripts_ instead of a library
of read & write _functions_.  Each script would focus on one half of the problem,
so mixing and matching formats would become command line options.  This would
be far more portable and furthermore the scripts could serve as examples of API
usage examples for anyone else that needed to "move" a model from one format
to another.  A tinker here and a tinker there and then I found myself with an
executable with an embedded interpretter that could execute multiple scripts and
pass the model between them: let the scripting begin.  Well not quite.

With the executable and not the interpretter as the main program, it became
clear that the model needed a file format that could be read natively in C. This
lead to a syntax and grammar definition and the corresponding Flex lexer and
Bison parser was added to the program.

Spacecraft
----------

Spacecraft is an evolution of that first executable.  It has been built from the
ground up with all of the benefits and none of the warts.  It is also freely
available with an open source library of scripts.

repository: enforcedvalid/launchpad

repo_name: enforcedvalid/launchpad


text:
# TinyTinyRSS Tool
`ttrss-tool` makes it easy to view and manipulate the feeds your Tiny Tiny RSS
account is subscribed to. It communicates with your tt-rss server using the
[tt-rss API](http://tt-rss.org/redmine/projects/tt-rss/wiki/JsonApiReference).

`ttrss-tool` was developed by [Jeremy W. Sherman](https://jeremywsherman.com)
and lives at [jeremy-w/ttrss-tool](https://github.com/jeremy-w/ttrss-tool).

`ttrss-tool` goes great with [Newsbeuter](http://newsbeuter.org/).
(It seemed a shame to have to hit the Web to edit your feedlist when using
ttrss as the backend, and thus was `ttrss-tool` born.)

## Usage
- `ttrss-tool ls [-lR] [catpath]`
  lists categories at `/` (default) or categories and feeds contained in
  the specified category.
- `ttrss-tool ln feed_url [catpath]`
  links a new feed into the specified category.
  If no category is specified, or `/` is specified, the feed is added to the
  default "Uncategorized" category.
- `ttrss-tool mkdir title`
  creates a new category.
  Due to API limitations, we can only create a top-level category.
- `ttrss-tool rm feed_spec`
  removes the specified feed.
  The feed can be specified by title using a catpath,
  by URL, or by numeric ID.
  (You can find the latter two bits of info using `ls -l`.)

## Authentication
`ttrss-tool` requires three pieces of information to operate:

- The address of your ttrss instance, such as `https://example.com/ttrss/`.
- Your account name on that instance.
- Your password.

You can supply this info by creating a config file `config` in a `ttrss-tool`
directory in `$XDG_CONFIG_HOME` (which defaults to `$HOME/.config`).

The config file should look like:

```json
{
  "addr": "https://example.com/ttrss/",
  "user": "alice",
  "pass": "keepoutmallory"
}
```

or

```json
{
  "addr": "https://example.com/ttrss/",
  "user": "alice"
}
```

With the latter form, you can either supply the password as a commandline flag,
or let `ttrss-tool` prompt you for it.

You can also supply this information as commandline flags:

- `-a,--addr`: the address of your ttrss instance, like
  `https://example.org/ttrss`
- `-u,--user`: the user name
- `-p,--pass`: the password

If both dotfile and commandline flags are present, then the flags win.

**NOTE:** The dotfile is just a JSON version of the long commandline flags.

## Printing Categories and Feeds
**TODO:** Describe how feeds and categories are displayed, and what the fields
mean.

license: ISC

repository: jeremy-w/ttrss-tool

repo_name: jeremy-w/ttrss-tool