text:
## Introduction

**yar** add session support to hapi - a persistent state across multiple browser requests using an [iron](https://hapi.dev/module/iron) encrypted cookie and server-side storage. **yar** tries to fit session data into a session cookie based  on a configured maximum size. If the content is too big to fit, it uses server storage via the [hapi plugin cache](https://hapi.dev/api#server.cache()) interface.

### Differences from @hapi/cookie

The **@hapi/cookie** plugin provides similar facilities to **yar**. The approach of the two projects does differ in some regards, though.
1. **yar** is focused on session support, and does not require that a user be logged in to have a session. **@hapi/cookie** only provides session storage for logged in users.  If you need session handling for non-authenticated users, use **yar**.
1. **yar** is capable of handling larger data sizes without any additional setup.  If your session data gets larger than cookies can handle **yar** will push the data out to the server cache for you.  By default this is memory storage, but can be any [catbox](https://hapi.dev/module/catbox) supported cache storage, including mongo, redis, local disk, and more.  **@hapi/cookie** can support larger session size as well, but requires you to handle connecting the cookie based session with your external data storage.

## Example

For example, the first handler sets a session key and the second gets it:
```js
let handler1 = (request, reply) => {

    request.yar.set('example', { key: 'value' });

    return null;
};

let handler2 = (request, reply) => {

    const example = request.yar.get('example');
    return example.key;     // Will send back 'value'
};
```

The plugin requires a password for encryption that must be at least 32 characters long:
```js
let options = {
    storeBlank: false,
    cookieOptions: {
        password: 'the-password-must-be-at-least-32-characters-long',
        isSecure: true
    }
};
/*
Please note that there are other default cookie options that can impact your security.
Please look at the description of the cookie options below to make sure this is doing
what you expect.
*/

const server = new Hapi.Server();

try {
  await server.register({
      plugin: require('@hapi/yar'),
      options: options
  });
} catch(err) {
    console.error(err);
}

await server.start();
```

## Password considerations

Keep in mind some things in regard to your password:

1. It should never be committed to the repository or hard coded in your code.  Instead pass the password via environment variables or some other server configuration management option.
1. In some situations it is possible that your password could be attacked remotely.  So choose a password that is randomly generated.  Use a random password generator to create something rather than creating your own.  Make sure it is long and includes special characters.
1. Consider rotating your cookie session password on a regular basis.

## Cookie Options

You can read about more cookie options in the [cookie options](#options) section.

### isSecure

Set `isSecure` (default `true`) to `false` if you are using standard http. Take care to do this in development mode only though. You don't want to use cookies sent over insecure channels for session management.  One way to take care of this is to use the `NODE_ENV` environment variable like this:

```js
let options = {
    cookieOptions: {
        isSecure: process.env.NODE_ENV !== 'development',
        ...
    }
};
```

### ignoreErrors

`ignoreErrors` (default `true`) tells hapi that it should not respond with a HTTP 400 error if the session cookie cannot decrypt.  This could happen if the cookie is changed on the client, or more likely, if you change the cookie password in your settings.  If you want to make this condition send an error like it did in prior versions, change this to `false`, but be aware that if you change your cookie password you will cause 400 errors to be returned to end users.  In that case you should probably change this back to true for a short time to allow session cookies to get reset for the best user experience.

You may turn this off, `false`, and try to use the hapi route state config option of `failAction` to instead get an event whenever a bad session cookie is encountered.  This can allow more sophisticated handling strategies or even allow for mitigation of brute force attacks on your cookie password.  See [server.state()](https://hapi.dev/api#server.state()) documentation for more details.

### clearInvalid

`clearInvalid` (default `true`) tells hapi that if a session cookie is invalid for any reason, to clear it from the browser.  This prevents hapi from having to reprocess the bad cookie on future requests.  In general you'll probably want this on, but if you'd prefer that session cookies be dealt with in some other way you may set this to `false`.

## Options

- `name` - determines the name of the cookie used to store session information. Defaults to _session_.
- `maxCookieSize` - maximum cookie size before using server-side storage. Defaults to 1K. Set to zero to always use server-side storage.
- `storeBlank` - determines whether to store empty session before they've been modified. Defaults to _true_.
- `errorOnCacheNotReady` - will cause yar to throw an exception if trying to persist to cache when the cache is unavailable. Setting this to false will allow applications using yar to run uninterrupted if the cache is not ready (however sessions will not be saving). Defaults to _true_.
- `cache` - **hapi** [cache options](https://hapi.dev/api#server.cache()) which includes
  (among other options):
    - `expiresIn` - server-side storage expiration (defaults to 1 day).
- `cookieOptions` - the configuration for cookie-specific features:
    - `password` - (Required) used to encrypt and sign the cookie data.
    - `path` - determines the cookie path. Defaults to _'/'_.
    - `isSameSite` - enables the `same-site` cookie parameter.  Default to 'Lax'.  Can be `'Strict'|'Lax'|'None'|false`.
    - `isSecure` - determines whether or not to transfer using TLS/SSL. Defaults to _true_.
    - `isHttpOnly` - determines whether or not to set HttpOnly option in cookie. Defaults to _false_.
    - `ttl` - sets the time for the cookie to live in the browser, in milliseconds.  Defaults to null (session time-life - cookies are deleted when the browser is closed).
    - `contextualize` - a function using the signature `async function(definition, request)` used to override a request-specific cookie settings where:
        - `definition` - a copy of the `options` to be used for formatting the cookie that can be manipulated by the function to customize the request cookie header. Note that changing the `definition.contextualize` property will be ignored.
        - `request` - the current request object.
- `customSessionIDGenerator` - an optional function to create custom session IDs. Must return a string and have the signature `function (request)` where:
    - `request` - (optional) is the original **request** received from the client.

### Route Options
You can also add these options on a route per route basis at `config.plugins.yar`:

- `skip` - a boolean value which, if true, means no session will be attached to the request (defaults to false).

### Methods

**yar** adds the `yar` property to every request object and initializes the `yar.id` on the first request from each browser. The `request.yar` interface provides the following methods:

- `reset()` - clears the session and assigns a new session id.
- `set(key, value)` - assigns a value (string, object, etc) to a given key which will persist across requests.  Returns the value.
- `set(keysObject)` - assigns values to multiple keys using each 'keysObject' top-level property. Returns the keysObject.
- `get(key, clear)` - retrieve value using a key. If 'clear' is 'true', key is cleared on return.
- `clear(key)` - clears key.
- `touch()` - Manually notify the session of changes (when using `get()` and changing the content of the returned reference directly without calling `set()`).
- `flash(type, message, isOverride)` - stores volatile data - data that should be deleted once read. When given no arguments, it will return all of the flash messages and delete the originals. When given only a type, it will return all of the flash messages of that type and delete the originals. When given a type and a message, it will set or append that message to the given type. 'isOverride' used to indicate that the message provided should replace any existing value instead of being appended to it (defaults to false).
- `lazy(enabled)` - if set to 'true', enables lazy mode. In lazy mode, `request.yar` can be modified directly (e.g. setting `request.yar.myKey` to an object value), and those keys will be stored and loaded back. Lazy mode isn't as fast as the normal get/set because it has to store the session state on every responses regardless of any changes being made.
- `await commit(h)` - used to manually prepare the session state and commit it into the response when the response is taken over in an `onPreResponse` handler. Normally, the **yar** `onPreResponse` handler performs the commit, but if an application extension handler takes over, **yar** doesn't get a chance to commit the state before the response goes out. The method requires the hapi `h` toolkit argument available in the extension handler.

**yar** adds the `yar` property to the server instance. The `server.yar` interface provides the following methods:

- `revoke(id)` - revokes the specified session.

repository: hapijs/yar

gha_license_id: NOASSERTION

repo_name: hapijs/yar


text:
1.1
===

* [BC BREAK] The MakerInterface changed: `writeNextStepsMessage`
  was renamed to `writeSuccessMessage`. You should now extend
  `AbstractMaker` instead of implementing the interface directly,
  and use `parent::writeSuccessMessage()` to get the normal success
  message after the command.

license: MIT

repository: MounaHelloPi/maker-bundle

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: MounaHelloPi/maker-bundle


text:
# Connection establishment

## wikipedia [Transmission Control Protocol](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) # 4.1 Connection establishment

To establish a connection, TCP uses a three-way [handshake](https://en.wikipedia.org/wiki/Handshaking). Before a client attempts to connect with a server, the server must first **bind** to and **listen** at a **port** to open it up for connections: this is called a **passive open**. Once the **passive open** is established, a client may initiate an **active open**. To establish a **connection**, the three-way (or 3-step) handshake occurs:

1) **SYN**: The **active open** is performed by the client sending a **SYN** to the server. The client sets the segment's **sequence number** to a random value `A`.

2) **SYN-ACK**: In response, the server replies with a SYN-ACK. The **acknowledgment number** is set to one more than the **received sequence number** i.e. `A+1`, and the **sequence number** that the server chooses for the packet is another random number, `B`.

> NOTE: SYN-ACK其实可以看做是同时发送SYN和ACK

3) **ACK**: Finally, the client sends an ACK back to the server. The **sequence number** is set to the **received acknowledgement value** i.e. `A+1`, and the **acknowledgement number** is set to one more than the received sequence number i.e. `B+1`.

> NOTE: 为什么是plus 1？在`Network\Theory\TCP\TCP-SEQ-number-and-ACK-number.md`的cnblogs [TCP 中的Sequence Number](https://www.cnblogs.com/JenningsMao/p/9487252.html)中对这个问题进行解释

At this point, both the client and server have received an acknowledgment of the connection. The steps 1, 2 establish the connection parameter (**sequence number**) for one direction and it is acknowledged. The steps 2, 3 establish the connection parameter (**sequence number**) for the other direction and it is acknowledged. With these, a **full-duplex communication** is established.

> NOTE: full-duplex，每个direction都有对应的connection parameter: sequence number。

> NOTE: 在文章packetlife [Understanding TCP Sequence and Acknowledgment Numbers](https://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/) 中展示了如何使用wireshark来观察connection establishment的过程，这篇文章收录在`Network\Theory\TCP\TCP-SEQ-number-and-ACK-number.md`中。

repository: dantefung/Linux-OS

repo_name: dantefung/Linux-OS


text:
# pynics
## Python scripts for computing Nuclear Independent Chemical Shifts and buildup functions from Castep data

The chemical shift at which a nuclear environment appears in solid-state NMR is dependent not only on the local intramolecular interactions affecting that environment, but also on interactions with longer range features such as ring currents and hydrogen bonding. Utilising DFT GIPAW calculations, it is possible to partition the contributions of these different features to chemical shift. Further, it is possible to observe the spatial effects of these contributions, and the distance at which these contributions arise.

See the below 'how-to's for how pynics can perform such analysis and see the CCP-NC website for the full protocol: https://www.ccpnc.ac.uk/

### How to install

pynics is available on the Python Package Index. You can install the latest stable release by using `pip`:

    pip install pynics --user

It's recommended to use a virtual environment to reduce the chance of conflicts with the rest of your environment. With conda you could do:

 1. Create conda virtual environment
    `conda create --name pynicsenv`
 2. Activate the conda environment
    `conda activate pynicsenv`
 3. Make sure pip is installed
    `conda install pip`
 4. pip-install pynics with it's dependencies.
    `pip install pynics`

You could also use virtualenv to manage your virtual environments.

Alternatively, you can get the latest version (not guaranteed to be stable) from github:

    git clone https://github.com/CCP-NC/pynics.git
    pip install ./pynics --user

This approach should work even on machines for which one does not possess admin privileges (such as HPC clusters), as long as Python and `pip` are present.
Numpy, ASE and soprano are requirements. Install with pip:

    pip install ./ --user

in the pynics folder.

### How to use (lorentz_buildup_nics)

1. Run a Castep NMR calculation on the system of interest and store the currents in a binary file - this is done by using the
`MAGRES_WRITE_RESPONSE: TRUE` parameter in the `.param` file;
2. Create a `.nicslist` file, formatted like the `.cell` file, with a single `NICS_POINTS_FRAC` block, listing the
fractional coordinates of all points for which the NICS buildup functions are desired, or a `NICS_POINTS_ABS` block, which can use cartesian coordinates.
3. Run the command line tool:

    `lorentz_buildup_nics <seedname>`

with the seedname of the system, in the same folder as the Castep calculation.
Use `lorentz_buildup_nics -h` for a list of additional command line parameters.

### How to use (nicsanalyse)

1. A single unit cell of the system of interest should be geometry optimized using Castep.
2. This unit cell should then be propagated to a supercell such that there is a separation > 10 Å between a central molecule and the next cell.
3. The `splitcell` utility can then be run on this, with the following options

```
splitcell 	--struct <structure file> \
		--nicslist <file to output nicslist>
```

4. The output cell files should then have Castep GIPAW calculations done performed on them, following the same steps as above for lorentz_buildup_nics (e.g., pass the `MAGRES_WRITE_RESPONSE:True` parameter). The `.nicslist` should be the output nicslist of `splitcell.py`.
5. On the resulting current files, run the `nicsanalyse` utility as

```
nicsanalyse        --nicslist <path to nicslist> \
		   --nomol_magres <path to nomol magres> \
		   --onemol_magres <path to onemol magres> \
		   --supercell_magres <path to supercell magres> \
		   --output <output file>
```

### Cite
This library was originally created to carry out the calculations in the "The Lorentz Sphere visualised" paper. If you use this code in your work, please cite:

S. Sturniolo and J. R. Yates , "The Lorentz sphere visualised", J. Chem. Phys. 150, 094103 (2019) https://doi.org/10.1063/1.5080298

```
@article{doi:10.1063/1.5080298,
	author = {Sturniolo,S.  and Yates,J. R. },
	title = {The Lorentz sphere visualised},
	journal = {The Journal of Chemical Physics},
	volume = {150},
	number = {9},
	pages = {094103},
	year = {2019},
	doi = {10.1063/1.5080298},
	URL = {https://doi.org/10.1063/1.5080298}
}
```

repository: CCP-NC/pynics

gha_language: Python

gha_license_id: MIT

repo_name: CCP-NC/pynics


text:
[![CircleCI](https://circleci.com/gh/ddd-by-examples/library.svg?style=svg)](https://circleci.com/gh/ddd-by-examples/library)
[![Code Coverage](https://codecov.io/gh/ddd-by-examples/library/branch/master/graph/badge.svg)](https://codecov.io/gh/ddd-by-examples/library)

# Table of contents

1. [About](#about)
2. [Domain description](#domain-description)
3. [General assumptions](#general-assumptions)
    3.1 [Process discovery](#process-discovery)
    3.2 [Project structure and architecture](#project-structure-and-architecture)
    3.3 [Aggregates](#aggregates)
    3.4 [Events](#events)
    3.4.1 [Events in Repositories](#events-in-repositories)
    3.5 [ArchUnit](#archunit)
    3.6 [Functional thinking](#functional-thinking)
    3.7 [No ORM](#no-orm)
    3.8 [Architecture-code gap](#architecture-code-gap)
    3.9 [Model-code gap](#model-code-gap)
    3.10 [Spring](#spring)
    3.11 [Tests](#tests)
4. [How to contribute](#how-to-contribute)
5. [References](#references)

## About

This is a project of a library, driven by real [business requirements](#domain-description).
We use techniques strongly connected with Domain Driven Design, Behavior-Driven Development,
Event Storming, User Story Mapping.

## Domain description

A public library allows patrons to place books on hold at its various library branches.
Available books can be placed on hold only by one patron at any given point in time.
Books are either circulating or restricted, and can have retrieval or usage fees.
A restricted book can only be held by a researcher patron. A regular patron is limited
to five holds at any given moment, while a researcher patron is allowed an unlimited number
of holds. An open-ended book hold is active until the patron checks out the book, at which time it
is completed. A closed-ended book hold that is not completed within a fixed number of
days after it was requested will expire. This check is done at the beginning of a day by
taking a look at daily sheet with expiring holds. Only a researcher patron can request
an open-ended hold duration. Any patron with more than two overdue checkouts at a library
branch will get a rejection if trying a hold at that same library branch. A book can be
checked out for up to 60 days. Check for overdue checkouts is done by taking a look at
daily sheet with overdue checkouts. Patron interacts with his/her current holds, checkouts, etc.
by taking a look at patron profile. Patron profile looks like a daily sheet, but the
information there is limited to one patron and is not necessarily daily. Currently a
patron can see current holds (not canceled nor expired) and current checkouts (including overdue).
Also, he/she is able to hold a book and cancel a hold.

How actually a patron knows which books are there to lend? Library has its catalogue of
books where books are added together with their specific instances. A specific book
instance of a book can be added only if there is book with matching ISBN already in
the catalogue.  Book must have non-empty title and price. At the time of adding an instance
we decide whether it will be Circulating or Restricted. This enables
us to have book with same ISBN as circulated and restricted at the same time (for instance,
there is a book signed by the author that we want to keep as Restricted)

## General assumptions

### Process discovery

The first thing we started with was domain exploration with the help of Big Picture EventStorming.
The description you found in the previous chapter, landed on our virtual wall:
![Event Storming Domain description](docs/images/eventstorming-domain-desc.png)
The EventStorming session led us to numerous discoveries, modeled with the sticky notes:
![Event Storming Big Picture](docs/images/eventstorming-big-picture.jpg)
During the session we discovered following definitions:
![Event Storming Definitions](docs/images/eventstorming-definitions.png)

This made us think of real life scenarios that might happen. We discovered them described with the help of
the **Example mapping**:
![Example mapping](docs/images/example-mapping.png)

This in turn became the base for our *Design Level* sessions, where we analyzed each example:
![Example mapping](docs/images/eventstorming-design-level.jpg)

Please follow the links below to get more details on each of the mentioned steps:
- [Big Picture EventStorming](./docs/big-picture.md)
- [Example Mapping](docs/example-mapping.md)
- [Design Level EventStorming](docs/design-level.md)

### Project structure and architecture
At the very beginning, not to overcomplicate the project, we decided to assign each bounded context
to a separate package, which means that the system is a modular monolith. There are no obstacles, though,
to put contexts into maven modules or finally into microservices.

Bounded contexts should (amongst others) introduce autonomy in the sense of architecture. Thus, each module
encapsulating the context has its own local architecture aligned to problem complexity.
In the case of a context, where we identified true business logic (**lending**) we introduced a domain model
that is a simplified (for the purpose of the project) abstraction of the reality and utilized
hexagonal architecture. In the case of a context, that during Event Storming turned out to lack any complex
domain logic, we applied CRUD-like local architecture.

![Architecture](docs/images/architecture-big-picture.png)

If we are talking about hexagonal architecture, it lets us separate domain and application logic from
frameworks (and infrastructure). What do we gain with this approach? Firstly, we can unit test most important
part of the application - **business logic** - usually without the need to stub any dependency.
Secondly, we create ourselves an opportunity to adjust infrastructure layer without the worry of
breaking the core functionality. In the infrastructure layer we intensively use Spring Framework
as probably the most mature and powerful application framework with an incredible test support.
More information about how we use Spring you will find [here](#spring).

As we already mentioned, the architecture was driven by Event Storming sessions. Apart from identifying
contexts and their complexity, we could also make a decision that we separate read and write models (CQRS).
As an example you can have a look at **Patron Profiles** and *Daily Sheets*.

### Aggregates
Aggregates discovered during Event Storming sessions communicate with each other with events. There is
a contention, though, should they be consistent immediately or eventually? As aggregates in general
determine business boundaries, eventual consistency sounds like a better choice, but choices in software
are never costless. Providing eventual consistency requires some infrastructural tools, like message broker
or event store. That's why we could (and did) start with immediate consistency.

> Good architecture is the one which postpones all important decisions

... that's why we made it easy to change the consistency model, providing tests for each option, including
basic implementations based on **DomainEvents** interface, which can be adjusted to our needs and
toolset in future. Let's have a look at following examples:

* Immediate consistency
    ```groovy
    def 'should synchronize Patron, Book and DailySheet with events'() {
        given:
            bookRepository.save(book)
        and:
            patronRepo.publish(patronCreated())
        when:
            patronRepo.publish(placedOnHold(book))
        then:
            patronShouldBeFoundInDatabaseWithOneBookOnHold(patronId)
        and:
            bookReactedToPlacedOnHoldEvent()
        and:
            dailySheetIsUpdated()
    }

    boolean bookReactedToPlacedOnHoldEvent() {
        return bookRepository.findBy(book.bookId).get() instanceof BookOnHold
    }

    boolean dailySheetIsUpdated() {
        return new JdbcTemplate(datasource).query("select count(*) from holds_sheet s where s.hold_by_patron_id = ?",
                [patronId.patronId] as Object[],
                new ColumnMapRowMapper()).get(0)
                .get("COUNT(*)") == 1
    }
    ```
   _Please note that here we are just reading from database right after events are being published_

   Simple implementation of the event bus is based on Spring application events:
    ```java
    @AllArgsConstructor
    public class JustForwardDomainEventPublisher implements DomainEvents {

        private final ApplicationEventPublisher applicationEventPublisher;

        @Override
        public void publish(DomainEvent event) {
            applicationEventPublisher.publishEvent(event);
        }
    }
    ```

* Eventual consistency
    ```groovy
    def 'should synchronize Patron, Book and DailySheet with events'() {
        given:
            bookRepository.save(book)
        and:
            patronRepo.publish(patronCreated())
        when:
            patronRepo.publish(placedOnHold(book))
        then:
            patronShouldBeFoundInDatabaseWithOneBookOnHold(patronId)
        and:
            bookReactedToPlacedOnHoldEvent()
        and:
            dailySheetIsUpdated()
    }

    void bookReactedToPlacedOnHoldEvent() {
        pollingConditions.eventually {
            assert bookRepository.findBy(book.bookId).get() instanceof BookOnHold
        }
    }

    void dailySheetIsUpdated() {
        pollingConditions.eventually {
            assert countOfHoldsInDailySheet() == 1
        }
    }
    ```
    _Please note that the test looks exactly the same as previous one, but now we utilized Groovy's
    **PollingConditions** to perform asynchronous functionality tests_

    Sample implementation of event bus is following:

    ```java
    @AllArgsConstructor
    public class StoreAndForwardDomainEventPublisher implements DomainEvents {

        private final JustForwardDomainEventPublisher justForwardDomainEventPublisher;
        private final EventsStorage eventsStorage;

        @Override
        public void publish(DomainEvent event) {
            eventsStorage.save(event);
        }

        @Scheduled(fixedRate = 3000L)
        @Transactional
        public void publishAllPeriodically() {
            List<DomainEvent> domainEvents = eventsStorage.toPublish();
            domainEvents.forEach(justForwardDomainEventPublisher::publish);
            eventsStorage.published(domainEvents);
        }
    }
    ```

To clarify, we should always aim for aggregates that can handle a business operation atomically
(transactionally if you like), so each aggregate should be as independent and decoupled from other
aggregates as possible. Thus, eventual consistency is promoted. As we already mentioned, it comes
with some tradeoffs, so from the pragmatic point of view immediate consistency is also a choice.
You might ask yourself a question now: _What if I don't have any events yet?_. Well, a pragmatic
approach would be to encapsulate the communication between aggregates in a _Service-like_ class,
where you could call proper aggregates line by line explicitly.

### Events
Talking about inter-aggregate communication, we must remember that events reduce coupling, but don't remove
it completely. Thus, it is very vital to share(publish) only those events, that are necessary for other
aggregates to exist and function. Otherwise there is a threat that the level of coupling will increase
introducing **feature envy**, because other aggregates might start using those events to perform actions
they are not supposed to perform. A solution to this problem could be the distinction of domain events
and integration events, which will be described here soon.

### Events in Repositories
Repositories are one of the most popular design pattern. They abstract our domain model from data layer.
In other words, they deal with state. That said, a common use-case is when we pass a new state to our repository,
so that it gets persisted. It may look like so:

```java
public class BusinessService {

    private final PatronRepository patronRepository;

    void businessMethod(PatronId patronId) {
        Patron patron = patronRepository.findById(patronId);
        //do sth
        patronRepository.save(patron);
    }
}
```

Conceptually, between 1st and 3rd line of that business method we change state of our Patron from A to B.
This change might be calculated by dirty checking or we might just override entire Patron state in the database.
Third option is _Let's make implicit explicit_ and actually call this state change A->B an **event**.
After all, event-driven architecture is all about promoting state changes as domain events.

Thanks to this our domain model may become immutable and just return events as results of invoking a command like so:

```java
public BookPlacedOnHold placeOnHold(AvailableBook book) {
      ...
}
```

And our repository might operate directly on events like so:

```java
public interface PatronRepository {
     void save(PatronEvent event) {
}
```

### ArchUnit

One of the main components of a successful project is technical leadership that lets the team go in the right
direction. Nevertheless, there are tools that can support teams in keeping the code clean and protect the
architecture, so that the project won't become a Big Ball of Mud, and thus will be pleasant to develop and
to maintain. The first option, the one we proposed, is [ArchUnit](https://www.archunit.org/) - a Java architecture
test tool. ArchUnit lets you write unit tests of your architecture, so that it is always consistent with initial
vision. Maven modules could be an alternative as well, but let's focus on the former.

In terms of hexagonal architecture, it is essential to ensure, that we do not mix different levels of
abstraction (hexagon levels):
```java
@ArchTest
public static final ArchRule model_should_not_depend_on_infrastructure =
    noClasses()
        .that()
        .resideInAPackage("..model..")
        .should()
        .dependOnClassesThat()
        .resideInAPackage("..infrastructure..");
```
and that frameworks do not affect the domain model
```java
@ArchTest
public static final ArchRule model_should_not_depend_on_spring =
    noClasses()
        .that()
        .resideInAPackage("..io.pillopl.library.lending..model..")
        .should()
        .dependOnClassesThat()
        .resideInAPackage("org.springframework..");
```

### Functional thinking
When you look at the code you might find a scent of functional programming. Although we do not follow
a _clean_ FP, we try to think of business processes as pipelines or workflows, utilizing functional style through
following concepts.

_Please note that this is not a reference project for FP._

#### Immutable objects
Each class that represents a business concept is immutable, thanks to which we:
* provide full encapsulation and objects' states protection,
* secure objects for multithreaded access,
* control all side effects much clearer.

#### Pure functions
We model domain operations, discovered in Design Level Event Storming, as pure functions, and declare them in
both domain and application layers in the form of Java's functional interfaces. Their implementations are placed
in infrastructure layer as ordinary methods with side effects. Thanks to this approach we can follow the abstraction
of ubiquitous language explicitly, and keep this abstraction implementation-agnostic. As an example, you could have
a look at `FindAvailableBook` interface and its implementation:

```java
@FunctionalInterface
public interface FindAvailableBook {

    Option<AvailableBook> findAvailableBookBy(BookId bookId);
}
```

```java
@AllArgsConstructor
class BookDatabaseRepository implements FindAvailableBook {

    private final JdbcTemplate jdbcTemplate;

    @Override
    public Option<AvailableBook> findAvailableBookBy(BookId bookId) {
        return Match(findBy(bookId)).of(
                Case($Some($(instanceOf(AvailableBook.class))), Option::of),
                Case($(), Option::none)
        );
    }

    Option<Book> findBy(BookId bookId) {
        return findBookById(bookId)
                .map(BookDatabaseEntity::toDomainModel);
    }

    private Option<BookDatabaseEntity> findBookById(BookId bookId) {
        return Try
                .ofSupplier(() -> of(jdbcTemplate.queryForObject("SELECT b.* FROM book_database_entity b WHERE b.book_id = ?",
                                      new BeanPropertyRowMapper<>(BookDatabaseEntity.class), bookId.getBookId())))
                .getOrElse(none());
    }
}
```

#### Type system
_Type system - like_ modelling - we modelled each domain object's state discovered during EventStorming as separate
classes: `AvailableBook`, `BookOnHold`, `CheckedOutBook`. With this approach we provide much clearer abstraction than
having a single `Book` class with an enum-based state management. Moving the logic to these specific classes brings
Single Responsibility Principle to a different level. Moreover, instead of checking invariants in every business method
we leave the role to the compiler. As an example, please consider following scenario: _you can place on hold only a book
that is currently available_. We could have done it in a following way:
```java
public Either<BookHoldFailed, BookPlacedOnHoldEvents> placeOnHold(Book book) {
  if (book.status == AVAILABLE) {
      ...
  }
}
```
but we use the _type system_ and declare method of following signature
```java
public Either<BookHoldFailed, BookPlacedOnHoldEvents> placeOnHold(AvailableBook book) {
      ...
}
```
The more errors we discover at compile time the better.

Yet another advantage of applying such type system is that we can represent business flows and state transitions
with functions much easier. As an example, following functions:
```
placeOnHold: AvailableBook -> BookHoldFailed | BookPlacedOnHold
cancelHold: BookOnHold -> BookHoldCancelingFailed | BookHoldCanceled
```
are much more concise and descriptive than these:
```
placeOnHold: Book -> BookHoldFailed | BookPlacedOnHold
cancelHold: Book -> BookHoldCancelingFailed | BookHoldCanceled
```
as here we have a lot of constraints hidden within function implementations.

Moreover if you think of your domain as a set of operations (functions) that are being executed on business objects
(aggregates) you don't think of any execution model (like async processing). It is fine, because you don't have to.
Domain functions are free from I/O operations, async, and other side-effects-prone things, which are put into the
infrastructure layer. Thanks to this, we can easily test them without mocking mentioned parts.

#### Monads
Business methods might have different results. One might return a value or a `null`, throw an exception when something
unexpected happens or just return different objects under different circumstances. All those situations are typical
to object-oriented languages like Java, but do not fit into functional style. We are dealing with this issues
with monads (monadic containers provided by [Vavr](https://www.vavr.io)):
* When a method returns optional value, we use the `Option` monad:

    ```java
    Option<Book> findBy(BookId bookId) {
        ...
    }
    ```

* When a method might return one of two possible values, we use the `Either` monad:

    ```java
    Either<BookHoldFailed, BookPlacedOnHoldEvents> placeOnHold(AvailableBook book) {
        ...
    }
    ```

* When an exception might occur, we use `Try` monad:

    ```java
    Try<Result> placeOnHold(@NonNull PlaceOnHoldCommand command) {
        ...
    }
    ```

Thanks to this, we can follow the functional programming style, but we also enrich our domain language and
make our code much more readable for the clients.

#### Pattern Matching
Depending on a type of a given book object we often need to perform different actions. Series of if/else or switch/case statements
could be a choice, but it is the pattern matching that provides the most conciseness and flexibility. With the code
like below we can check numerous patterns against objects and access their constituents, so our code has a minimal dose
of language-construct noise:
```java
private Book handleBookPlacedOnHold(Book book, BookPlacedOnHold bookPlacedOnHold) {
    return API.Match(book).of(
        Case($(instanceOf(AvailableBook.class)), availableBook -> availableBook.handle(bookPlacedOnHold)),
        Case($(instanceOf(BookOnHold.class)), bookOnHold -> raiseDuplicateHoldFoundEvent(bookOnHold, bookPlacedOnHold)),
        Case($(), () -> book)
    );
}
```

### (No) ORM
If you run `mvn dependency:tree` you won't find any JPA implementation. Although we think that ORM solutions (like Hibernate)
are very powerful and useful, we decided not to use them, as we wouldn't utilize their features. What features are
talking about?  Why don't we need them? We want to have more control
over SQL queries and minimize the object-relational impedance mismatch ourselves. Moreover, thanks to relatively
small aggregates, containing as little data as it is required to protect the invariants, we don't need the
lazy loading mechanism either.
With Hexagonal Architecture we have the ability to separate domain and persistence models and test them
independently. Moreover, we can also introduce different persistence strategies for different aggregates.
In this project, we utilize both plain SQL queries and `JdbcTemplate` and use new and very promising
project called Spring Data JDBC, that is free from the JPA-related overhead mentioned before.
Please find below an example of a repository:

```java
interface PatronEntityRepository extends CrudRepository<PatronDatabaseEntity, Long> {

    @Query("SELECT p.* FROM patron_database_entity p where p.patron_id = :patronId")
    PatronDatabaseEntity findByPatronId(@Param("patronId") UUID patronId);

}
```

At the same time we propose other way of persisting aggregates, with plain SQL queries and `JdbcTemplate`:

```java
@AllArgsConstructor
class BookDatabaseRepository implements BookRepository, FindAvailableBook, FindBookOnHold {

    private final JdbcTemplate jdbcTemplate;

    @Override
    public Option<Book> findBy(BookId bookId) {
        return findBookById(bookId)
                .map(BookDatabaseEntity::toDomainModel);
    }

    private Option<BookDatabaseEntity> findBookById(BookId bookId) {
        return Try
                .ofSupplier(() -> of(jdbcTemplate.queryForObject("SELECT b.* FROM book_database_entity b WHERE b.book_id = ?",
                                     new BeanPropertyRowMapper<>(BookDatabaseEntity.class), bookId.getBookId())))
                .getOrElse(none());
    }

    ...
}
```
_Please note that despite having the ability to choose different persistence implementations for aggregates
it is recommended to stick to one option within the app/team_

### Architecture-code gap
We put a lot of attention to keep the consistency between the overall architecture (including diagrams)
and the code structure. Having identified bounded contexts we could organize them in modules (packages, to
be more specific). Thanks to this we gain the famous microservices' autonomy, while having a monolithic
application. Each package has well defined public API, encapsulating all implementation details by using
package-protected or private scopes.

Just by looking at the package structure:

```
└── library
    ├── catalogue
    ├── commons
    │   ├── aggregates
    │   ├── commands
    │   └── events
    │       └── publisher
    └── lending
        ├── book
        │   ├── application
        │   ├── infrastructure
        │   └── model
        ├── dailysheet
        │   ├── infrastructure
        │   └── model
        ├── librarybranch
        │   └── model
        ├── patron
        │   ├── application
        │   ├── infrastructure
        │   └── model
        └── patronprofile
            ├── infrastructure
            ├── model
            └── web
```
you can see that the architecture is screaming that it has two bounded contexts: **catalogue**
and **lending**. Moreover, the **lending context** is built around five business objects: **book**,
**dailysheet**, **librarybranch**, **patron**, and **patronprofile**, while **catalogue** has no subpackages,
which suggests that it might be a CRUD with no complex logic inside. Please find the architecture diagram
below.

![Component diagram](docs/c4/component-diagram.png)

Yet another advantage of this approach comparing to packaging by layer for example is that in order to
deliver a functionality you would usually need to do it in one package only, which is the aforementioned
autonomy. This autonomy, then, could be transferred to the level of application as soon as we split our
_context-packages_ into separate microservices. Following this considerations, autonomy can be given away
to a product team that can take care of the whole business area end-to-end.

### Model-code gap
In our project we do our best to reduce _model-code gap_ to bare minimum. It means we try to put equal attention
to both the model and the code and keep them consistent. Below you will find some examples.

#### Placing on hold
![Placing on hold](docs/images/placing_on_hold.jpg)

Starting with the easiest part, below you will find the model classes corresponding to depicted command and events:

```java
@Value
class PlaceOnHoldCommand {
    ...
}
```
```java
@Value
class BookPlacedOnHold implements PatronEvent {
    ...
}
```
```java
@Value
class MaximumNumberOfHoldsReached implements PatronEvent {
    ...
}
```
```java
@Value
class BookHoldFailed implements PatronEvent {
    ...
}
```

We know it might not look impressive now, but if you have a look at the implementation of an aggregate,
you will see that the code reflects not only the aggregate name, but also the whole scenario of `PlaceOnHold`
command handling. Let us uncover the details:

```java
public class Patron {

    public Either<BookHoldFailed, BookPlacedOnHoldEvents> placeOnHold(AvailableBook book) {
        return placeOnHold(book, HoldDuration.openEnded());
    }

    ...
}
```

The signature of `placeOnHold` method screams, that it is possible to place a book on hold only when it
is available (more information about protecting invariants by compiler you will find in [Type system section](#type-system)).
Moreover, if you try to place available book on hold it can **either** fail (`BookHoldFailed`) or produce some events -
what events?

```java
@Value
class BookPlacedOnHoldEvents implements PatronEvent {
    @NonNull UUID eventId = UUID.randomUUID();
    @NonNull UUID patronId;
    @NonNull BookPlacedOnHold bookPlacedOnHold;
    @NonNull Option<MaximumNumberOfHoldsReached> maximumNumberOfHoldsReached;

    @Override
    public Instant getWhen() {
        return bookPlacedOnHold.when;
    }

    public static BookPlacedOnHoldEvents events(BookPlacedOnHold bookPlacedOnHold) {
        return new BookPlacedOnHoldEvents(bookPlacedOnHold.getPatronId(), bookPlacedOnHold, Option.none());
    }

    public static BookPlacedOnHoldEvents events(BookPlacedOnHold bookPlacedOnHold, MaximumNumberOfHoldsReached maximumNumberOfHoldsReached) {
        return new BookPlacedOnHoldEvents(bookPlacedOnHold.patronId, bookPlacedOnHold, Option.of(maximumNumberOfHoldsReached));
    }

    public List<DomainEvent> normalize() {
        return List.<DomainEvent>of(bookPlacedOnHold).appendAll(maximumNumberOfHoldsReached.toList());
    }
}
```

`BookPlacedOnHoldEvents` is a container for `BookPlacedOnHold` event, and - if patron has 5 book placed on hold already -
`MaximumNumberOfHoldsReached` (please mind the `Option` monad). You can see now how perfectly the code reflects
the model.

It is not everything, though. In the picture above you can also see a big rectangular yellow card with rules (policies)
that define the conditions that need to be fulfilled in order to get the given result. All those rules are implemented
as functions **either** allowing or rejecting the hold:

![Restricted book policy](docs/images/placing-on-hold-policy-restricted.png)
```java
PlacingOnHoldPolicy onlyResearcherPatronsCanHoldRestrictedBooksPolicy = (AvailableBook toHold, Patron patron, HoldDuration holdDuration) -> {
    if (toHold.isRestricted() && patron.isRegular()) {
        return left(Rejection.withReason("Regular patrons cannot hold restricted books"));
    }
    return right(new Allowance());
};
```

![Overdue checkouts policy](docs/images/placing-on-hold-policy-overdue.png)

```java
PlacingOnHoldPolicy overdueCheckoutsRejectionPolicy = (AvailableBook toHold, Patron patron, HoldDuration holdDuration) -> {
    if (patron.overdueCheckoutsAt(toHold.getLibraryBranch()) >= OverdueCheckouts.MAX_COUNT_OF_OVERDUE_RESOURCES) {
        return left(Rejection.withReason("cannot place on hold when there are overdue checkouts"));
    }
    return right(new Allowance());
};
```

![Max number of holds policy](docs/images/placing-on-hold-policy-max.png)

```java
PlacingOnHoldPolicy regularPatronMaximumNumberOfHoldsPolicy = (AvailableBook toHold, Patron patron, HoldDuration holdDuration) -> {
    if (patron.isRegular() && patron.numberOfHolds() >= PatronHolds.MAX_NUMBER_OF_HOLDS) {
        return left(Rejection.withReason("patron cannot hold more books"));
    }
    return right(new Allowance());
};
```

![Open ended hold policy](docs/images/placing-on-hold-policy-open-ended.png)

```java
PlacingOnHoldPolicy onlyResearcherPatronsCanPlaceOpenEndedHolds = (AvailableBook toHold, Patron patron, HoldDuration holdDuration) -> {
    if (patron.isRegular() && holdDuration.isOpenEnded()) {
        return left(Rejection.withReason("regular patron cannot place open ended holds"));
    }
    return right(new Allowance());
};
```

#### Spring
Spring Framework seems to be the most popular Java framework ever used. Unfortunately it is also quite common
to overuse its features in the business code. What you find in this project is that the domain packages
are fully focused on modelling business problems, and are free from any DI, which makes it easy to
unit-test it which is invaluable in terms of code reliability and maintainability. It does not mean,
though, that we do not use Spring Framework - we do. Below you will find some details:
- Each bounded context has its own independent application context. It means that we removed the runtime
coupling, which is a step towards extracting modules (and microservices). How did we do that? Let's have
a look:
    ```java
    @SpringBootConfiguration
    @EnableAutoConfiguration
    public class LibraryApplication {

        public static void main(String[] args) {
            new SpringApplicationBuilder()
                    .parent(LibraryApplication.class)
                    .child(LendingConfig.class).web(WebApplicationType.SERVLET)
                    .sibling(CatalogueConfiguration.class).web(WebApplicationType.NONE)
                    .run(args);
        }
    }
    ```
- As you could see above, we also try not to use component scan wherever possible. Instead we utilize
`@Configuration` classes where we define module specific beans in the infrastructure layer. Those
configuration classes are explicitly declared in the main application class.

### Tests
Tests are written in a BDD manner, expressing stories defined with Example Mapping.
It means we utilize both TDD and Domain Language discovered with Event Storming.

We also made an effort to show how to create a DSL, that enables to write
tests as if they were sentences taken from the domain descriptions. Please
find an example below:

```groovy
def 'should make book available when hold canceled'() {
    given:
        BookDSL bookOnHold = aCirculatingBook() with anyBookId() locatedIn anyBranch() placedOnHoldBy anyPatron()
    and:
        PatronEvent.BookHoldCanceled bookHoldCanceledEvent = the bookOnHold isCancelledBy anyPatron()

    when:
        AvailableBook availableBook = the bookOnHold reactsTo bookHoldCanceledEvent
    then:
        availableBook.bookId == bookOnHold.bookId
        availableBook.libraryBranch == bookOnHold.libraryBranchId
        availableBook.version == bookOnHold.version
}
```
_Please also note the **when** block, where we manifest the fact that books react to
cancellation event_

## How to contribute

The project is still under construction, so if you like it enough to collaborate, just let us
know or simply create a Pull Request.

## How to Build

### Requirements

* Java 11
* Maven

### Quickstart

You can run the library app by simply typing the following:

```console
$ mvn spring-boot:run
...
...
2019-04-03 15:55:39.162  INFO 18957 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2019-04-03 15:55:39.425  INFO 18957 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-04-03 15:55:39.428  INFO 18957 --- [           main] io.pillopl.library.LibraryApplication    : Started LibraryApplication in 5.999 seconds (JVM running for 23.018)

```

### Build a Jar package

You can build a jar with maven like so:

```console
$ mvn clean package
...
...
[INFO] Building jar: /home/pczarkowski/development/spring/library/target/library-0.0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
```

### Build with Docker

If you've already built the jar file you can run:

```console
docker build -t spring/library .
```

Otherwise you can build the jar file using the multistage dockerfile:

```console
docker build -t spring/library -f Dockerfile.build .
```

Either way once built you can run it like so:

```console
$ docker run -ti --rm --name spring-library -p 8080:8080 spring/library
```

### Production ready metrics and visualization
To run the application as well as Prometheus and Grafana dashboard for visualizing metrics you can run all services:

```console
$ docker-compose up
```

If everything goes well, you can access the following services at given location:
* http://localhost:8080/actuator/prometheus - published Micrometer metrics
* http://localhost:9090 - Prometheus dashboard
* http://localhost:3000 - Grafana dashboard

In order to see some metrics, you must create a dashboard. Go to `Create` -> `Import` and select attached `jvm-micrometer_rev8.json`. File has been pulled from
`https://grafana.com/grafana/dashboards/4701`.

Please note application will be run with `local` Spring profile to setup some initial data.

## References

1. [Introducing EventStorming](https://leanpub.com/introducing_eventstorming) by Alberto Brandolini
2. [Domain Modelling Made Functional](https://pragprog.com/book/swdddf/domain-modeling-made-functional) by Scott Wlaschin
3. [Software Architecture for Developers](https://softwarearchitecturefordevelopers.com) by Simon Brown
4. [Clean Architecture](https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164) by Robert C. Martin
5. [Domain-Driven Design: Tackling Complexity in the Heart of Software](https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215) by Eric Evans

repository: ddd-by-examples/library

gha_language: Java

repo_name: ddd-by-examples/library


text:
# cicd-springboot
Implementing Continuous Integration/Continuous Delivery on Spring Boot Java App

[![Build Status](https://travis-ci.org/aaron0318/cicd-springboot.svg?branch=master)](https://travis-ci.org/aaron0318/cicd-springboot)
![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/randycaidocker/cicd-springboot)


text:
[TOC]

# RandLA-Net: Efficient Semantic Segmentation of Large-Scale Point Clouds

## Abstract

- logic: research problem-->gap-->proposal and core components-->empirical experiments

- research problem: investigate on the problem of **efficient semantic seg. for lg-scale PCs**

- current issue/gap: most of the current approaches can only handle sm-scale PCs due to either the expensive sampling process or the computationally heavy pre-processing step

- proposal: a new neural architecture for semantic seg. task for lg-scale PCs which the author thinks is efficient and lightweight.

- core components: 1) the key to this approach is **random pt sampling (RS)** --> remarkably computation and memory efficient **but discard key features by chance**, 2) **local feature aggregation module** which **progressively increase the receptive field for each 3D point, thereby effectively preserving geometric details**  --> to overcome the issue of key features discarding

- empirical experiments: 1)it is super fast( more than200x faster when 1 million points in a single pass) compared, 2)gain STOA performance on two large-scale benchmarks Semantic.3D reduce8 and SemanticKITTI

## 1.Introduction

- Justification of eff. sem. seg. for lg-scale PCs: a fundamental and essential capability for realtime intelligent systems, such as autonomous driving and augmented reality

- key challenges of PCs: the raw point
clouds acquired by depth sensors are typically **irregularly sampled, unstructured and unordered**

- gap: DL can not be directly applied to PCs due to its characteristics which are quite diff. from image data.

- literature review
  - a pioneering work PointNet capable of learning point-wise features using MLPs but fails to capture wider local info for each pt.
  - To learn richer local structures, **many dedicated neural modules have been subsequently and rapidly introduced**.
  - These papers can be summarize as 4 categories: 1) neighbouring feature pooling, 2) graph message passing, 3) kernel-based convolution, and 4) attention based aggregation.
  - limitations for these papers: 1)most of them only handle/process extremely small 3D point clouds (e.g., 4k points or 1×1 meter blocks), 2)and cannot be directly extended to larger point clouds (e.g., millions of points and up to 200×200 meters) without **preprocessing steps such as block partition**
  - 3 reasons for this limitation: 1) point-sampling methods are either computationally expensive or memory inefficient, 2)feature learners rely on computationally expensive kernelisation or graph construction, 3)the existing local feature learners are either incapable of capturing complex structures, or do so inefficiently, due to their limited size of receptive fields
  - works tackling the task of lg-scale PCs: SPG,FCPN,PCT; Although they achieve decent semantic seg. results, the preprocessing and voxelization steps are too computationally heavy to be deployed in real-time applications

- aim: design a memory and computationally efficient neural architecture, which is able to directly process large-scale 3D point clouds in a single pass, without requiring any pre/post-processing steps such as voxelization, block partitioning or graph construction.

- core components: random sampling (RS) and local feature aggregation (LFA)
  - RS; a key enabler for deep neural networks to efficiently process large-scale point clouds but **can discard key information, especially for objects with sparse points.**
  - LFA; To counter the potentially detrimental impact of RS, LFA is proposed to **capture complex local structures over progressively smaller point-sets**. Specially, comprised of 3 units: 1)a local spatial encoding (LocSE) unit to explicitly preserve local geometric structures, 2)rather than max/avg pooling, here use attentive pooling to automatically keep the useful local features, 3)stack multiple LocSE units and attentive poolings as a dilated residual block, greatly increasing the effective receptive field for each point.

- Amazing performance of this net: 1) up to 200× faster on lg-scale PCs, 2)surpasses the STOA sem. seg. methods on both Semantic3D and SemanticKITTI benchmarks.

- contrib: 1)analyze and compare existing sampling methods and then identify random sampling as the suitable method for lg-scale PCs, 2)a newly feature aggregation module which is capable of **learning/capturing/preserving complex local context/structures** by progressively increasing the receptive field for each pt,3) STOA performance on two lg-scale benchmarks while also it is significant memory and computation saving.

## 2.Related work

- Projection and Voxel Based Networks.
- Point Based Networks
- Learning for Large-scale Point Clouds

## 3.RandLA-Net
### overview

- down-sampling issue; Faced with lg-scale PCs spanning up to hundreds of meters, it is inevitable to down-sample PCs progressively and efficiently while preserving the useful point
features
- Basic idea of this net: use the simple and fast approach of random sampling to greatly **decrease point density**, whilst **applying a carefully designed local feature aggregator to retain prominent features**.

### sampling method comparison
- FPS
- IDIS
- RS
- GS
- CRS
- PGS

### local feature aggregation

This LFA module is applied on **each pt in parallel** and consists of 3 units: **local spatial encoding(LocSE), attentive pooling(AP), dilated residual block(DRB)**.

- LocSE;![](images/RandLA-Net/LocSE.png)
  - it explicitly *embed xyz coordinates of all nb pts such that the corresponding center point features are always aware of their relative spatial locations*. **This conforms to the intuition of sem. seg task that the semantic labels of each pt is determined by its nb pts within a range.--yc**
  - This allows to observe local geometric patterns, thus eventually to help the entire network to learn/capture the complex local structures.
  - 3 steps: 1) find nearest nb pts for each input pt using Euclidean distance KNN (later on, focus describe the steps on 1 pt), 2) relative pt position encoding `(r_i)^k` by concatenating pt's xyz, its nb pts, its Euclidean distance, and relative xyz position, then followed by a MLP, 3)point feature `F_i_hat` augmentation by concatenating relative pt pos. encoding (r_i)^k and its corresponding point features.
  ![](images/RandLA-Net/LocSE-formula.png)
  - for 2nd step, an ablation study is conducted using different pt feature setting concatenation combination. It can be shown that this combination(pt+pt nb+rel xyz+distance) is better.
  ![](images/RandLA-Net/ablation-study-relative-position-encoding.png)
  - the output of LocSE is **a set of nb features  explicitly encoding the local geometric structures for the center point** `p_i`.

- AP;![](images/RandLA-Net/attentive-pooling.png)
  - this unit is used to aggregate the nb pts(Note: previous works often use max/avg pooling, this might result in lots of info loss). Therefore, here AP is used which consists of two steps computing attention scores and weighted summation.
  ![](images/RandLA-Net/attentive-pooling-more-comments.png)
  - computing attention scores; a shared function
g() to learn a unique attention score for each feature is designed to obtain the attention scores as a soft mask to automatically selecting imp. features. g() is made up of a MLP and a softmax function.
  - weighted summation;check the above fig. for the weight summation details.
  - **AP here is quite sim. to sum pooling,but with a attention score matrix to weight.--yc**
  - An ablation study is conducted using different pooling methods including max,mean,sum pooling. note: the below fig also involve other ablation study such as remove local spatial encoding and simplify dilated residual block.
  ![](images/randla-net/ablation-study-AP.png)
  - to conclude, given the input point cloud P , for the ith point `p_i`, the LocSE and AP units learn to aggregate the geometric patterns and features of its K nearest points, and finally generate an informative feature vector `~f_i` called **an aggregated feature**.

- DRB;![](images/RandLA-Net/dilated-residual-block.png)
  - inspired by the ResNet and the effective dilated networks, the DRB is made up of **several sets of LocSE and AP unit stack** with a skip connection.
  - dilating the receptive fields; the red 3D point observes K nb points after the first LocSE/Attentive Pooling operation, and then is able to receive information from up to K2 neighbouring points i.e. its two-hop neighbourhood after the second.
  ![](images/RandLA-Net/dilated-residual-block-receptive-blocks.png)
  - how many sets of LocSE and AP stack?Theoretically, the more units we stack, the more powerful this block as its sphere of reach becomes greater and greater. However, more units would inevitably sacrifice **the overall computation efficiency**. In addition, the entire network is likely to be **over-fitted**. The paper choose 2 as the number.
  - An ablation study on the number of set of LocSE and AP stacking in the block show that 2 sets of LocSE and AP stacking is better.
  ![](images/randla-net/ablation-study-DRB-aggragation-units.png)

- summary
  - LFA is designed to **effectively preserve complex local structures via explicitly considering nb geometries and significantly increasing receptive fields**.
  - Moreover,**computationally efficient** since only MLPs in the neural structure.

### implementation

- RandLA-Net is implemented by stacking multiple LFA modules and random sampling layers. the architecture is like below fig.
![](images/RandLA-Net/achitecture.png)
- encoder-decoder structure, then 3 FC layers w. dropout to predict semantic labels for each pt.

## 4.Experiments

### Efficiency of Random Sampling
- RS is the most suitable sampling method for lg-scale PCs.
![](images/RandLA-Net/random-sampling-comparison.png)

### Efficiency of RandLA-Net
- super fast
- lg inference pts in a single forward pass.
![](images/RandLA-Net/RandLA-Net-efficiency.png)

### STOA performance on several benchmarks
- Semantic.3D
![](images/RandLA-Net/semantic3d-table.png)
![](images/RandLA-Net/semantic3d-fig.png)
![](images/RandLA-Net/semantic3d-fig2.png)

- SemanticKITTI
![](images/RandLA-Net/semantickitti-table.png)
![](images/RandLA-Net/semantickitti-fig2.png)
![](images/RandLA-Net/semantickitti-fig.png)

- S3DIS
![](images/RandLA-Net/s3dis-table.png)
![](images/RandLA-Net/s3dis-fig.png)

## 5.Conclusion

## References (important)
TODO

## my comments and summary

### my curious question on this paper before reading

Questions:
- RandLA?  Random, Local feature Aggragator
- efficient? yep, quite eff., 200x than SPG
- how lg?  semantic.3D and semantiKITTI benchmark ds
- comp w. STOA? slightly better than KPConv

### summary

### Idea

- relative pt position encoding, can we add other types of distance, e.g.: L1 distance, L2 distance?


text:
Landingi Core
=============

[![Build Status](https://travis-ci.com/landingi/core.svg?branch=master)](https://travis-ci.com/landingi/core)
[![License MIT](https://img.shields.io/apm/l/vim-mode.svg)](https://opensource.org/licenses/MIT)
![Packagist Version](https://img.shields.io/packagist/v/landingi/core)

# Requirements
* PHP >=7.4

# Purpose
`landingi/core` repository is the place for a reusable Value Objects, Clients and Interfaces commonly used in
the Landingi ecosystem.

repository: landingi/core

gha_language: PHP

repo_name: landingi/core


text:
* ECS: Elastic Container Service
	* Is a logical grouping of EC2 machines/instances
	* Is a mere configuration for an efficient use and management of your EC2 instances resources
	* Uses Docker to instantiate containers/instances/virtual machines on these (EC2) hosts
	* To add/register EC2 instances --> all you need is Amazon ECS Container Agent running on your EC2 instance/machine

	**Amazon ECS Container Agent**

	* The container agent running on each instance within an Amazon ECS cluster sends information about the instance's current running tasks and resource utilization to Amazon ECS
	* It can start and stop tasks whenever it receives a request from Amazon ECS

### What does ECS let you do?

* Launch & stop container-based applications with simple API calls
* Get state of your cluster from a centralized service
* Give access to many familiar Amazon EC2 features
* Schedule placement of containers across your cluster --> autoscaling group

### Containers and Images

* To deploy applications on Amazon ECS, your application components must be architectured to run in containers
* Container images are stored in a **registry** from which they can be downloaded and run on your cluster

### Task Definitions

* To prepare your application to run on Amazon ECS, you create a task definition:
	* Text file - in JSON format
	* Describes one or more containers (max 10) that form your application
	* Is a blueprint for your application
	* Some parameters:
		* Which launch type
		* Which ports
		* What data volumes

### Tasks and Scheduling

* **Task**:
	* is the instantiation of a task definition within a cluster

* You can specify the number of tasks to run on your cluster after creating a task definition for your application

* **Scheduler**:
	* Place tasks in your cluster
	* There are different scheduling options available - for example, you can define a **service** that runs and maintains a specified number of tasks simultaneously

* **Clusters**:
	* When you run tasks using Amazon ECS, you place them on a cluster, which is a logical grouping of resources
	* Launch type:
		* **Fargate**: Amazon ECS manages your cluster resources
		* **EC2**: you manage your group of container instances

gha_language: CSS


text:
# 0.3.0 - Architectural Change
* To ease development, we're migrating to ClojureScript as first class on Atom
* Removed `import-for-missing` command (it was not working most of the time)
* Added `add-import-for-var` (it's better designed, and it is tested)
* Added `organize-namespace` command (rewrites NS, removes unused imports, etc)

## 0.2.4 - Shadow Element
* Removed pseudo ::shadow element on CSS (thanks @barbagrigia)
* Some debugging information when loading CLJS REPL (but still locking somewhere)

## 0.2.3 - Bugfix on Windows
* Removed dependency from HOME env variable (fixes
[#19](https://github.com/mauricioszabo/clojure-plus/issues/19))
* Refresh and Refresh-all are now commands instead of files

## 0.2.2 - More helpers
* Added "interrupt" command. It'll delegate to proto but will not lock anymore our execution context
* Refresh will now clear dependency cache. This means that refresh will recover from fatal error in more cases
* Added option "invert stacktrace" - better debugging or errors
* Corrected some errors with stacktrace parsing
* Corrected mark current SEXP

## 0.2.0 - ClojureScript support
* Added configuration to start a CLJS repl inside Atom
* Added code to differentiate between Clojure and ClojureScript
* Possibility to force Clojure or ClojureScript
* More info on statusbar
* New commands:
  * evaluate-block
  * evaluate-selection
* Watches in ClojureScript
* Renamed --check-deps-- ns (problems with CLJS)

## 0.1.2 - Bugfix
* Fixed cases when the first exception was being repeated when running code multiple times

## 0.1.2 - Fix on EVRY and Simple Refresh
* Simple refresh option on settings
* Fixed simple refresh causing an exception when there's no namespace in file
* Fixed "Everything plugin" integration
* Adding option to toggle simple refresh
* Simple correction when an exception returned nil

## 0.1.1 - Simple fix
* Exceptions will not show debug info in console anymore
* Exceptions are now block decorations

## 0.1.0 - First Release
* Watch expressions added
* Eval for top block (for watch expressions to work)
* Before / After refresh commands
* Stacktraces on errors
* Goto vars with configurable directory

repository: mauricioszabo/clojure-plus

gha_language: CoffeeScript

repo_name: mauricioszabo/clojure-plus


text:
---
name: 📝 Feature request
about: 해당 Repository에 건의하고 싶은 사항 👍 (Suggest an idea for this Repository)
title: ''
labels: ''
assignees: ''

---

**Target Application or Platform**
 - Application(Project): in this repository (Optional)
 - OS: [e.g. iOS, Windows, Linux]
 - Dev Language: [e.g. Swift, Python, JS]

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.

repository: DahNyue/CodingTestPracticeDirectory

repo_name: DahNyue/CodingTestPracticeDirectory


text:
# Edge Detection - using _Dilation_

## Introduction

We're going to detect edges of an image, using combination of Dilation & Subtraction.

- First grayscale image
- Now dilate gray scaled image
- Then subtract gray scaled image from dilated one
- We've edge highlighted image

**Note :: Assumes foreground objects are in White i.e. rgb(255, 255, 255), which is to be edge detected, because we're using Dilation as our base op !!!**

## Usage

- Make sure you've downloaded `in.itzmeanjan.filterit.jar` & set it as your Java project dependency.

- Now add following code into a Java source file.

```java
import in.itzmeanjan.filterit.ImportExportImage;
import in.itzmeanjan.filterit.edgedetection.EdgeDetectionUsingDilation;

public class Main{

        public static void main(String [] args){
                System.out.println(
                    ImportExportImage.exportImage(
                        new EdgeDetectionUsingDilation().detect("shoe.jpg"), "edgeDetectionUsingDilation.jpg"));
        }

}
```

- Compile & run code

## Result

Source | Edge Highlighted
--- | ---
![dream](../examples/dream.jpg) | ![edgeDetectionUsingDilation](../examples/edgeDetectionUsingDilation.jpg)

Thanking you :)


text:
= Visual design guideline =

== Color palette ==

 * Each website must have a well defined color palette. Several websites can share the same color palette.
 * The selected palette should have a maximum of 20 colors. Start with a single color.
 * Select the colors from the X11 colors or the web-safe colors [http://en.wikipedia.org/wiki/Web_colors web colors].
 * All colour combinations MUST have brightness contrast >=125 and color contrast >=400 (Hewlett Packard colour contrast standard). You can check the color contrast between two colors using [http://www.hp.com/hpinfo/abouthp/accessibility/webaccessibility/color_tool.html Hewlett Packard's Color Contrast tool].
 * You MUST NOT use any colour combinations which will be indistinguishable by people with a form of colour-blindness [http://www.vischeck.com/vischeck/vischeckURL.php colour-blindness]
 * It is usually recommended to include a gradient of colors in the palette. Ex: aluminium colors in the Tango palette.
 * What the colors say about the site ?
 * How should visitors feel on the site ?

Ex: [http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines Tango icon theme]

Tools:
 * [http://www.degraeve.com/color-palette/ Get a color palette that matches an image]
 * [http://www.netfront.fr/Services/rgb2pantone/ RGB to Pantone conversion]
 * [http://www.goffgrafix.com/pantone-rgb-100.php Pantone to RGB conversion]
 * [http://www.pantone.com/pages/pantone/colorfinder.aspx Check a Pantone colour]
 * [http://sobac.com/sobac/tangocolors.htm Html Tango colours]

== Fonts ==

Each website must have a well defined list of fonts known as '''favorite fonts'''.

=== Fonts for images ===

When selecting fonts for jpeg, gif, svg, etc.. images:
 * You can use any font (but preferably one of the favorite fonts). Make sure that the copyright of the font is compatible with the intended use. Save to the source repository the new font, copyright, and a readme file listing the applications/websites using this font.

=== Fonts for web pages ===

 * Fonts MUST be defined in the style sheets.
 * Every font-family CSS property MUST rely on a font stack instead of a single font.
 * A typical user may be using Windows, MacOS, Linux or a mobile browser.
 * You MUST include at least one safe font in your font stack as a last resort.
 * The most safe option is to use the generic font families as defined by the CSS: sans-serif, serif, monospace, cursive and fantasy. Sans-serif is regularly specified in CSS as the default as it is more easily readable on screens.
 * Considered as web safe: arial, arial black, comic sans ms, courier, courier new, georgia, helvetica, impact, palatino, times new roman, trebuchet ms, verdana .
 * Font sizes MUST NOT be specified in units that are not resizeable in all browsers, except for print stylesheets. You SHOULD use em or % for sizing [http://pxtoem.com/ PX to EM conversion].
 * Font-size SHOULD NOT be specified using keywords (e.g x-small) as they are rendered inconsistently across browsers.

Tools:
 * [http://www.typetester.org/ Comparison of the fonts for the screen]
 * [http://media.24ways.org/2007/17/fontmatrix.html Matrix of fonts]
 * [http://dustinbrewer.com/fonts-on-the-web-and-a-list-of-web-safe-fonts/ Web safe fonts]

== Icons ==

 * Icons MUST be created, maintained, and saved using [http://en.wikipedia.org/wiki/Scalable_Vector_Graphics Scalable Vector Graphics (SVG)]. However, many applications will use the exported version in jpeg, png, gif ...of these SVG images.
 * Common Filenaming  [http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html icons naming conventions]
 * All icons MUST have an easily distinguishable silhouette.
 * All icons are lit from above, with the light source slightly to the left.
 * (1) All icons are stroked with a thin outline (1 pixel for 48×48 pixel). The color of the outline is a dark variant of the key color of the icon.
 * (2) Use highlights to create a second inner outline of the object.
 * (3) Use glossy reflection on objects that have a reflective surface in real life (plastic, glass, some metal, et cetera).

[[Image(http://tango.freedesktop.org/images/0/0e/Unify-icon-elements.png)]]

There are four major icon sizes, an icon theme must address:
 * Large: 48×48 pixels.
 * Medium: 32x32 pixels
 * Small: 22x22 pixels.
 * Extra Small: 16×16 pixels.

Tools:
 * [http://www.inkscape.org/ inkscape]
 * [http://www.brandsoftheworld.com/ directory of logos]
 * [http://icons.mysitemyway.com/ Royalty Free Icons]

== Logos ==

Properties of a good logo:
 * A customer should be able to '''describe''' it with words and to '''remember''' it easily. In other words, you have to keep it simple.
 * The logo has to be effective without color. In other words, think shape first and leave the choice of colors for the very end.
 * The logo should be scalable, and still recognizable when printed on a pen or pin badge.
 * Dimensions:
  * The logo alone should fit in a square.
  * The logo + website.com name should able to be printed on a plaque 200mm x 400 mm (ratio 2:1) - for example -
  * The logo + website.com name should able to be printed on a 4.4cm x 1.61 (ratio 2.7:1) - for example -
 * Choose only 2 or 3 colors. Keep in mind that we may have to be able to print it on white,black or transparent backgrounds. In some cases, we may want to choose a color scheme for white backgrounds and a different one for black backgrounds.

=== Notes concerning flarebyte.com logo ===

 * The logo represents a sun with a flare. The flare looks like a F.
 * The logo is still recognizable on a white,black or transparent background.

== Layout ==

 * Layout should help to create a general feeling.
 * Layout should help to increase readability.

== Usability ==

 * Things that look the same should act the same.
 * Things that look different should act different.
 * Error messages should actually mean something to the user and tell the user how to fix the problem.
 * Every action should have a reaction.
 * Everyone makes mistakes, so every mistake should be fixable. Support undo and redo. Users often choose system functions by mistake ...
 * Consistency, consistency, consistency.
 * Minimize the need for a mighty memory.
 * Keep it simple.
 * The best journey is the one with fewest steps.
 * You should always know how to find out what to do next.
 * Allow users to tailor frequent actions.
 * Aesthetic and minimalist design: Dialogues should not contain information which is irrelevant or rarely needed.
 * Help and documentation: Even though it is better if the system can be used without documentation, it may be necessary to provide help and documentation. Any such information should be easy to search, focused on the user's task, list concrete steps to be carried out, and not be too large.

== Accessibility ==

Web accessibility refers to the practice of making websites usable by people of all abilities and disabilities.

 * Text Alternatives: Provide text alternatives for any non-text content so that it can be changed into other forms people need, such as large print, braille, speech, symbols or simpler language.
 * Time-based Media: Provide alternatives for time-based media.
 * Adaptable: Create content that can be presented in different ways (for example simpler layout) without losing information or structure.
 * Distinguishable: Make it easier for users to see and hear content including separating foreground from background.
 * Keyboard Accessible: Make all functionality available from a keyboard.
 * Enough Time: Provide users enough time to read and use content.
 * Seizures: Do not design content in a way that is known to cause seizures (Web pages MUST NOT contain anything that flashes more than three times in any one second period).
 * Navigable: Provide ways to help users navigate, find content, and determine where they are.
 * Predictable: Make Web pages appear and operate in predictable ways.
 * Input Assistance: Help users avoid and correct mistakes.
 * Compatible: Maximize compatibility with current and future user agents, including assistive technologies.

[http://www.w3.org/TR/WCAG20/ Web Content Accessibility Guidelines (WCAG) 2.0]

== CSS ==

 * The presentation of any page employing CSS MUST degrade gracefully (re: Browser Support) in browsers that do not support, or provide only partial support for style sheets.
 * Any usage of CSS MUST be valid according to a published W3C recommendation:
 * The file size of attached style sheets SHOULD be kept as low as possible. For the purpose of page weight calculations, all attached style sheet files will be taken into account.
 * Inline styles SHOULD NOT be used, as it is generally preferable to define styles in an attached style sheet.
 * Colours SHOULD be specified using hex pair RGB values, such as #336699, or short Hex values, such as #369.
 * Margins, borders and padding: negative values MUST NOT be used to move content outside the visible body of the page, because this would obscure the page meaning if images were turned off (image replacement).
 * Style sheets MUST NOT be used to modify the appearance of the toolbar or global site elements.
 * You MUST validate CSS using the [http://jigsaw.w3.org/css-validator/ W3C CSS Validation Service]

== Browser Devices ==

=== General considerations ===

==== Ratio ====
Most screen displays respect a ratio close to the aesthetic [http://en.wikipedia.org/wiki/Golden_ratio Greek golden ratio]: approximately 1.618034. This golden ratio can also be approximated to 4/3 or even better to 16/9.

==== Width ====

In a curious way, the width of many screens seems to satisfy the 10x(2^n^) equation.
Examples: 320, 640, 1280.

==== Usable Display ====

The usable screen display is smaller than the physical mobile screen display because a small portion of the screen has to be used by the browser. Therefore we recommend to use the [FlarebyteDimension flarebyte width] which satisfies the (3^2^)x(2^n^) equation.
Examples:  288, 576, 1152.

=== Desktop ===

 * You MUST validate web pages using:
     * [http://validator.w3.org/ W3C Markup Validation Service]

|| Name || Resolution ||
|| Netbook || 800 ||
|| Desktop || 1024 ||
|| Panorama || 1280+ ||

Tools:
 * [http://www.anybrowser.org/campaign/abdesign.html]

=== Mobile devices ===

In fact, it's entirely possible to group many devices with similar screen widths together and to end up with five distinct device screen width groupings:

|| Name || Resolution ||
|| tiny || 84, 96, 101, 128, 130, 132 ||
|| small || 160, 176 ||
|| medium || 208, 220, 240 ||
|| large || 320, 360, 480+ ||

[[Image(http://mobiforge.com/files/screensizes.png)]]

 * You MUST validate mobile web pages using:
     * [http://validator.w3.org/mobile/ W3C mobileOK Checker]
     * [http://ready.mobi/launch.jsp?locale=en_EN mobiReady testing tool]
     * [http://www.mobileawesomeness.com/ Mobile awesomeness]

[http://www.bbc.co.uk/guidelines/futuremedia/technical/css.shtml BBC CSS guidelines]
[http://codebeautifier.com/ CSS Formatter and Optimiser]

repository: flarebyte/wonderful-bazar

repo_name: flarebyte/wonderful-bazar


text:
# TODO
* Better display for thenCompose   - show node as active with trailer perhaps?
* adjust zoom levels (set pxPerMs in graphTimeline
* Show when errors have occurred in zoom line (Like chrome timeline)
* Fix vertical scrollbar update when scrolling down
* Code locations (see completer)
* Deal with parent heritage -  Make "the node that created me "  a dep - this will fix most remeaining vertical density issues.
* Show more details of Http Requests (although security issues around headers possibly)
* Show some info about size of closures and data
* Improve display of interstitial erros

# cccRaZZyy IDEAS :
*  Link  code locations to to Github???? (fn CrAzY)
*  Use java magic to introspect serialized data  - "what is in this closure "

# DONE:

* Show delay as pending rather than active when waiting (i.e. when node is composed, replace pending node with other node )
* Show call logs for main fn :  13:1:1.144
* Correct time format
* Show active time of events
* Time line: live scrolling mode
    - Quick open new graph (i.e. checkbox - open next graph)
    - show timeline scrolling from right
    - pending nodes animated (done?)
    - pending nodes are flush against right hand boundary (could be done bu

* Time line : add guage at bottom
* Zoom Line:
   - Add window overlay
   - show errors
   - show times

* More detail:
                  - Fetch call logs to show Fn start/create times

repository: delabassee/flowui

repo_name: delabassee/flowui


text:
# OCFL Community Extension 0004: Hashed N-tuple Storage Layout

* **Extension Name:** 0004-hashed-n-tuple-storage-layout
* **Authors:** Peter Winckles
* **Minimum OCFL Version:** 1.0
* **OCFL Community Extensions Version:** 1.0
* **Obsoletes:** n/a
* **Obsoleted by:** n/a

## Overview

This storage root extension describes how to safely map OCFL object identifiers
of any length, containing any characters to OCFL object root directories with
the primary goals of ensuring portability and filesystem performance at the cost
of directory name transparency.

Using this extension, OCFL object identifiers are hashed and encoded
as lowercase hex strings. These digests are then divided into _N_
n-tuple segments, which are used to create nested paths under the OCFL
storage root.

This approach allows OCFL object identifiers of any composition to be evenly
distributed across the storage hierarchy. The maximum number of files under any
given directory is controlled by the number of characters in each n-tuple, and
the tree depth is controlled by the number of n-tuple segments each digest is
divided into. Additionally, it obviates the need to handle special characters in
OCFL object identifiers because the mapped directory names will only ever
contain the characters `0-9a-f`.

However, this comes at the cost of not being able to identify the OCFL object
identifier of an object simply by browsing the OCFL storage hierarchy. The ID of
an object may only be found within its `inventory.json`.

## Parameters

### Summary

* **Name:** `digestAlgorithm`
    * **Description:** The digest algorithm to apply on the OCFL object
      identifier; MUST be an algorithm that is allowed in the OCFL fixity block
    * **Type:** string
    * **Constraints:** Must not be empty
    * **Default:** sha256
* **Name**: `tupleSize`
    * **Description:** Indicates the segment size (in characters) to split the
      digest is split into
    * **Type:** number
    * **Constraints:** An integer between 0 and 32 inclusive
    * **Default:** 3
* **Name:** `numberOfTuples`
    * **Description:** Indicates the number of segments to use for path generation
    * **Type:** number
    * **Constraints:** An integer between 0 and 32 inclusive
    * **Default:** 3
* **Name:** `shortObjectRoot`
    * **Description:** When true, indicates that the OCFL object root directory
      name should contain the remainder of the digest not used in the n-tuple
      segments
    * **Type:** boolean
    * **Default:** false

### Details

#### digestAlgorithm

`digestAlgorithm` is defaulted to `sha256`, and it MUST either contain a digest
algorithm that's [officially supported by the OCFL
specification](https://ocfl.io/1.0/spec/#digest-algorithms) or defined in a community
extension. The specified algorithm is applied to OCFL object identifiers to
produce hex encoded digest values that are then mapped to OCFL object root
paths.

#### tupleSize

`tupleSize` determines the number of digest characters to include in
each tuple. The tuples are used as directory names. The default value
is `3`, which means that each intermediate directory in the OCFL
storage hierarchy could contain up to 4096 sub-directories. Increasing
this value increases the maximum number of sub-directories per
directory.

If `tupleSize` is set to `0`, then no tuples are created and `numberOfTuples`
MUST also equal `0`.

The product of `tupleSize` and `numberOfTuples` MUST be less than or equal to
the number of characters in the hex encoded digest.

#### numberOfTuples

`numberOfTuples` determines how many tuples to create from the digest. The
tuples are used as directory names, and each successive directory is nested
within the previous. The default value is `3`, which means that every OCFL
object root will be 4 directories removed from the OCFL storage root, 3 tuple
directories plus 1 encapsulation directory. Increasing this value increases the
depth of the OCFL storage hierarchy.

If `numberOfTuples` is set to `0`, then no tuples are created and `tupleSize`
MUST also equal `0`.

The product of `numberOfTuples` and `tupleSize` MUST be less than or equal to
the number of characters in the hex encoded digest.

#### shortObjectRoot

The directory that immediately encapsulates an OCFL object MUST either be named
using the entire digest or the remainder of the digest that was not used in a
tuple. When `shortObjectRoot` is set to `false`, the default, the entire digest
is used, and, when it's `true` only the previously unused remainder is used.

If the product of `tupleSize` and `numberOfTuples` is equal to the number of
characters in the hex encoded digest, then `shortObjectRoot` MUST be `false`.

## Procedure

The following is an outline of the steps to map an OCFL object identifier to an
OCFL object root path:

1. The OCFL object identifier, UTF-8 encoded, is hashed using the specified
   `digestAlgorithm`.
2. The digest is encoded as a lowercase hex string.
3. Starting at the beginning of the digest and working forwards, the digest is
   divided into `numberOfTuples` tuples each containing `tupleSize` characters.
4. The tuples are joined, in order, using the filesystem path separator.
5. If `shortObjectRoot` is `true`, the remaining, unused portion of the digest
   is joined on the end of this path. Otherwise, the entire digest is joined on
   the end.

## Examples

### Example 1

This example demonstrates what the OCFL storage hierarchy looks like when using
the default configuration.

#### Parameters

It is not necessary to specify any parameters to use the default configuration.
However, if you were to do so, it would look like the following:

```json
{
    "extensionName": "0004-hashed-n-tuple-storage-layout",
    "digestAlgorithm": "sha256",
    "tupleSize": 3,
    "numberOfTuples": 3,
    "shortObjectRoot": false
}
```

#### Mappings

| Object ID | Digest | Object Root Path |
| --------- | ------ | ---------------- |
| object-01 | 3c0ff4240c1e116dba14c7627f2319b58aa3d77606d0d90dfc6161608ac987d4 | `3c0/ff4/240/3c0ff4240c1e116dba14c7627f2319b58aa3d77606d0d90dfc6161608ac987d4` |
| ..hor/rib:le-$id | 487326d8c2a3c0b885e23da1469b4d6671fd4e76978924b4443e9e3c316cda6d | `487/326/d8c/487326d8c2a3c0b885e23da1469b4d6671fd4e76978924b4443e9e3c316cda6d` |

#### Storage Hierarchy

```
[storage_root]/
├── 0=ocfl_1.0
├── ocfl_layout.json
├── extensions/
│   └── 0004-hashed-n-tuple-storage-layout/
│       └── config.json
├── 3c0/
│   └── ff4/
│       └── 240/
│           └── 3c0ff4240c1e116dba14c7627f2319b58aa3d77606d0d90dfc6161608ac987d4/
│               ├── 0=ocfl_object_1.0
│               ├── inventory.json
│               ├── inventory.json.sha512
│               └── v1 [...]
└── 487/
    └── 326/
        └── d8c/
            └── 487326d8c2a3c0b885e23da1469b4d6671fd4e76978924b4443e9e3c316cda6d/
                ├── 0=ocfl_object_1.0
                ├── inventory.json
                ├── inventory.json.sha512
                └── v1 [...]
```

### Example 2

This example demonstrates the effects of modifying the default parameters to use
a different `digestAlgoirthm`, smaller `tupleSize`, and a larger
`numberOfTuples`.

#### Parameters

```json
{
    "extensionName": "0004-hashed-n-tuple-storage-layout",
    "digestAlgorithm": "md5",
    "tupleSize": 2,
    "numberOfTuples": 15,
    "shortObjectRoot": true
}
```

#### Mappings

| Object ID | Digest | Object Root Path |
| --------- | ------ | ---------------- |
| object-01 | ff75534492485eabb39f86356728884e | `ff/75/53/44/92/48/5e/ab/b3/9f/86/35/67/28/88/4e` |
| ..hor/rib:le-$id | 08319766fb6c2935dd175b94267717e0 | `08/31/97/66/fb/6c/29/35/dd/17/5b/94/26/77/17/e0` |

#### Storage Hierarchy

```
[storage_root]/
├── 0=ocfl_1.0
├── ocfl_layout.json
├── extensions/
│   └── 0004-hashed-n-tuple-storage-layout/
│       └── config.json
├── 08/
│   └── 31/
│       └── 97/
│           └── 66/
│               └── fb/
│                   └── 6c/
│                       └── 29/
│                           └── 35/
│                               └── dd/
│                                   └── 17/
│                                       └── 5b/
│                                           └── 94/
│                                               └── 26/
│                                                   └── 77/
│                                                       └── 17/
│                                                           └── e0/
│                                                               ├── 0=ocfl_object_1.0
│                                                               ├── inventory.json
│                                                               ├── inventory.json.sha512
│                                                               └── v1 [...]
└── ff/
    └── 75/
        └── 53/
            └── 44/
                └── 92/
                    └── 48/
                        └── 5e/
                            └── ab/
                                └── b3/
                                    └── 9f/
                                        └── 86/
                                            └── 35/
                                                └── 67/
                                                    └── 28/
                                                        └── 88/
                                                            └── 4e/
                                                                ├── 0=ocfl_object_1.0
                                                                ├── inventory.json
                                                                ├── inventory.json.sha512
                                                                └── v1 [...]
```

### Example 3

This example demonstrates what happens when `tupleSize` and `numberOfTuples` are
set to `0`. This is an edge case and not a recommended configuration.

#### Parameters

```json
{
    "extensionName": "0004-hashed-n-tuple-storage-layout",
    "digestAlgorithm": "sha256",
    "tupleSize": 0,
    "numberOfTuples": 0,
    "shortObjectRoot": false
}
```

#### Mappings

| Object ID | Digest | Object Root Path |
| --------- | ------ | ---------------- |
| object-01 | 3c0ff4240c1e116dba14c7627f2319b58aa3d77606d0d90dfc6161608ac987d4 | `3c0ff4240c1e116dba14c7627f2319b58aa3d77606d0d90dfc6161608ac987d4` |
| ..hor/rib:le-$id | 487326d8c2a3c0b885e23da1469b4d6671fd4e76978924b4443e9e3c316cda6d | `487326d8c2a3c0b885e23da1469b4d6671fd4e76978924b4443e9e3c316cda6d` |

#### Storage Hierarchy

```
[storage_root]/
├── 0=ocfl_1.0
├── ocfl_layout.json
├── extensions/
│   └── 0004-hashed-n-tuple-storage-layout/
│       └── config.json
├── 3c0ff4240c1e116dba14c7627f2319b58aa3d77606d0d90dfc6161608ac987d4/
│   ├── 0=ocfl_object_1.0
│   ├── inventory.json
│   ├── inventory.json.sha512
│   └── v1 [...]
└── 487326d8c2a3c0b885e23da1469b4d6671fd4e76978924b4443e9e3c316cda6d/
    ├── 0=ocfl_object_1.0
    ├── inventory.json
    ├── inventory.json.sha512
    └── v1 [...]
```

repository: awoods/ocfl-java

branch_name: refs/heads/main

repo_name: awoods/ocfl-java


text:
---
author: yitaek
comments: true
date: 2015-05-31 02:59:42+00:00
layout: post
link: https://yitaek.wordpress.com/til196/china/hangzhou/
slug: hangzhou
title: Hangzhou
wordpress_id: 472
category: travel
---

Three days should be enough to see all of the city's touristy spots. Almost everything revolves around West Lake.

**West Lake**

West Lake reminded me of the Kirkland waterfront. The lake itself isn't particularly clean and sometimes the fog/smog covers the view, but overall was a pleasant sight. I recommend renting a bike and going around the entire lake. Bikes aren't allowed on the walkways right next to the lake, but there are plenty of sights to see along the bike roads. I never got to take a boat ride or go to the islands at the middle of the lake, but assume it would be worth the time.

[![hangzhou](https://yitaek.files.wordpress.com/2015/05/hangzhou.jpg?w=300)](https://yitaek.files.wordpress.com/2015/05/hangzhou.jpg)

**Leifeng Tower**

It costs 40 RMB to enter, but it's worth the money. I was initially excited because a friend told us there was a legend about a monkey or a white princess that is storied with the pagoda. It turns out the story is a love story about a man and a white snake who took on human form. Anyways, you can take the elevator up to the top floor, where you have the best view of West Lake, overlooking all the boats and bridges.

**Lingyin Temple**

By far my favorite place in Hangzhou. It was pouring rain when I visited, but in a way it made the underground caves/temples more impressive. I'm not sure what the story is behind the place, but there are tons of carved buddha sculptures in the caves. The most prominent one Fei Lai Feng is fenced off, but you can walk around towards the top by crossing one of the trees and come down the back way to see it.

[![hangzhou temple](https://yitaek.files.wordpress.com/2015/05/hangzhou-temple.jpg?w=300)](https://yitaek.files.wordpress.com/2015/05/hangzhou-temple.jpg)

**Xixi Wetland Park**

I'm not sure what makes this place a wetland park. It's literally a wetland...with water and no animal life. Everything is under construction still. I guess you can take a boat ride, but you can walk around and find more of the same thing everywhere. It's not worth the money to go there unless you've never seen a wetland before.

**Jiuxi 18 Stream**

We were led to this place by a local grandma who vowed to take us to a place with tea and waterfalls. To enter the nature walk area by the stream, you must pass through a huge tea town. I'm not sure what the tea was called but it had a light, clean taste. The walk to the various temples and the towers are surrounded by tea plantations. The maps were bit confusing so it took us a while to find the waterfall (I think it was called nine river creek or something).

[![hangzhou](https://yitaek.files.wordpress.com/2015/05/hangzhou1.jpg?w=300)](https://yitaek.files.wordpress.com/2015/05/hangzhou1.jpg)

**Hefang Street**

It's by Zhongshan Road and there is plenty of street food if you go at night. I wasn't brave enough to try stinky tofu, but there were lots of people buying all sorts of Chinese food. It's fun to walk around, checking out all the little shops, and watching old Chinese people exercising/dancing together in the parks.

extension: markdown

gha_language: HTML