├── 00-frontpage.md
├── 01-abstract.md
├── 02-contents.md
├── 03-introduction.md
├── 04-protocol-overview.md
├── 05-distributed-programs-as-ambients.md
├── 06-compilation-model.md
├── 07-execution-model.md
├── 08-applications.md
├── 09-future-work.md
├── 10-conclusion.md
├── 11-references.md
├── LICENSE
├── README-references.md
├── README.md
├── ambients.pdf
├── ambients.rdf
└── tools
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
└── src
├── concat.js
├── get-files.js
├── html
├── footer.html
├── header.html
└── style.css
└── md-to-html.js
/00-frontpage.md:
--------------------------------------------------------------------------------
1 |
Ambients
2 | Peer-to-Peer Programs and Data
3 |
4 | Haja Networks
5 | {{VERSION}}
6 |
--------------------------------------------------------------------------------
/01-abstract.md:
--------------------------------------------------------------------------------
1 | Abstract
2 |
3 |
4 | The decentralized web has shown great promise for highly available, massively distributed, open, censorship-free, privacy-preserving and non-exclusive application ecosystems. The technology landscape is, however, becoming fragmented due to a lack of collaboration and safe interoperability between platforms. This fragmentation exacerbates the uncertainty, risk and cost of decentralized application development and deployment. Furthermore, competing decentralized technology projects promote application programming models that are logically centralized, removing incentives for pursuing a fully decentralized web.
5 |
6 | To counter this problem, we introduce the Ambients protocol to create and verifiably execute distributed programs in decentralized, peer-to-peer networks. The main contribution of the Ambients protocol is a process-algebraic specification of its purely functional, safe and composable programming model. Combined with a content-addressed and location-agnostic execution model, what we present is a novel protocol for distributed computation.
7 |
8 | A deterministic evaluation of Ambients programs is guaranteed by a novel, strongly confluent, distributed rewrite system based on ambient calculus. Deterministic verification of the rewrite system, and its integrity and authenticity, are guaranteed by recording the execution and control flow of programs as Merkle-DAG-based, partially ordered, immutable event logs. Because of these guarantees, the Ambients protocol enables building and composing truly decentralized applications, databases and services, making safe interoperability and collaboration feasible within existing networks and platforms.
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/02-contents.md:
--------------------------------------------------------------------------------
1 | Contents
2 |
3 |
4 |
5 | 1. [Introduction](#introduction)
6 | 1. [Background](#background)
7 | 2. [A Glimpse of Hope](#a-glimpse-of-hope)
8 | 3. [Motivations](#motivations)
9 | 2. [Protocol Overview](#protocol-overview)
10 | 1. [Ambients Protocol Summary](#ambients-protocol-summary)
11 | 2. [Properties of the Ambients Protocol](#properties-of-the-ambients-protocol)
12 | 3. [Distributed Programs as Ambients](#distributed-programs-as-ambients)
13 | 1. [Programming Model](#programming-model)
14 | 1. [Process Algebra](#process-algebra)
15 | 2. [Ambient Calculus](#ambient-calculus)
16 | 3. [Ambient Calculus Syntax](#ambient-calculus-syntax)
17 | 4. [Ambient - The Computation Container](#ambient---the-computation-container)
18 | 5. [Ambient Capabilities](#ambient-capabilities)
19 | 2. [Protocol Primitives](#protocol-primitives)
20 | 1. [Values](#values)
21 | 2. [Computation Primitives](#computation-primitives)
22 | 1. [Computation Context: func](#computation-context-func)
23 | 2. [Computation Parameter: arg](#computation-parameter-arg)
24 | 3. [Function Expressions With func and arg](#function-expressions-with-func-and-arg)
25 | 3. [Distribution Primitives](#distribution-primitives)
26 | 1. [Request Computation: call](#request-computation-call)
27 | 2. [Return Computation: return](#return-computation-return)
28 | 4. [Evaluation Strategies](#evaluation-strategies)
29 | 3. [Computation Abstractions](#computation-abstractions)
30 | 1. [Types](#types)
31 | 2. [Monoids](#monoids)
32 | 3. [Functors](#functors)
33 | 4. [Compilation Model](#compilation-model)
34 | 1. [Translating Ambients Programs](#translating-ambients-programs)
35 | 2. [Program Bytecode](#program-bytecode)
36 | 3. [The Bytecode Format](#the-bytecode-format)
37 | 1. [Opcodes](#opcodes)
38 | 2. [Targets](#targets)
39 | 3. [Instruction Order](#instruction-order)
40 | 5. [Execution Model](#execution-model)
41 | 1. [Ambients as Logs](#ambients-as-logs)
42 | 1. [Partial Order](#partial-order)
43 | 2. [Integrity](#integrity)
44 | 3. [Verifiability](#verifiability)
45 | 2. [Logs](#logs)
46 | 3. [Events](#events)
47 | 1. [Event Data Structure](#event-data-structure)
48 | 2. [Creating Ambients](#creating-ambients)
49 | 3. [Defining Programs](#defining-programs)
50 | 4. [Duality of Capabilities and Co-capabilities](#duality-of-capabilities-and-co-capabilities)
51 | 5. [Transferring Control](#transferring-control)
52 | 6. [Evaluating Result](#evaluating-results)
53 | 4. [Identities and Addresses](#identities-and-addresses)
54 | 5. [Runtime Environment](#runtime-environment)
55 | 1. [The Virtual Machine](#the-virtual-machine)
56 | 2. [Discovery](#discovery)
57 | 3. [State Machine](#state-machine)
58 | 4. [Primitive Data Types](#primitive-data-types)
59 | 5. [System Interface](#system-interface)
60 | 6. [Applications](#applications)
61 | 1. [Data Structures](#data-structures)
62 | 2. [Databases](#databases)
63 | 3. [Protocols](#protocols)
64 | 4. [Decentralized Applications](#decentralized-applications)
65 | 5. [Digital Services](#digital-services)
66 | 7. [Future Work](#future-work)
67 | 1. [Research](#research)
68 | 2. [Development](#development)
69 | 8. [Conclusion](#conclusion)
70 | 9. [References](#references)
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/03-introduction.md:
--------------------------------------------------------------------------------
1 | # I. Introduction {introduction}
2 |
3 | > *"I imagined the web as an open platform that would allow everyone, everywhere to share information, access opportunities and collaborate across geographic and cultural boundaries."* *[Tim Berners-Lee](https://webfoundation.org/2017/03/web-turns-28-letter/) [[59](#906cbf)]*
4 |
5 | ## Background
6 |
7 | The [web started](https://zeltser.com/web-history/#Origins_WWW) [[18](#ac6eff)] as a way to share research and communicate between independent entities. Over time, as value was created and unlocked, the implementation of the web took a [direction that favored centralization](https://hackernoon.com/the-evolution-of-the-internet-from-decentralized-to-centralized-3e2fa65898f5) [[56](#6ceff0)] in favor of efficiency over resilience, profit and control of markets over digital liberty. Walls have been built everywhere to keep users in, digital boundaries are hard to cross, access to opportunities is limited, a [few control](https://www.hrw.org/reports/2006/china0806/5.htm) [[48](#5772d5)] [what information we can share](https://en.wikipedia.org/wiki/Criticism_of_Facebook#Censorship) and how, and how we [find information in the first place](https://en.wikipedia.org/wiki/Censorship_by_Google); and the online individual is easily tracked and [compromised](https://informationisbeautiful.net/visualizations/worlds-biggest-data-breaches-hacks/) [[68](#ebc930)]. The current web is in trouble.
8 |
9 | > *"Catalini and Gans defined "the cost of networking" as a problem associated with the increasing market power of the FANG group. Reduction of that cost will lead to disentanglement of the network effect benefits from market power."* *[The Blockchain Effect](https://medium.com/mit-cryptoeconomics-lab/the-blockchain-effect-86bd01006ec2) [[55](#ef5455)], [Catalini & Gans](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2874598) [[53](#1e2308)]*
10 |
11 | Market power on the web is centralized to a handful of corporations and their platforms. This has been achieved through creating a platform and a data moat, in which the users and their data are aggregated in a single, massive database. The data is accessible to the users and developers only through a proprietary application UI, but the data is owned and controlled by the platform. Capturing the individual user, attracting their contacts and limiting competitive external developer access, so that the users can't transact outside the system, creates substantial network effects - a powerful incentive for centralization.
12 |
13 | This consolidated market power has lead to a situation where it's [hard for new businesses to compete](https://medium.com/s/story/why-decentralization-matters-5e3f79f7638e) [[66](#8aa0ab)] with the incumbent platforms. New businesses can't access users or their data outside the major platforms and very few can contend with the amount of resources they have. As well, new businesses can only get access to users and data by going through the incumbents, which further establishes the platforms' control over a) their users b) who can access those users and c) what the rules for access are.
14 |
15 | This is a massive risk to entrepreneurial businesses as the rules can change at any point. This in turn reduces the number of new entrants, [innovation](https://arxiv.org/pdf/1812.03651.pdf) [[52](#c329bb)] and competition. The major platforms don't have pricing or service quality pressure and they [charge higher prices](https://www.theregister.co.uk/2017/11/06/coreos_kubernetes_v_world/) [[31](#4e92d2)] for lower quality services. Any new business submitting to a platform can be shut down without a notice. For the end user, this ultimately means that there are less options to choose from and they're locked in. Centralization on the web has lead to data and market monopolization, with all of the ills that it creates for the market itself.
16 |
17 | At the same time, the vast amount of data has become a liability - data gets stolen or otherwise compromised every so often. For good reason, the regulatory bodies are increasing their demands on the major platforms to take care of users' privacy. However, at other times, the regulatory bodies want and get access to the platform and their users' data. This makes the centralized platforms a lucrative environment for performing mass-surveillance and an easy target for censorship.
18 |
19 | The situation is unsustainable and ultimately prevents innovation from happening, limiting the potential of the web. In order to protect users, enable a fair market, and encourage innovation and growth, a paradigm shift from centralized to decentralized models is needed.
20 |
21 | The paradigm shift is achieved by *reversing the authority*.
22 |
23 | Instead of platforms working as a gatekeeper between the user and their data and between users and other services, in reverse the users own their data and control who or which application can access it. While in the current model data is centralized around the platforms, in the decentralized model the data is "centralized" around the user.
24 |
25 | > *"In a network of autonomous systems, an agent is only concerned with assertions about its own policy; no external agent can tell it what to do, without its consent. This is the crucial difference between autonomy and centralized management."* *[Burgess](http://markburgess.org/papers/Promise_Driven_Networks.pdf) [[6](#0654a1)]*
26 |
27 | Instead of users asking the application if they can access and use it, the [applications ask](https://ruben.verborgh.org/blog/2017/12/20/paradigm-shifts-for-the-decentralized-web) [[47](#5ac866)] the user for permission to access their data. Instead of one big database for all users, there are an infinite number of small databases, many for every user and application. Instead of having a separate account in thousands of services, self-certified identities and user profiles work across all applications. Blog posts, activity feeds, friend lists are owned by the users, who decide which service and user interface they use to access and operate on them. The user can allow their data to be used by multiple applications simultaneously, making the data re-usable and interoperable between applications and networks. Keeping [local copies](https://queue.acm.org/detail.cfm?id=3025012) [[33](#ea6b04)] of small databases and operating on them [locally](https://www.inkandswitch.com/local-first.html) [[36](#962fab)] is efficient and makes the user experience feel instantaneous. Applications work in disconnected environments by default.
28 |
29 | Instead of a business requiring permission from the platforms to get access to users, they can directly communicate with the user and request access to their data. They can talk to other services through a unified common language and create new services by composing other services and data, creating emergent value and new business opportunities. An environment where businesses don't need to build and operate expensive infrastructure to acquire and keep users at high cost allows them to focus on their core offering instead of building a platform and data moat.
30 |
31 | Because the data, users, and applications are decoupled, and because everything is cryptographically verified, the developers can build and compose applications and services swiftly and fearlessly and compete on user experience, algorithms, data insights, service quality, price, ethical values, such as respect for privacy, and more. Because the rules and access to users are not dictated by the platforms, businesses can move faster to and in the market and even small players can enter, compete, and seize opportunities.
32 |
33 | This leveled playing field creates a new wave of innovation and decentralized applications, services, and business models. Ultimately, it is the end users who benefit from more diverse service and application offerings, better user experience, improved privacy, and lowered prices. The [decentralized web will be open](http://brewster.kahle.org/2015/08/11/locking-the-web-open-a-call-for-a-distributed-web-2/) [[37](#fbcce8)], free (as in freedom), creative, and fun.
34 |
35 | ## A Glimpse of Hope
36 |
37 | The rise of crypto-networks has created a new wave of interest in technologies that enable decentralization. [Bitcoin](https://bitcoin.org/) [[12](#700ac1)] and [Ethereum](https://www.ethereum.org/) [[20](#001f73)] have led the way and as a whole we've built a lot in the past few years. We've developed technologies that can be used as building blocks for decentralized systems, such as [IPFS](https://github.com/ipfs/papers/raw/master/ipfs-cap2pfs/ipfs-p2p-file-system.pdf) [[28](#8bc425)], [libp2p](https://libp2p.io) [[32](#6f8013)], and most of these new technologies, protocols, and systems are open source. A variety of new, cryptocurrency-based business models and digital governance models have been created. In a short time, systems that weren't possible to build before have been conceived, implemented, and deployed.
38 |
39 | At the core of many crypto-networks is a global ledger. The global ledger works as a "single global truth", which means that all transactions between network participants are recorded on the same global ledger. This creates a bottleneck: requiring everyone to synchronize with everyone else reduces the maximum throughput of the network as a whole. Many projects have tackled improving the overall throughput of a network, but a single stream can only flow so fast.
40 |
41 | Most ledger-based networks have a programming interface to program the network with "[smart contracts](https://en.wikipedia.org/wiki/Smart_contract)". Smart contracts are programs that run in a network by the network participants. We can create decentralized applications (dApps), make payments, run business logic, implement new protocols, and more. However, most smart contract languages and execution environments (that is the ledger they run on) [are not compatible with each other](https://eprint.iacr.org/2018/643) [[69](#8763e0)]. This means that the developers need to write their programs in a platform-specific language, effectively needing to decide up-front in which network they wish to run their programs or services. This creates fragmentation between the plethora of networks and creates an obstacle for interoperability between them. In this regard, most of the current blockchain systems create a technological silo for the developers: you have to choose which platform to bet on before even building the application, because switching platforms means rewriting the application.
42 |
43 | Furthermore, because the smart contract programs are tied to the underlying crypto-network and ledger, they preclude the possibility of freely developing on open, non-cryptocurrency based building blocks. That is, if a program is built on a specific blockchain platform, coins or tokens or payments are required, so the developers and users have to sign up with the network and acquire tokens for that network.
44 |
45 | This reminds us of the problem we have with centralized platforms, and on a more broader level doesn't seem to align with the original motivations that created the whole field.
46 |
47 | At the same time, we've become painfully aware of the realities of the centralized platforms and have started countermeasures through regulation, such as the [GDPR](https://eugdpr.org/) [[21](#18bc67)] in the European Union, or even calls to break down the platform owners.
48 |
49 | These opposing forces to centralization, especially the people and societies waking up to question the level of privacy and security the platforms offer, are a glimpse of hope. Fundamentally though, the problems still exist.
50 |
51 | ## Motivations
52 |
53 | To build and deploy infrastructure that can realize the full potential of decentralized networks, reverse the authority and [decouple data from network effects](https://medium.com/mit-cryptoeconomics-lab/the-blockchain-effect-86bd01006ec2) [[55](#ef5455)], we think the following aspects need to be addressed:
54 |
55 | - Asynchronous message passing
56 | - [Eventual consistency](https://www.allthingsdistributed.com/2008/12/eventually_consistent.html) [[23](#0f2564)]
57 | - The ability to structure large networks as smaller networks
58 | - A decoupling of computation from the platform
59 | - Usability in disconnected or disrupted environments
60 |
61 | The biggest limitation to the current blockchain networks is the requirement for a single, global source of truth, the ledger, and forcing every participant to constantly synchronize and keep the global state to transact on it. While the motivations to do so are understandable (strong consistency guarantees, crypto-economic incentives, etc.), it creates an unbearable inefficiency for the network to operate.
62 |
63 | To let infinitely diverse, offline-first applications be built on the decentralized web, the underlying protocols can not be built on a single token or network, or be dependent on them. Rather, the core protocols need to be flexible enough to build such networks on top and without requiring a payment to be able to use them. We need building blocks, not chains. The networks and protocols that require a single, global ledger are still needed and complementary to the core protocols, but the baseline needs to be as flexible, available, and efficient as possible, so that data can be decoupled from the underlying platform.
64 |
65 | The real world is asynchronous: events occur and "things happen" disconnected from each other, at "some point in time", but rarely do we observe them *exactly at the same time*. All forms of consistency and consensus are in fact eventually consistent; messages are passed between participants, according to a predefined set of rules (the protocol), and consensus is agreed upon only when the required messages have been exchanged and the steps of the protocol were executed. While the end result, the consensus, is a form of strong consistency and requires synchronization, the underlying mechanisms are asynchronous. Messages are sent and "at some point in time" they are received and acknowledged by the receivers. From this perspective, we need to consider eventual consistency as the baseline consistency level for all data and applications. Building on asynchronous message passing and eventual consistency, we can construct stronger [consistency guarantees](http://www.bailis.org/blog/linearizability-versus-serializability/) [[35](#13a108)] as needed.
66 |
67 | > *"You must give up on the idea of a single database for all your data, normalized data, and joins across services. This is a different world, one that requires a different way of thinking and the use of different designs and tools"* *[Jonas Bonér](https://info.lightbend.com/ebook-reactive-microservices-the-evolution-of-microservices-at-scale-register.html) [[49](#952882)]*
68 |
69 | With asynchronous messaging and eventual consistency, we gain the superpower of being able to program applications and networks that can withstand disconnected and disrupted service environments. The programs operate locally first, are always available, that is they work offline, and can synchronize with others when network connection is available. Being constantly connected is no longer needed. Overall, this leads to a better user experience than what we have today with web apps.
70 |
71 | Every participant interacting through a single global agreement, e.g. a blockchain, creates a bottleneck, which can only be so fast. Instead of requiring disconnected and unrelated interactions to be verified by the full network (for example Alice buying a coffee from Bob and sharing photos with Charlie) the individual programs should form sub-networks. The sub-networks can be seen as "micro-networks" per application or interaction. For example, Alice sharing photos with Charlie forms a network of two participants. Or, in a chat program, a channel with 50 users forms a network of 50 participants. Dividing large networks into sub-networks per application can be seen as "built-in sharding". Each participant in a network only stores and interacts with some parts of the network, but almost never all of them.
72 |
73 | Each crypto-network having its own execution environment and a custom programming language to program the network causes fragmentation. This fragmentation is an inefficiency that prevents network effects from forming around programs and data. The accrued value is locked in each individual network. To overcome this challenge and to unlock value, we need to decouple the program execution layer from the platform (the ledger) and realize an efficient, distributed computation model that makes it possible to run the same program in multiple, otherwise disconnected and incompatible networks.
74 |
75 | For this purpose, we present the **Ambients protocol**. Ambients is a protocol to build and run databases and programs in a peer-to-peer network. It decouples data from the underlying platform and network and creates an interoperability layer between different networks and systems. Decentralized applications can use it to build, deploy, execute, and share code and data in a compositional, verifiably safe, and scalable way.
76 |
--------------------------------------------------------------------------------
/04-protocol-overview.md:
--------------------------------------------------------------------------------
1 | # II. Protocol Overview {protocol-overview}
2 |
3 | To understand the need for the Ambients protocol, let's consider the challenges that developers currently face with prevailing programming models during the paradigm shift.
4 |
5 | The paradigm shift from platform-centric model to a decentralized one requires the decentralized applications to be equally as good or better than the ones offered by the platforms. Reversing the authority is only one of the steps. To succeed in creating better user experiences, we need to build our applications and services accordingly. The current programming models for decentralized applications and services unfortunately resemble the platforms: they use a database which is effectively centralized, often times a blockchain.
6 |
7 | With this in mind, consider that databases are a combination of a storage (the database state) and programs to access, update and query the storage (the database services). Relational databases commonly offer [SQL](https://en.wikipedia.org/wiki/SQL) as an interface to update and query the database, making SQL an interoperability layer for all programs that wish to access and manipulate the database state. Smart contract platforms work the same way: blockchains are the centralized database state and smart contracts provide the database services and an interface. In a way, all centralized platforms form around a centralized database to which the data moves into. In fact, such a database model shifts the decentralized web towards the centralized platform model.
8 |
9 | What happens when the database state is decentralized and local to its owner? The whole concept of a database is inverted: the database state no longer accumulates in one single place, but in multiple places in a network. Therefore, to have a true decentralized programming model equivalent to the traditional database-centric model, the database services (or any program) need to move to where the data is. To do so, the computation (the programs) needs to be distributed.
10 |
11 | It turns out, solving this problem means much more than just getting decentralized databases.
12 |
13 | ## Ambients protocol Summary
14 |
15 | The Ambients protocol connects decentralized applications and networks by defining a programming model for distributed programs and a peer-to-peer distribution and computation network to run and share them.
16 |
17 | Programs leveraging the Ambients protocol are turned into distributed executables that can be executed safely in the Ambients network. This lets the programs move where the data is. Sharing these distributed programs is essential for the interoperability and scalability of decentralized applications, for example when building the aforementioned decentralized, local-to-its-owner database where the programs form the distributed database services. The deployment and execution of the distributed programs is discussed in detail in the later [chapters](#execution-model).
18 |
19 | The Ambients programming model is restrictive enough to be verifiably safe. At the same time, it is expressive enough to let developers build data structures, functions, algorithms, business logic, databases, even full-fledged systems and services. Most programming languages today have an Ambients-compliant subset of features, which means that developers can build their decentralized applications and services on the Ambients protocol using a familiar programming language. The translation of a program to a distributed program using the Ambients protocol is discussed in detail in the later [chapters](#compilation-model).
20 |
21 | The Ambients protocol is designed to be platform-independent. The Ambients network can overlay and connect multiple different Ambients-compliant runtime environments, from trusted, permissioned centralized systems (like traditional web services) to trustless, permissionless decentralized systems (like blockchain platforms). The details of Ambients-compliant runtime environments are discussed in more detail in the later [chapters](#runtime-environment).
22 |
23 | The Ambients protocol is open source, and free for everyone to build on.
24 |
25 | ## Properties of the Ambients protocol
26 |
27 | Realizing that program distribution is essential for true decentralized applications, the quality and safety of the programs become an extremely important aspect. Including third-party code is a risk to the application quality and its users, both from a functional and a security perspective, because it is impossible to know how exactly this code might behave. Thorough testing is required to ensure the quality and safety, which slows down the development and increases time-to-market. Verifying the correct behavior of any arbitrary code is arguably the ["hardest problem in computer science"](https://blog.paralleluniverse.co/2016/07/23/correctness-and-complexity/) [[67](#9a5521)]. For any decentralized programming model to be successful, the distributed programs needs to be trustworthy and valuable.
28 |
29 | The Ambients protocol is based on the principle that decentralized applications building on it can trust that the distributed programs are always compositional, safe, scalable, and decentralized.
30 |
31 | The [Compositionality](https://en.wikipedia.org/wiki/Denotational_semantics#Compositionality) of distributed programs guarantees the highest levels of [interoperability](https://en.wikipedia.org/wiki/Conceptual_interoperability). Compositionality is not just about [modularity](https://blog.statebox.org/modularity-vs-compositionality-a-history-of-misunderstandings-be0150033568) [[41](#d2985a)]. It means that the properties of the parts are preserved in the composition. If compositionality holds, safe, scalable, and decentralized programs can be composed together to form a new program which is also safe, scalable, and decentralized. Proving this requires a level of rigor that only mathematical constructions are known to have. In turn, that same rigor guarantees the full understanding of program behavior. This guarantee can turn an untrusted program into a trusted program and is essential for interoperability of decentralized applications and networks.
32 |
33 | The [Safety](https://en.wikipedia.org/wiki/Software_system_safety) of distributed programs is an essential property for establishing the trust between applications. We define safety simply as a program behaving exactly as expected. Verifying this again requires mathematical rigor for modeling the expected behavior of programs and specifying the safety properties as logical formulas that can be checked during and after program evaluations. This is essential for establishing the trust between programs.
34 |
35 | The [Scalability](https://en.wikipedia.org/wiki/Scalability) of distributed programs increases the value of a decentralized network. Scalability is commonly regarded as the solution to performance issues, but it is also about ensuring that users benefit from being part of the application network. Non-scalable programs eventually become unavailable, making applications using them unavailable and denying the service from users. Scalable programs, in turn, remain available, and in the best case improve, when usage grows which increases the absolute value of the application in a decentralized network. Therefore, verifying that a distributed program scales is essential for the long-term health of a decentralized network and for the success of a decentralized programming model.
36 |
37 | Decentralization of distributed programs is not an end goal itself, but a crucial property to enable cooperation in open and permissionless networks while allowing programs to compete. Decentralization distributes the value of programs to all participants and a protocol that is decoupled from its underlying platform allows developers and users to operate on a higher abstraction level and enjoy shared "network effects", while enabling innovation to emerge. In contrast, [as previously discussed](#background), centralized networks require to compete over users and developer mindshare, which eventually converges to the situation as it is right now. To prevent this to happen, deliberate design choices need to be made, such as requiring location-agnostic content-addressing, expecting trust to be proof-based, and guaranteeing open and permissionless network participation.
38 |
39 | The Ambients protocol preserves these properties by specifying models for verifying the properties throughout the lifecycle of a distributed program. Detailed in the following chapters, we specify:
40 |
41 | 1. The [Programming Model](#protocol-primitives) for translating programs to a process-algebraic representation of distributed computation
42 | 2. The [Compilation Model](#compilation-model) for compiling programs to distributed executables
43 | 3. The [Execution Model](#execution-model) for deploying, executing, and sharing distributed executables in content-addressed, peer-to-peer networks
44 |
45 |
46 |
--------------------------------------------------------------------------------
/06-compilation-model.md:
--------------------------------------------------------------------------------
1 | # IV. Compilation Model {compilation-model}
2 |
3 | Distributed programs need to be deployed to the network to be executed. A successful deployment requires that there's a common *executable* format that every runtime environment in the network understands.
4 |
5 | In this chapter, we define the *compilation model*, the process of translating source code to an executable, distributed program. The end product of this process is an executable in [bytecode format](#the-bytecode-format), ready for [deployment](#defining-programs).
6 |
7 | ## Translating Ambients programs
8 |
9 | The Ambients protocol overall is programming language-agnostic. That means almost any programming language can be used to write distributed programs, as long as there's a [compiler](https://en.wikipedia.org/wiki/Compiler) that can process the source language and turn it into the Ambients bytecode. While most common programming languages can be used, due to the [protocol primitives](#protocol-primitives), functions and types, functional languages are especially well-suited to write distributed programs.
10 |
11 | Compilation model requires all compilers to:
12 |
13 | 1. compile original source code to an intermediate abstract syntax structure (usually as in [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree))
14 | 2. translate the intermediate structure to the [computation primitives](#computation-primitives), [distribution primitives](#distribution-primitives) and [computation abstractions](#computation-abstractions) of the Ambients protocol
15 | 3. generate the [bytecode](#program-bytecode) executable from the primitives
16 |
17 | How these requirements are met is up to the compiler implementation. The compilers are free to apply a variety of optimizations and internal logic at compile-time. Generated bytecode and the correctness of the primitive translation are validated upon execution, as described in the [Execution model](#execution-model).
18 |
19 | ## Program Bytecode
20 |
21 | It is important to ensure that programs deployed to the network keep the information hidden from the computation participants who don't need to access it. This is one of the key properties of the execution model and one of the requirements is that programs can be [sliced](#defining-programs) into their parallel sub-parts, so that only a minimal part of the program is exposed to the other participants. The compilation model, and its implementation, the compiler, satisfies this requirement by producing a [bytecode representation](#the-bytecode-format) for every unique ambient and their nested ambients as the compiler output.
22 |
23 | The program instructions, each parallel sub-part of the program (a "slice"), and their call-order, are represented as a DAG and saved to a content-addressed storage, as a Merkle-DAG, giving each program and their sub-parts a unique *hash*. Using this hash, the program can be fetched from the network and referenced by the programs. Storing the bytecode as a Merkle-DAG, we can be assured that upon fetching the program from the network, the bytecode hasn't been tampered with. By sharing the hash of the bytecode of the program, the program can be [discovered](#discovery) in the network and included in other programs as a dependency.
24 |
25 | ## The Bytecode Format
26 |
27 | As described in the previous section, the bytecode is a sequence of compact instructions to execute the program according to the [Execution model](#execution-model) discussed in later chapters.
28 |
29 | The bytecode is a binary format which defines the ambients and their movement as ["opcodes"](https://en.wikipedia.org/wiki/Opcode) that are executed on "targets". The bytecode expressions are, then, a sequence of *instructions* encoded as tuples of
30 |
31 | ```
32 | (, )
33 | ```
34 |
35 | The definitions of the individual elements are discussed in [Opcodes](#opcodes) and [Targets](#targets) and the relation between the tuples, i.e. the call order of instructions, is discussed in [Instruction Order](#instruction-order). The exact bytecode format will be later specified in the detailed protocol specification. In this paper, we sketch the high-level structures and formats.
36 |
37 | The purpose of the bytecode encoding is to:
38 | - keep the programs as compact, efficient, and distributable as possible
39 | - make the execution order unambiguous for easier verification, and capture the sequential and parallel instructions
40 |
41 | In the future, there is potential to:
42 | - Write a compiler with the protocol, i.e. verifiable compilation
43 | - Embed a compiler in the VM (JIT-like compiler)
44 |
45 | ### Opcodes
46 |
47 | The *opcodes* capture the type of the instruction to be executed. We first define a set of opcodes for the events specific to the execution model and the opcodes for the [Robust Ambient calculus terms](#ambient-capabilities), the capabilities and co-capabilities:
48 |
49 | - `0`: `create`
50 | - `1`: `deploy`
51 | - `2`: `in`
52 | - `3`: `in_`
53 | - `4`: `out`
54 | - `5`: `out_`
55 | - `6`: `open`
56 | - `7`: `open_`
57 |
58 | We then define opcodes for the [computation](#computation-primitives) and [distribution](#distribution-primitives) primitives of the protocol:
59 |
60 | - `0`: `func`
61 | - `1`: `call`
62 | - `2`: `arg`
63 | - `3`: `return`
64 |
65 | ### Targets
66 |
67 | We continue with the definition that the *target* in the `(, )` tuple is either the opcode for the primitive *or* the name of the target ambient. For the co-capability `open_`, the target is not used - instead, always use `0` as the target opcode. That is, `open_` compiles to `(7, 0)`.
68 |
69 | ### Instruction Order
70 |
71 | We finish by defining how the expected execution order of the instructions is captured in the bytecode. As each step in the program is represented by the tuple `(, )`, we construct an Execution DAG where the instruction tuples are the nodes of the DAG. Each instruction, a node in the Execution DAG, has an edge directed to the previous instruction of the program, which forms a causal order between them. As DAGs can branch and join, the Execution DAG captures both the sequential and parallel instructions.
72 |
73 | For example, the program `call[out a.in b|open_]` would be represented as four execution steps:
74 |
75 | ```
76 | ("create", "call")
77 | ("out", "a")
78 | ("in", "b")
79 | ("open_", 0)
80 | ```
81 |
82 | They would form the following Execution DAG:
83 |
84 | ```
85 | ("create", "call")
86 | |
87 | / \
88 | / \
89 | ("out", "a") ("open_", 0)
90 | |
91 | ("in", "b")
92 | ```
93 |
94 | Using the previously defined opcodes, the instructions produced by the compiler are:
95 |
96 | ```
97 | (0, 1)
98 | (4, "a")
99 | (2, "b")
100 | (7, 0)
101 | ```
102 |
103 | The first instruction `(0, 1)` can be read as *"create an ambient called `call`"*. The second instruction `(4, "a")` maps to the capability `out a` followed by the third instruction `(2, "b")` for the capability `in b`. The `open_` co-capability is captured in the fourth instruction `(7, 0)`.
104 |
105 | From the Execution DAG of the program, we can see how the DAG captures the sequential and parallel instructions, and divides the program into sub-parts:
106 |
107 | ```
108 | (0, 1)
109 | |
110 | / \
111 | / \
112 | (4, "a") (7, 0)
113 | |
114 | (2, "b")
115 | ```
116 |
--------------------------------------------------------------------------------
/07-execution-model.md:
--------------------------------------------------------------------------------
1 | # V. Execution Model {execution-model}
2 |
3 | Encoding programs as distributed computation primitives lets us reason about the behavior of the programs and the systems they're part of intuitively. To ensure that programs are behaving correctly in decentralized, trustless networks, the programs must be interpreted and executed on a computer, such as a virtual machine, that fulfills the execution requirements. The execution requirements and environment are described as the protocol *execution model*.
4 |
5 | This section describes the execution model for the protocol, by defining:
6 |
7 | - A model to encode ambients and their discrete events as a distributed logs
8 | - A finite-state machine that represents the state of an ambient
9 | - The constraints and specifications that all protocol implementations must adhere to
10 | - The verification procedures for the computations and state transitions
11 |
12 | ## Ambients as Logs
13 |
14 | The protocol defines distributed programs as ambient expressions which form a set of parallel and nested ambients and a path according to which an ambient moves. A program is executed, i.e. run, by reducing its initial ambient expression to its final state. The [execution of a program](https://en.wikipedia.org/wiki/Execution_(computing)) makes the ambient move and change its state. To capture the ambient structures and movement and to be able to verify that programs were correctly executed, we define an [execution model](https://en.wikipedia.org/wiki/Execution_model) for the protocol based on distributed logs of discrete events structured as [Merkle-DAGs](https://discuss.ipfs.io/t/what-is-a-merkle-dag/386) [[65](#68f94b)].
15 |
16 | A log consists of discrete events, which occur and are recorded during the execution of a program. Starting from an initial state the program follows the ambient reduction rules, step-by-step, to a final state. Every ambient in the system records its events to its own log and includes a signature to prove authenticity. During this process, every ambient records its own log, which includes a signature to prove authenticity. The aforementioned Merkle-DAG structure keeps the log [partially ordered](#partial-order) and preserves [cryptographic integrity](#integrity).
17 |
18 | The state of an ambient, at any point in the execution, can be calculated from the events it has recorded in its log. It is the reductions, and in turn the events, that make ambients move and change their state. To look at it the other way around, the state of an ambient is recorded as immutable events in a distributed log. This enables us to analyze a program and its state at any given time in detail, to move back and forth between the states making, for example, [time-travel debugging](https://en.wikipedia.org/wiki/Time_travel_debugging) possible.
19 |
20 | The recording of program execution as a log establishes the ambient structures, the expected instructions, that the correct instructions were executed and that the log contains only the expected events. This model enables any participant in the network to verify that the correct events were recorded by the correct participant at the correct time, and thus we can be sure that:
21 |
22 | - A program was executed correctly
23 | - A program behaved correctly
24 |
25 | The safety properties of the protocol require that any protocol implementation and its underlying log must:
26 |
27 | - [_Partially order_](#partial-order) its events
28 | - Preserve the [_integrity_](#integrity) of its events
29 | - Enable [_verification_](#verifiability) of its events
30 |
31 | A database that provides a log abstraction, and guarantees the aforementioned properties can be used as a storage system in a protocol implementation. In the peer-to-peer world, blockchains and some DAGs, such as [Merkle-CRDTs](https://hector.link/presentations/merkle-crdts/merkle-crdts.pdf) [[39](#c21b4a)], can be used as the log. For example, solutions that meet all the requirements are [OrbitDB](https://github.com/orbitdb/orbit-db) [[46](#6c9acc)] and the Ethereum [blockchain](https://www.ethereum.org/) [[20](#001f73)]. There are several implementations that use a similar log structure, such as ["Feeds"](https://ssbc.github.io/scuttlebutt-protocol-guide/#feeds) [[51](#c6b702)] in [Secure Scuttlebutt](https://www.scuttlebutt.nz/) [[50](#452eb7)], ["Threads"](https://medium.com/textileio/wip-textile-threads-whitepaper-just-kidding-6ce3a6624338) [[4](#bfb036)] in [Textile](https://textile.io/) [[54](#b386b1)] and ["Hypercore"](https://github.com/mafintosh/hypercore) [[27](#f396b4)] used by the [Dat](https://dat.foundation/) [[17](#3ec99e)] protocol. These may be directly usable for the execution model described here.
32 |
33 | The execution model doesn't set any strict requirements for exchanging messages between the network participants to communicate new events. The message exchange can be implemented through various mechanisms and is discussed in more detail in the chapter [Operating System and Networking Requirements](#the-virtual-machine).
34 |
35 | ### Partial Order
36 |
37 | The execution model requires that events in a log are at least partially ordered. [Partial order](https://en.wikipedia.org/wiki/Partially_ordered_set) means that, for some events in the log, we don't know which came first, so they are considered *concurrent*. That is, they happened at the same time and the [causal order](https://lamport.azurewebsites.net/pubs/time-clocks.pdf) [[60](#db71ae)] between them can't be determined.
38 |
39 | With partial ordering as the baseline consistency requirement, the execution model captures parallel execution of computation through concurrent events and stronger consistency guarantees can be achieved either through the log implementation or at the application level. For example, a total order can be derived from a partial order by giving a partially ordered log a [total sorting function](https://arxiv.org/pdf/1805.04263.pdf) [[45](#9e91aa)] or using a [blockchain as the underlying log](http://sites.computer.org/debull/A16mar/p39.pdf) [[24](#5a52fa)].
40 |
41 | Most importantly, partial ordering enables [eventual consistency](https://en.wikipedia.org/wiki/Eventual_consistency) which removes the need for participants to synchronize, reducing the consensus and coordination overhead to a minimum. This in turn greatly benefits the overall network throughput and significantly contributes to better scalability.
42 |
43 | ### Integrity
44 |
45 | Integrity of the computation and data is a crucial safety property in the execution model. The execution model requires all events to be *unforgeable* and *immutable* after they've been written to a log. As a corollary, all logs must guarantee their structural integrity, which means that the order of the events in a log must also be *unforgeable* and *immutable*.
46 |
47 | *Unforgeability* can be achieved by signing each event with a public signing key of the creator of the event. The signature works as a proof that it was created by the owner of the signing key. Upon receiving an event, participants verify the signature against the event data and the given public key. If the signature verifies, the participant can be sure that the event wasn't forged.
48 |
49 | *Immutability* can be achieved by structuring the events as Merkle-DAGs in a [content-addressed storage system](https://en.wikipedia.org/wiki/Content-addressable_storage). When persisted, the content-addressed storage returns a hash to the event Merkle-DAG, which is then used to reference that event. The Merkle-DAG structure guarantees that a) any change to the event data or its references would change its hash and b) upon receiving the event its contents match the given hash. Together, these two properties establish *immutability* and *unforgeability* of the events.
50 |
51 | ### Verifiability
52 |
53 | To guarantee that distributed programs are executed and behave correctly, the execution model requires that its properties are easily and reliably verifiable. The execution model is *verifiable* if integrity and the order and authenticity of events can be verified by the network participant. This means that verification of the logs and events must be fast, simple, cheap, and reproducible for expected and unexpected behavior.
54 |
55 | The main mechanism for verification is the [event data structure](#event-data-structure) and its representation as a Merkle-DAG. The event data, explained in detail in the [Event Data Structure](#event-data-structure) section, contains all the necessary information to verify its contents as well as its authenticity. The Merkle-DAG data structure, in turn, enables us to verify the order of the events and integrity of data and communications, that is, we can be sure that the data we received was the data we requested.
56 |
57 | Performing the verifications at runtime is the responsibility of the [virtual machine](#the-virtual-machine).
58 |
59 | ## Logs
60 |
61 | Logs are a [unifying abstraction](https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying) [[64](#43c4e1)] and an [indispensable tool](https://martinfowler.com/eaaDev/EventSourcing.html) [[22](#1998e6)] in designing and implementing distributed systems that collect multiple events into one logical data structure. Executing a program generates events that are linked together as a Merkle-DAG, forming a log. The events are hashed as [Merkle-trees](http://www.merkle.com/papers/Certified1979.pdf) [[3](#e90b3d)] making them cryptographically secure and giving each event an immutable content-address. Merkle-DAGs, or [Merkle-trees](https://en.wikipedia.org/wiki/Merkle_tree), are a well-known and researched data structure [widely used](https://en.wikipedia.org/wiki/Merkle_tree#Uses) especially in peer-to-peer and crypto-currency technologies.
62 |
63 | A log is created by defining a *[manifest](#identities-and-addresses)* object for the log. Each ambient and the events from their reductions are written to their own log.
64 |
65 | Every event in a log has a *log identifier*. The identifier establishes which log a particular event belongs to. An identifier is distinct for every log and is assigned by the executor of a program. A distinct log identifier ties the events of a program together with the executor and protects against forged events.
66 |
67 | Every event contains an _operation_, which specifies the ambient capability or co-capability that was "consumed" in a reduction step. For example, the events recorded by the next reduction step for a program `a[in_ b] | b[in a]` - the operations would be `in_ b` and `in a` respectively. Recording the operation in the events allows us to check the events against the expected events and to be sure that they match the expected order and protocol primitives.
68 |
69 | Every event contains one or more links or references to the previous events in the log. Events linked together form the DAG-structure: `A ← B ← C ← D`. The links between the events define the *partial order* of events, establish the *integrity* of a log and allows traversing the log backwards in order to verify all the events in the log (that is, the full program execution). An event and its order, as part of a Merkle-DAG, can't be changed without changing the hashes of all subsequent events establishes *immutability* of the event and the log. That means that events can't be inserted to the history of a log making a log tamper-proof. Due to the movement of ambients from one ambient to another, events sometimes refer to events in other logs that form the sub-parts of a program and become part of a larger DAG describing the system and its execution.
70 |
71 | Referencing the events all the way to the beginning of the execution establishes an isolated execution path. That is, the hash of the root event gives a unique id for the execution of the program and separates it from other calls to the same program. This construction is important as it solves the [interference problem](#ambient-capabilities) present in ambient calculus.
72 |
73 | Every event is cryptographically signed by the executor of the program and the public key used to sign the event is included. Signing the events establishes authenticity: any participant can verify that the event was indeed produced and recorded by the log owner. The signature is created by hashing the log id, operation, creator, payload address, and refs of the event, then signing the generated hash and adding it to the signature field of the event. Referencing the previous events form the causal order, i.e. a timestamp, and including the references in the signature protects the log from [replay attacks](https://en.wikipedia.org/wiki/Replay_attack).
74 |
75 | Parallel composition of ambients (and thus parallel execution of a program or its sub-parts) are represented as unions of Merkle-DAGs. For example, the ambient `a[b[] | c[]]` forms a DAG as a union of the two independent sub-DAGs isolated from each other. The individual DAGs can be considered as [slices of the program](#defining-programs), and subsets of the full program. This definition is important; when events are passed to other logs and participants, the receiver can only access the minimum slice of the program needed, while other parts of the program remain hidden and inaccessible to the receiver. Only the originating ambient knows all the events of the log and is able to reconstruct the full program. A receiver of an event can only reconstruct the part of the program ("slice") that the event refers to.
76 |
77 | Events produced by the [protocol primitive ambients](#protocol-primitives) (*func, arg, call, return*) are embedded in the logs of their parent ambients and they don't have their own logs. For example, events produced by executing `call` and `return` primitives are embedded in the logs of the caller and the callee. Having a separate log for each primitive would add coordination overhead between participants.
78 |
79 | At any time, a log has a single writer which makes it clear who the executor is, who has control over an ambient and to which log they should write to, clearly separating the participants and their responsibilities. Since signing an event requires the possession of a private signing key, logs can only be written *locally*. As such, on the network level, the coordination overhead stays minimal while executing a program, and participants can make progress individually. The result is extremely low latency updates, as those happen on the local devices first. Consequently, applications have a user experience that feels faster than when an application needs to make a request to a server and wait for the response. Thus, applications can work even disconnected from the network, offline.
80 |
81 | ## Events
82 |
83 | The discrete events recorded in the logs are the result of the ambient calculus reduction steps when a program is executed. They occur at some point in time, and different events are separated in time. Events of a reduction can also happen in parallel, or *concurrently*, which results in one or more ambients recording their events at the same (logical) time. Additionally, the Robust Ambients' calculus rules define that to reduce a capability, a matching co-capability is also reduced. Hereby, there are actually two events that happen at every reduction: one event for reducing the capability (e.g. `in`) and one event for reducing the matching co-capability (e.g. `in_`). The execution model defines this as the [duality of capabilities and co-capabilities](#duality-of-capabilities-and-co-capabilities).
84 |
85 | In this section, we define a set of rules, which guarantee that the computation primitives are always recorded and verified in the same deterministic order. Even though the computation primitive ambients internally can run in parallel and have no deterministic ordering, the rules of the execution model define a specific, known-in-advance order in which the computation primitives work, and are recorded, in relation to each other. This guarantee has useful consequences:
86 |
87 | - The events of a distributed program have causal ordering and the log forms a partially ordered set (where the causality is represented by DAGs)
88 | - Running a distributed program will eventually converge to a deterministic end result
89 | - The event for the end result becomes the *least upper bound* of the partially ordered set and the finished program forms a [join-semilattice](https://en.wikipedia.org/wiki/Semilattice) (for a more formal definition, the reader is advised to refer to the [Merkle-CRDTs paper](https://hector.link/presentations/merkle-crdts/merkle-crdts.pdf) [[39](#c21b4a)])
90 | - Parallel computations are isolated and do not interfere with each other
91 |
92 | ### Event Data Structure
93 |
94 | An event consists of:
95 |
96 | - An `id` that establishes which log the event belongs to
97 | - An `op` which contains the event name, as per the [bytecode format](#the-bytecode-format), and any required arguments for the event
98 | - A `public key` of the creator of the event
99 | - A `signature` to establish authenticity
100 | - A set of `references` to the previous events in the program execution
101 | - An optional `payload` containing the hash of computed value (included _if and only if_ the [program slice](#defining-programs) was fully executed)
102 |
103 | For example, an event recorded upon reducing `in a`, which hashes to `zdpuApuYgEmSfLjSXhkhtTww78Eg9Rz5wobu2BnBqPBVSksRU`, would be represented in JSON as (*complete hashes truncated for brevity*):
104 |
105 | ```
106 | {
107 | id: 'zdpuArPwAFjAJqbJYwW714H362twiSMF1TX6H5T7L...',
108 | op: 'in a',
109 | sig: '30440220264d3bab838066d856087779af511afe...',
110 | creator: {
111 | id: 'zdpuAwkLw7KAgXSEqduQQoyo9MrpkWrKDrKtBUg...',
112 | publicKey: '04c9680e7399c5d9589df2b62f32d568...',
113 | },
114 | refs: [
115 | 'zdpuAmofe9Wk44ZbvMojdYPqBZ5xdrY5b8UWZmZFop4...',
116 | 'zdpuB2UnPayCXCENwbu4bH72okXDQYfeQ8bhJk2VsPF...'
117 | ]
118 | }
119 | ```
120 |
121 | ### Creating Ambients
122 |
123 | When starting a program, a `create` event is first written to the log of the program. The `create` event contains the name of the ambient which declares the existence of an ambient. For example, an ambient `a[in b.open_]` would produce an event with an op `create a`. The internal structure of an ambient, e.g. `in b.open_`, is recorded as a `deploy` event discussed in the [Program Definition chapter](#defining-programs). Subsequently, throughout the execution of the program, when a nested ambient is created, a `create` event is recorded. A log can thus contain several `create` events that were generated by the same program.
124 |
125 | As with other events, the `create` event data structure references the previous events in the program execution, linking the nested ambients to their parent. This connection makes it possible to find the path from any event back to its parent ambient and all the way to the root ambient, the start of the program execution. The references establish the causality between the parent ambient and its nested ambients, which means the parent ambient is always created before the ambients it contains.
126 |
127 | ### Defining Programs
128 |
129 | After the existence of an ambient is declared with a `create` event, it is directly followed by a `deploy` event. The `deploy` event defines what the expected next steps of the program are. During the verification, the information in a `deploy` event is used to check against the events recorded in a log. To know if what happened was correct, we need to know what was supposed to happen. The `deploy` provides the verifier with this information, making it a core data structure that allows *verifiability* of the program behavior. It also allows the verifier to check where and when new capabilities were adopted.
130 |
131 | If an ambient contains parallel nested ambients, a concurrent `deploy` event is created for each nested ambient. For example, the ambient `a[b[open_] | c[open_]]`, would create two concurrent `deploy` events, one for `b[open_]` and one for `c[open_]`, both referring to the `create a` event of their parent ambient `a`. Subsequently, `b[open_]` and `c[open_]` would respectively first record `create b` and `create c` followed by `deploy open_` and `deploy open_` events.
132 |
133 | Separating the creation and deployment of the sub-parts of the program has two important consequences.
134 |
135 | First, it allows a program to be *[sliced](https://en.wikipedia.org/wiki/Program_slicing)* to its sub-parts which enables parallel, isolated execution of the parts of the program. *Slices* of a program can be distributed to the network to be executed by other network participants.
136 |
137 | Second, *slicing* a program prevents information leakage, that is, to not reveal information about a program which shouldn't be revealed to network participants. A participant receiving an event needs to be able to traverse all the way to the root ambient to verify its source, name and expected steps, but it should not learn about the other, parallel sub-parts of the parent program. If a program was defined using only the `create` event, the receiver would learn everything about the program: all parallel ambients of the program, what other calls were made, and to whom, and more. Separating the `deploy` event from the `create` event, provides the necessary structure to keep parts of the program hidden from the other parts. This enables network participants to execute and verify a sub-part of the program, but they can't reconstruct the full program.
138 |
139 | For example, a program that makes 100 function calls that are not dependent on each other can be distributed to 100 different network participants, each participant being oblivious of the other 99 function calls executed by the other participants.
140 |
141 | Defining a `deploy` event and separating it from the `create` event constitutes the core structure and mechanism for verifiably distributing and executing programs in a network.
142 |
143 | The program defined by the `deploy` event is referred to by its [address](#identities-and-addresses), which is included in the `deploy` event.
144 |
145 | ### Duality of Capabilities and Co-capabilities
146 |
147 | The Robust Ambients calculus' reduction rules specify that a reduction finishes only when a capability and its respective co-capability are both consumed at the same time. We call this connection the *duality of capabilities and co-capabilities*.
148 |
149 | The duality is reflected in the log events by the definition that 1) there's a direct reference between the capability and co-capability events and 2) there are no other recorded events between them.
150 |
151 | The events for co-capabilities `in` and `out` reference the matching event of the `in` and `out` capabilities. For example, executing a program `a[call[out a] | out call]` creates the event `out a` in the log of `a` followed by the matching event `out call` which refers to the previous event: `out a ← out call`. This forms the verifiable link between the request to move in or out of an ambient, the authority that the moving ambient was allowed to do so and a record that the ambient has indeed moved.
152 |
153 | The `open` and `open_` are ordered differently than `in` and `out`. The `open` capability references the matching `open_` co-capability, e.g. `open_ ← open a`. Opening an ambient gives new capabilities to its opener. For example, when the ambient `a[in b.open_]` enters ambient `b[in_ a.open a]`, ambient `b` adopts the `open_` capability from `a`. The capabilities adopted by the opening ambient can be deduced from the `deploy` events referred to by the `open` event and its previous events. Interestingly, this leads to an observation that the only event that can refer to an `open_` event is the respective `open` event.
154 |
155 | ### Transferring Control
156 |
157 | During the execution of a program, ambients can move out of their parent ambients and into other ambient. Moving into another ambient is marked by the `in` capability, and recording it in an event defines that the control of the ambient has been transferred from its parent to the ambient it enters.
158 |
159 | For example, reducing the ambient `a[in b] | b[in_ a]` generates an event with an op `in b` in the log of `a`. Given the [duality of capabilities and co-capabilities](#duality-of-capabilities-and-co-capabilities), a concurrent event `in_ a` is recorded in the log of `b`.
160 |
161 | As the control of the ambient is passed to another ambient, the `in` capability is special compared to the other capabilities: when an `in` event is recorded, the control of the ambient has been passed to the destination ambient, after which the parent ambient has no control over that ambient. The destination ambient, then, adopts the remaining capabilities of the entering ambient. For example, when the ambient `a[in b.open_]` enters ambient `b[in_ a.open a]`, ambient `b` adopts the `open_` capability from `a`. In turn, the destination ambient will record the events produced by the adopted capabilities to its own log (as opposed to writing them to the parent ambient's log, or the parent ambient continuing to write the events to its own log). This minimizes the need for synchronization between the parent and destination ambients, which means that they can continue the program execution independently and in isolation of each other. The definition of transferring the control is thus a construction that allows programs to be distributed efficiently to network participants.
162 |
163 | The control transfer sets some requirements for recording the `in` event. Because the control is transferred and the destination ambient adopts the remaining capabilities from the parent ambient, the `in` event must make sure that all capabilities and ambients of the parent are transferred. To achieve this, every `in` event references the previous events, like other events do, but in addition it references all the *"heads"* (that is, a union of events that no other event in the log points to) of the ambients and capabilities that are nested inside of the moving ambient.
164 |
165 | ### Evaluating Results
166 |
167 | When the control is transferred back to the caller, the caller's virtual machine has all the information it needs to evaluate the result of the computation.
168 |
169 | The evaluation of the result happens by inspecting the log of events the remote participant has generated, starting from the received `in` event. Because the last recorded `in` event contains a reference to all the _heads_ in the execution DAG, the caller can traverse the log all the way back to the `in` event that started the remote execution and thus determine the runtime state of the program evaluation.
170 |
171 | If all the heads in the `in` event refer to a program that has no unconsumed capabilities or co-capabilities left to consume, the VM determines that the program evaluation has entered a constant and immutable state, a final [value](#values). This value is then evaluated by the VM to its [primitive data type](#primitive-data-types). Optionally, VM can use the remotely precomputed results, accessible via content-address in event `payload`. Consider the string concatenation monoid:
172 |
173 | ```
174 | string[
175 | concat[
176 | left[string[a[]]]|
177 | right[string[b[]]]
178 | ]
179 | ]
180 | ```
181 |
182 | The value represented by the ambients, as constructed from the log, is evaluated to `"ab"` by the string implementation of the [Virtual Machine](#the-virtual-machine). This value is then returned by the [State Machine](#state-machine) upon querying the current state of the program.
183 |
184 | Upon receiving the `in` event, having verified and evaluated the resulting value, the caller records the evaluation action by writing an `open_` event to the log of the returned program. The caller then writes an `open` event, to the log of the calling program, which references the previous `open_` and the content-address of the final state as a `payload`, thereby concluding the evaluation of the result.
185 |
186 | ## Identities and Addresses
187 |
188 | Deploying a program creates a root manifest file. This file contains the program "bytecode" and the public signing key of the deployer. The manifest is then signed by the deployer to prevent forging of program deployments. The manifest file is hashed and the hash of the manifest is the identifier of the program.
189 |
190 | The identifier in turn is used to construct a *program address*. The program address consists of the protocol prefix and the identifier, separated by `/`. For example, if the manifest hashes to `zdpuAwAdomEUPx54FZVLt33ZeGZ5VrJkTgLxQiUZNBwZ3kr7e`, the address of the program can be represented as (*complete hash truncated for brevity*):
191 |
192 | ```
193 | /amb/zdpuAwAdomEUPx54FZVLt33ZeGZ5VrJkTgLxQiUZNBwZ3...
194 | ```
195 |
196 | The address establishes [location transparency](https://www.lightbend.com/ebooks/reactive-microsystems-evolution-of-microservices-scalability-oreilly) [[49](#952882)]: a single, logical address, to which messages can be sent to and which is always available, regardless of *where* the program is run. If hashes are identifiers to *immutable* content in a content-addressed system, then an identifier for a program in the Ambients protocol is an identifier to *mutable* content.
197 |
198 | This effectively means that a program in an address is like a database or service that can be queried.
199 |
200 | Sending messages and listening to this address, the network participants exchange messages about the latest events. Upon receiving events, participants apply them to their local copy of the log. To verify that an event is valid for a log, the receiver 1) fetches the manifest from the content-addressed network 2) reads the "keys" field from the manifest 3) checks that the creator's public signing key defined in the event is present in the "keys" field. If the key is found from the manifest, if the log id in the event matches the manifest hash and if the signature of the event verifies, the receiver can establish that the creator of the event is allowed to write the event to the log.
201 |
202 | The manifest contains:
203 |
204 | - `program`, which is the hash of the [program bytecode](#program-bytecode) and by which the program bytecode can be retrieved from a content-addressed storage
205 | - `name`, to describe the program
206 | - `keys`, which is an address to a list of keys that are allowed to write to the log of the program
207 | - `creator`, which identifies the creator of the program and their public signing key
208 | - `signature`, to establish authenticity of manifest
209 |
210 | For example, a manifest that hashes to `zdpuAyJe8DpoEAbs2z3djcNs2XnQBPExisJuqfpo4mygDmLXK`, would be presented in JSON as (*complete hashes truncated for brevity*):
211 | ```
212 | {
213 | program: 'zdpuAkfNT6xd5mC3Jk3ZNMGrjoqqRqSKTLjU...',
214 | name: 'hello-world',
215 | keys: '/amb/zdpuAuTSoDhKKgAfjJBRvWw4wSg5r6b3oW...',
216 | creator: {
217 | id: 'zdpuAwkLw7KAgXSEqduQQoyo9MrpkWrKDrKtBUg...',
218 | publicKey: '04c9680e7399c5d9589df2b62f32d568...'
219 | }
220 | signature: '30440220264d3bab838066d856087779af...',
221 | }
222 | ```
223 |
224 | The manifest defines the keys of the participants who are allowed to execute the program, which means they're able to write to the log of the program. The "keys" field contains an address which, when resolved, returns a list of keys. The address can be either an immutable file or an address of another ambient program that works as mutable list of keys, for example an access controller program.
225 |
226 | Each sub-part of the program creates their own manifest and attaches the address of the manifest to the `deploy` event created by that sub-part.
227 |
228 | Separating the manifests per sub-program keeps the full program information hidden. This means that knowing an address of a sub-part of the program doesn't reveal the address of the full program. Only the deployer of the program has the address of the full program. The deployer can give the address to others if they wish to share the program with them. By not giving the address to others, the program and its state or result stays hidden. Knowing the address is considered having "read access". However, to keep the program bytecode, its access control information and meta data confidential, the fields in the manifest file can also be encrypted.
229 |
230 | Defining the keys in the manifest allows the deployer to define a) who can call the deployed program, e.g. only the creator, a set of nodes or anyone, and b) when requesting a computation from the network, e.g. calling a function, who can execute that function for the deployer. This allows granular access control and lets deployer define a specific, for example a "trusted", set of participants for a program or parts of it.
231 |
232 | In addition, the manifest can be used to describe other useful information, such as encryption keys to enforce confidential computation between the participants. The granularity makes it possible to define authorization or encryption on a per-function-call level, which means that for example granting or revoking access can be done at any point in time.
233 |
234 | ## Runtime Environment
235 |
236 | Programs are executed by a [runtime environment](https://en.wikipedia.org/wiki/Runtime_system). We define the runtime environment for the protocol as a [virtual machine](https://en.wikipedia.org/wiki/Virtual_machine).
237 |
238 | ### The Virtual Machine
239 |
240 | The runtime, defined as a *virtual machine* (VM), is software that takes the program's compiled bytecode as an input, verifies that the bytecode is valid, executes the instructions defined by the program, writes the events to the log, communicates with other participants in the network and verifies events received from them, interfaces with the operating system, handles and manages keys for signing and encryption, and more.
241 |
242 | The purpose of the VM is to provide a platform-independent runtime environment to run programs in a sandboxed and isolated environment, limiting the access to the underlying operating system and hardware. It abstracts away the details of the underlying systems and hardware allowing a program to be executed the same way on any platform. For example, a VM for the protocol implemented in JavaScript can be run on Node.js or in the browsers, and a VM implemented in Rust can be run as a native program on a chosen operating system, both being able to run the same programs and communicate with each other.
243 |
244 | Network participants running programs on the virtual machines form a network. The VM is responsible for distributing the computational workload to the network participants: it can decide to run a computation locally, or only parts of it locally and to request other parts to be computed by the network. Multiple programs can be run at the same time and a single program can perform multiple computations in parallel. It is the responsibility of the VM to coordinate and [schedule](https://en.wikipedia.org/wiki/Scheduling_(computing)) the computation workloads to the appropriate resources. The VM is also responsible for communicating with the network and its participants, handling identities, signing and authenticating messages, and ultimately verifying that the protocol is followed. All VMs in the network have the responsibility to verify the remote programs upon execution and to refuse executing any invalid or incorrectly behaving programs. Incorrect behavior also includes [compilers](#translating-ambients-programs) generating invalid executables and VMs failing to carry out their responsibilities, whether due to implementation errors (i.e. bugs) or malicious intent.
245 |
246 | The VM keeps track of the program execution and encapsulates its state using [state machines](#state-machine).
247 |
248 | The VM works as an interface between the programs and the operating system. It provides APIs for the programs to access operating system level services. This includes for example, an access to storage to persist data, networking functionality to communicate with the network, and cryptographic primitives for hashing or encryption. The VM also implements primitive data types, such as *integers* or *strings*, and provides a core library for the programs to use. The required data types and interfaces are defined in [Primitive Data Types](#primitive-data-types) and [System Interface](#system-interface).
249 |
250 | The VMs are free to do optimizations internally to make the execution of programs more efficient. For example, optimizations could include pre-fetching programs or logs from the network, optimizing network topologies or using program type information for more efficient evaluation of computation results.
251 |
252 | ### Discovery
253 |
254 | In order to distribute programs and have them run by other network participants, the execution model defines that a _discovery_ mechanism is used to become aware of programs and participants willing to execute them.
255 |
256 | The discovery mechanism itself is not strictly defined by the execution model and implementations are free to use various mechanisms or protocols to perform the discovery. In general and at minimum, the discovery mechanism should communicate the [address](#identities-and-addresses) of the program or the hash of the [program bytecode](#program-bytecode), in order to establish that the correct program is verifiably executed by the remote participants.
257 |
258 | For example, a Publish-Subscribe mechanism, a marketplace that connects those wishing to distribute a program and those willing to execute it, a private network or system with existing discovery service, or even out-of-band mechanisms can all be used to connect the participants and exchange the program information.
259 |
260 | ### State Machine
261 |
262 | The virtual machine uses a [finite-state machine](https://en.wikipedia.org/wiki/Finite-state_machine) for each program. The state machines track the state of the program: where the execution of the program is at any given time, the possible next steps and the [result](#evaluating-results) of the program. In other words, the state machine represents the computed value of a program.
263 |
264 | The state machine takes a log of events as its input and outputs the current state. To do this, the state machine replays the events by starting from the first event and applying each event to the current state, updating its state on each event. Upon receiving a new event from the network, the event is passed after verification to the state machine's update function, which triggers the calculation of the new state. If all events required to change the state have been received, the state machine proceeds to the next state through a a state transition.
265 |
266 | The state machine is internal to the VM and is not exposed to the user.
267 |
268 | ### Primitive Data Types
269 |
270 | The virtual machine implements a set of common, [primitive data types](https://en.wikipedia.org/wiki/Primitive_data_type) such as strings, numerals, arrays, and more. The implementation of the primitive data types, and the functions to operate on them (e.g. *addition* or *multiplication* operations on integers) allows the VM to encode and decode between the event data and typed runtime data to efficiently evaluate and handle such types.
271 |
272 | Depending on the source language a program is written in, the primitive data types can be built-in to the source programming language or they can be exposed to the user through a library.
273 |
274 | The detailed list of primitive data types to be implemented by the virtual machines will be defined in the future. For now, we envision at least the following types to be included, and upon which to expand in the future:
275 |
276 | - Booleans
277 | - Integers
278 | - Floating-point numbers
279 | - Bytes
280 | - Characters
281 | - Strings
282 | - Tuples
283 | - Lists
284 |
285 | ### System Interface
286 |
287 | The system interface provides a unified way for programs to use operating system services across all platforms. The programs will want to persist data on disk, to be able to communicate with other participants in the network, to use cryptographic keys and functions, and more. The system interface exposes this functionality to the programs and the virtual machine manages the calls to the actual services.
288 |
289 | It is important to separate the system level calls from the application and protocol level, as it draws a clear line between what the protocol can guarantee and what it cannot: *all requests and responses to the operating system are* ***not*** *verifiable by the protocol*. That is, the user must trust their execution environment, i.e. the virtual machine and the operating system, to function correctly.
290 |
291 | The system level services, accessed through the system interface, are I/O operations. From the system perspective, they cause side effects and as the system calls can go all the way down to the hardware level, the protocol can't verify that the I/O actually happened. However, all system interface services, except the Untrusted Code Execution Interface, are required to be deterministic in a way that they return either failure or always the same result for same input.
292 |
293 | As a rule, programs using the system interface are executable by any node in the network, so all virtual machines must implement the system interface. The Untrusted Code Execution Interface is the exception to this rule, and programs using it are not expected to be run by all nodes, only by a subset of the network.
294 |
295 | Having a unified system interface for all programs allows the virtual machines, i.e. the protocol implementations, to use different components as part of their implementation. This allows different storage backends to be used and the user can choose the storage according to their needs. For example, in a trustless environment an application could choose to use a Merkle-tree-based content-addressed storage system, such as [IPFS](https://ipfs.io) [[29](#59ac11)], whereas in a trusted system, the users could opt to use a traditional database system.
296 |
297 | The exact APIs for the system interface will be specified in the detailed protocol specification. We envision the interfaces to provide access to at least the following services:
298 |
299 | **Content-addressed Storage** provides a file system and a data storage layer and can be used to store arbitrary data in various formats and persist files in directory hierarchies. The programs can fetch data, download files or list contents of a directory through the storage interface.
300 |
301 | **Peer-to-Peer Networking** provides functionality to manage connections to other participants on the system and network level. The programs can request the system to open a connection to a certain participant, to discover new participants through DHT and other discovery mechanisms, or to join a group communication channel through a Pubsub system.
302 |
303 | A **Cryptography Interface** provides secure cryptography functionality to the programs. Signing and encryption keys can be generated, signatures can be verified and data decrypted through the interface. Keys can be stored and managed through the interface. For example, a wallet for a crypto-currency, such as an Ethereum, could be used as the underlying implementation.
304 |
305 | The **Untrusted Code Execution Interface** provides a way to access untrusted or highly hardware-dependent services of the system. For example, random number generators and time APIs can be accessed through the interface. Programs that require specific binaries to be available in the operating system, or require communication with external systems, such as to make calls to smart contracts or to location-addressed systems, can use the untrusted code execution interface to access those services. However, since the interface allows access to arbitrary functionality, not all participants in a network will support all the same functionality. The support for specific services through the Untrusted Code Execution Interfaces depends on each individual participant.
306 |
307 | The relationship and the order of the layers from a program down to the operating system level can be described with the following diagram:
308 |
309 | ```
310 | +-----------------------------------------------+
311 | | Program |
312 | +-----------------------------------------------+
313 | | VM |
314 | +-----------------------------------------------+
315 | | System Interface |
316 | +-------+-------+------+------------------------+
317 | |Storage|Network|Crypto|Untrusted Code Execution|
318 | +-------+-------+------+------------------------+
319 | ```
320 |
--------------------------------------------------------------------------------
/08-applications.md:
--------------------------------------------------------------------------------
1 | # VI. Applications {applications}
2 |
3 | Fundamentally, the Ambients protocol makes it possible to share application or system state as distributable data structures. By modeling data and systems as functions, developers can easily move between different levels of abstractions. The programming and execution model that the Ambients protocol institutes has several important consequences.
4 |
5 | First, there are no more servers to interact with to query and modify the application's data. The state of the database doesn't need to be replicated in a separate application-level data model but instead, the database is directly programmable from the application. This reduces the coordination overhead and the complexity of all translation layers of classes and objects trying to keep the constantly updating database and application data model in sync. Being directly programmable also means that developers are free to use familiar language and tools, which lowers the threshold for grasping the programming model, and ultimately leads to quicker iteration times.
6 |
7 | Second, developers can create local-first applications that work offline, creating a superior user experience compared to the client-server model. For example, the user can post to their blog while offline due to the "blog program" and "posts database" being local programs on the user's device. When they publish a post, the program doesn't need to make a request to a server and instead the post is written directly to the local database. The act of publishing feels magically instantaneous. This is especially important for the decentralized web to win the hearts of mobile users.
8 |
9 | Third, all data can be seen as data structures on different levels of abstractions. At the smallest level, the developer can model and share the application state with primitive data structures, such as Sets, Lists or even an individual number (counter). Updating that data model propagates changes to all participants using the model, safely under the Ambients execution model. New data models and structures can be composed from existing models and structures to support more complex applications. By composing new data structures and sharing functions to update, filter or transform the data, we start seeing something resembling a database. When we combine multiple databases, data structures, such as user profiles or activity feeds and posts, and add business logic, we start seeing an application. Composing several data structures, databases and applications together, we have a system, a decentralized service.
10 |
11 | Fourth, because of the lock-step fashion of function calls in the Ambients protocol, we can look at the function calls as exchanging messages in request-response style. This allows us to create transactions and protocols. Participant A sends a message X to the other participants in the program and they, upon receiving the message, send an acknowledgment of X back to participant A. This constitutes a simple two-step protocol, but the same pattern can be extended to any complex set of rules and behaviors. For example, a blockchain or crypto-network protocol can be constructed by following this perspective.
12 |
13 | Finally, the ultimate benefit for the applications comes from separating the data and programs from the underlying platform. Making the program available in a network makes the computed data reusable in multiple applications, even at the same time. For example, a "GitHub" and a "Twitter" application can both update a user's profile or activity feed, or the user can share and collaborate on a playlist created in their music player with a friend using another music player. Data and programs being reusable, like code modules, means that developers and their users are free to switch platforms, service providers or data sources at any time, keeping their data as they go. Being programming language- and platform-agnostic, the Ambients programming model lets developers continue to use familiar tools and languages to build their applications, and to decide on the level of consistency, security and decentralization they want to offer to their users. With all this power, developers can stop fearing their platform choices and start focusing again on quality, user experience, security, and everything that is actually valuable to their users.
14 |
15 | ## Data Structures
16 |
17 | > *"Data structures are algorithms with memory."* *Elad Verbin*
18 |
19 | The Ambients protocol allows any data structure that can be modeled as a function to be turned into a distributed program. This makes it a very powerful tool for building components and shared data structures for distributed systems and services.
20 |
21 | Conflict-free Replicated Datatypes, [CRDTs](https://arxiv.org/pdf/1805.06358.pdf) [[14](#32b908)], have turned out to be hugely helpful data structures in implementing distributed system. In essence, they represent a shared state of a particular data structure that can automatically converge to a deterministic result across the participants. That is, all participants, having received all updates to the data structure, observe the same value.
22 |
23 | Operation-based CRDTs can be modeled as updates to the data structure, causally ordered in time. The execution model of the Ambients protocol defines the same operation-based, causality-defining structure and lends itself perfectly to implementing CRDTs. For example, adding an element to a Growth-Only Set CRDT by calling a function `gset_append("hello", prevSet)` would generate the events in the execution log that, upon reading the value, would result in a set of `["hello"]`.
24 |
25 | ## Databases
26 |
27 | Databases are specialized data structures. Most databases have a concept of an operations log, also called the ["transaction log"](https://en.wikipedia.org/wiki/Transaction_log), which records all updates to the database and from which the state of the database is computed from. The log in the execution model of Ambients is an operations log and thus directly translates to databases. Add indexing and the ability to query, and we have a database. Access to the database and data can be controlled on granular levels. The Ambients protocol and its core execution model is an operations log and as such, any kind of database or data model can be built on it.
28 |
29 | For example, database tables are data structures that can be constructed from database "operations" and upon querying the database, multiple tables are joined to return the result. In event sourcing, log databases are commonly used as the event store and the Ambients protocol provides a natural way to do distributed event sourcing and state updates. In the decentralized world, [OrbitDB](https://github.com/orbitdb/orbit-db) [[46](#6c9acc)] at its core has a distributed, peer-to-peer operations log ([ipfs-log](https://github.com/orbitdb/ipfs-log)) [[30](#beb8a0)] and its execution model is very similar to that of the Ambients protocol. Using the log abstraction, OrbitDB is able to offer multiple database models: key-value databases, document stores, counters, event logs, CRDTs and more. [3Box](https://3box.io/) [[1](#41a06b)], built on OrbitDB, provides a very specific and specialized type of database: user profiles.
30 |
31 | ## Protocols
32 |
33 | Consider a protocol where a specific sequence of specific messages are exchanged in order to reach a final agreement. At each step, preconditions are verified before progressing to the next step. Protocols can be anything from a simple two-party transaction (or payment) protocol to a complex set of rules and states such as distributed consensus protocols. For example, payment channels and state channels, business logic ("if this then that"), access controllers ("policy") or consensus protocols, can be seen as an exchange of an ordered sequence of messages and the Ambients protocol is well-suited for modeling such logic.
34 |
35 | ## Decentralized Applications
36 |
37 | If we break down the structure of many proprietary web applications and services today, we see that structurally they contain many smaller components and data structures. For example, GitHub contains organizations, users, repositories, issues, comments, etc.; Twitter contains users, tweets, a feed, private messages, etc.; a chat application has users, bots and channels; a blog has posts, comments, pages, etc.; an e-commerce site has shops, items, reviews, payments, delivery tracking, etc.
38 |
39 | By breaking down the application data and state to small databases and data structures, we can compose applications from existing parts. Since the parts are not tied to the particular applications, e.g. a user's database of tweets, other applications can build new UIs to view and modify it, or use the database as part of an aggregation service that composes data from multiple users together. Multiple programs can use the same database, at the same time, to offer different views to the data.
40 |
41 | Programs using the Ambients protocol become offline-capable out of the box because of the locality of data. This allows snappy UIs, and applications can still work when there's no internet connection (e.g. in LAN) or the connection is sporadic (e.g. mobile devices or IoT).
42 |
43 | Generally, applications that enable collaboration on the same document or data are well suited to be built on Ambients. Collaborative document editing, chat software, discussion forums, comment feeds and task lists are all exemplary programs that benefit from decentralization. Turn-based and real-time multiplayer games can verifiably track the state of a game session, player's actions and inventory, and on a higher-level, the state of the whole game world.
44 |
45 | While Ambients protocol enables data models where the users own their data, this is not always desired or needed. For example, who "owns" a public chat room? The decision of who owns the data is still something the developer needs to decide, but building programs on Ambients gives the developer the *possibility* to let users own their data, bring in their own identities, and generally respect user privacy and consent (or lack thereof).
46 |
47 | ## Digital Services
48 |
49 | Databases, identities, APIs and other services are the cornerstones of many digital services. Composing small and large pieces of data, aggregating data and running an algorithm to provide new insight to that data or providing authentication or payments services, are all valuable services in the decentralized web.
50 |
51 | Due to the compositionality of ambients, services can be composed from various parts, both decentralized and centralized, public and private, to create larger systems and networks that serve their clients' needs. For example, a web API is a service to access data, Facebook as a whole is a service that combines many smaller parts together (contacts, posts, news feed, sharing, messages, etc.), a bank service that validates that a payment was made, a private or proprietary registry that tracks and validates membership of users, or a marketplace that connects, asks, and bids.
52 |
--------------------------------------------------------------------------------
/09-future-work.md:
--------------------------------------------------------------------------------
1 | # VII. Future Work {future-work}
2 |
3 | The Ambients protocol combines efficient and practical distributed systems with safe and formal models of distributed computation, forming a novel approach for building truly decentralized systems.
4 |
5 | While the protocol outlined in this paper forms the core of the Ambients protocol, there are various additions and improvements that will be included in the protocol in the future. This section outlines planned future additions and improvements to the protocol, ongoing research and practical development work.
6 |
7 | As an open source protocol, future research and development will be performed and coordinated by the Ambients protocol community on GitHub at https://github.com/ambientsprotocol [[9](#9cecfe)].
8 |
9 | ## Research
10 |
11 | Current and future research is focused on improving the protocol capabilities to make the execution model more robust and the programming model more expressive, making emergent system designs possible.
12 |
13 | To make the programming model more expressive, there is ongoing research to include additional computation abstractions. These include [conditionals](https://en.wikipedia.org/wiki/Conditional_(computer_programming)) such as _if-else_ statements, the [_ternary_ ](https://en.wikipedia.org/wiki/Ternary_operation) operator and [pattern matching](https://en.wikipedia.org/wiki/Pattern_matching). Together, these abstractions give the end user better expressiveness to handle control flow in their programs.
14 |
15 | In order to have more powerful program and data composition primitives, we plan to add computation abstractions for [applicative functors](https://wiki.haskell.org/Applicative_functor) [[10](#e83a80)], [monads](https://wiki.haskell.org/Monad) [[42](#aff2a9)] and [profunctors](http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html) [[5](#05a56a)], and more. In addition, it would be interesting to use [_codata types_ with _copattern matching_](http://www.cse.chalmers.se/~abela/popl13.pdf) [[15](#b93294)] to represent infinitely running programs.
16 |
17 | An ambient calculus variant for the Ambients protocol is being researched, to improve the overall efficiency of the protocol. This variant defines the Ambients protocol primitives as ambient calculus primitives, making the protocol encodings simpler and more efficient for the execution environment.
18 |
19 | In the future, more research is needed to enable safe optimizations in compilers (inlining, constant folding, etc.) and to use various caching strategies and algorithms in the execution model to improve local versus remote latency. For example, it would be interesting to create a model for optimal resource utilization to maximize the overall network throughput.
20 |
21 | ## Development
22 |
23 | We envision Ambients protocol implementations being used in various environments. This means that development efforts need to focus on making sure there is wide support for underlying operating systems and platforms. Early implementation efforts are focused on covering most common operating systems and hardware architectures as well as supporting web browsers (JavaScript or WASM). In the future, we envision Ambients programs being able to be run on resource-limited devices, such as mobile and IoT devices.
24 |
25 | Future development efforts will focus on improving the architecture and features of the virtual machines. For example, we envision VMs being able to do efficient garbage collection, just-in-time compilation of Ambients programs and even to model verifiable compilation.
26 |
27 | Compiler development efforts will focus initially on providing support for some commonly used programming languages, such as JavaScript. In the future, we envision adding compiler support for a host of languages that can be used to create Ambients programs. Also, we look forward to improve the compilers by letting them connect to the VMs and participate in the verification process - to make the developer experience friendlier and safer, and to shorten the feedback loop for verifying the correctness of whole program.
28 |
29 | As the Ambients protocol gets implemented for various environments, better tools are needed to make life easier for the implementors and researchers. [AmbiCobjs](https://www-sop.inria.fr/mimosa/ambicobjs/) [[8](#e77b77)] has been a crucial tool in designing the protocol so far and we envision a modern version to be implemented that allows simulating, debugging and auditing Ambients programs and the networks they form in real-time. For example, given the nature of the step-wise recording of the execution of Ambients programs, the protocol is well-suited for time-travel debugging and simulation of the programs. Given the mobility of ambients themselves, visualizing the networks and nodes that participate and perform computation would be highly beneficial to better understand and debug the networks and programs.
30 |
--------------------------------------------------------------------------------
/10-conclusion.md:
--------------------------------------------------------------------------------
1 | # VIII. Conclusion {conclusion}
2 |
3 | We have introduced the Ambients protocol for creating and verifiably executing distributed programs in decentralized, peer-to-peer networks. The main contributions of the protocol are defined in three models: the Programming model, Compilation model and Execution model.
4 |
5 | The Ambients Programming model defines the translation of a source program to a distributed program. The Programming model guarantees that if a source program can be defined as pure and total functions and immutable values, it can be transformed to a distributed Ambients program, defined as a composition of protocol primitives. The Ambients Compilation model defines the structure of distributed program executables. The Ambients Execution model defines the control flow of Ambients program deployment and execution in a content-addressed peer-to-peer network, recorded as a Merkle-DAG based event log. The Execution model guarantees the verifiability, authenticity and integrity of the execution of all distributed Ambients programs. The guarantees of all models are enforced and enabled by modeling the deterministic evaluation of programs as a strongly confluent rewrite system based on a process algebra called ambient calculus.
6 |
7 | Building on the computational properties and the hybrid distributed evaluation strategies of Ambients, we identify an emerging breed of decentralized applications, such as data structures and databases with shared distributed state, protocols for distributed consensus and program logic, and even digital services with compositional APIs, bridging the centralized and decentralized world.
8 |
9 | We look forward to implementing the Ambients protocol as an open-source community and together pursue the vision of a fully, truly, decentralized web.
10 |
--------------------------------------------------------------------------------
/11-references.md:
--------------------------------------------------------------------------------
1 | # IX. References {references}
2 |
3 | 1. 3Box, https://3box.io/
4 | 2. Johnsen, E.B., Steffen, M., Stumpf, J.B.: A Calculus of Virtually Timed Ambients. In: James, P. and Roggenbach, M. (eds.) Recent Trends in Algebraic Development Techniques. pp. 88–103. Springer International Publishing, Cham (2017)
5 | 3. Merkle, R.C.: A Certified Digital Signature. In: Brassard, G. (ed.) Advances in Cryptology — CRYPTO’ 89 Proceedings. pp. 218–238. Springer New York, New York, NY (1990)
6 | 4. Farmer, C.: A deeper look at the tech behind Textile’s Threads, https://medium.com/textileio/wip-textile-threads-whitepaper-just-kidding-6ce3a6624338
7 | 5. A Neighborhood of Infinity: Profunctors in Haskell, http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html
8 | 6. Borril, P., Burgess, M., Craw, T., Dvorkin, M.: A Promise Theory Perspective on Data Networks. arXiv:1405.2627 [cs]. (2014)
9 | 7. Birch, M.: A Visualization for the Future of Blockchain Consensus, https://medium.com/rchain-cooperative/a-visualization-for-the-future-of-blockchain-consensus-b6710b2f50d6
10 | 8. Zimmer, P.: Ambient Programming in Icobjs, http://www-sop.inria.fr/mimosa/ambicobjs/
11 | 9. Ambients, https://github.com/ambientsprotocol
12 | 10. Applicative functor - HaskellWiki, https://wiki.haskell.org/Applicative_functor
13 | 11. Alexander, A.: Benefits of Functional Programming, https://alvinalexander.com/scala/fp-book/benefits-of-functional-programming
14 | 12. Bitcoin, https://bitcoin.org/en/
15 | 13. Bugliesi, M., Castagna, G., Crafa, S.: Boxed Ambients. In: Theoretical Aspects of Computer Software. pp. 38–63. Springer Berlin Heidelberg, Berlin, Heidelberg (2001)
16 | 14. Preguiça, N., Baquero, C., Shapiro, M.: Conflict-free Replicated Data Types (CRDTs). arXiv:1805.06358 [cs]. (2018). doi:10.1007/978-3-319-63962-8\_185-1
17 | 15. Abel, A., Pientka, B., Thibodeau, D., Setzer, A.: Copatterns: programming infinite structures by observations. In: Proceedings of the 40th annual ACM SIGPLAN-SIGACT symposium on Principles of programming languages - POPL ’13. p. 27. ACM Press, Rome, Italy (2013)
18 | 16. Correct-by-construction Casper Wiki, https://github.com/ethereum/cbc-casper/wiki
19 | 17. Dat Foundation, https://dat.foundation/
20 | 18. Zeltser, L.: Early History of the World-Wide Web: Origins and Beyond, https://zeltser.com/web-history/#Origins_WWW
21 | 19. Gonzalez, G.: Equational reasoning, http://www.haskellforall.com/2013/12/equational-reasoning.html
22 | 20. Ethereum, https://ethereum.org
23 | 21. EUGDPR – Information Portal, https://eugdpr.org/
24 | 22. Fowler, M.: Event Sourcing, https://martinfowler.com/eaaDev/EventSourcing.html
25 | 23. Vogel, W.: Eventually Consistent - Revisited, https://www.allthingsdistributed.com/2008/12/eventually_consistent.html
26 | 24. Vukolic, M.: Eventually Returning to Strong Consistency. IEEE Data Eng. Bull. 39, 39–44 (2016)
27 | 25. Functor - HaskellWiki, https://wiki.haskell.org/Functor#Functor_Laws
28 | 26. Git, https://git-scm.com/
29 | 27. Buus, M.: Hypercore is a secure, distributed append-only log., https://github.com/mafintosh/hypercore
30 | 28. Benet, J.: IPFS - Content Addressed, Versioned, P2P File System. arXiv:1407.3561 [cs]. (2014)
31 | 29. Protocol Labs: IPFS is the Distributed Web, https://ipfs.io/
32 | 30. ipfs-log - Append-only log CRDT on IPFS, https://github.com/orbitdb/ipfs-log
33 | 31. Claburn, T.: “Lambda and serverless is one of the worst forms of proprietary lock-in we’ve ever seen in the history of humanity,” https://www.theregister.co.uk/2017/11/06/coreos_kubernetes_v_world/
34 | 32. Protocol Labs: libp2p - A modular network stack, https://libp2p.io/
35 | 33. Helland, P.: Life Beyond Distributed Transactions - ACM Queue, https://queue.acm.org/detail.cfm?id=3025012
36 | 34. Bernardy, J.-P., Spiwack, A.: Linear types make performance more predictable, https://www.tweag.io/posts/2017-03-13-linear-types.html
37 | 35. Bailis, P.: Linearizability versus Serializability, http://www.bailis.org/blog/linearizability-versus-serializability/
38 | 36. Kleppmann, M., Wiggins, A., van Hardenberg, P., McGranaghan, M.: Local-first software: You own your data, in spite of the cloud, https://www.inkandswitch.com/local-first.html
39 | 37. Kahle, B.: Locking the Web Open: A Call for a Decentralized Web, http://brewster.kahle.org/2015/08/11/locking-the-web-open-a-call-for-a-distributed-web-2/
40 | 38. Guan, X., Yang, Y., You, J.: Making Ambients More Robust. (2002)
41 | 39. Sanjuan, H., Pöyhtäri, S., Teixeira, P.: Merkle-CRDTs, https://hector.link/presentations/merkle-crdts/merkle-crdts.pdf, (2019)
42 | 40. Cardelli, L., Gordon, A.D.: Mobile Ambients. In: Proceedings of the First International Conference on Foundations of Software Science and Computation Structure. pp. 140–155. Springer-Verlag, London, UK, UK (1998)
43 | 41. Genovese, F.R.: Modularity vs Compositionality: A History of Misunderstandings, https://blog.statebox.org/modularity-vs-compositionality-a-history-of-misunderstandings-be0150033568
44 | 42. Monad - HaskellWiki, https://wiki.haskell.org/Monad
45 | 43. Phillips, I., Vigliotti, M.G.: On Reduction Semantics for the Push and Pull Ambient Calculus. In: Baeza-Yates, R., Montanari, U., and Santoro, N. (eds.) Foundations of Information Technology in the Era of Network and Mobile Computing. pp. 550–562. Springer US, Boston, MA (2002)
46 | 44. Peters, K., Nestmann, U.: On the Distributability of Mobile Ambients. arXiv:1808.01599 [cs]. (2018)
47 | 45. Kleppmann, M., Gomes, V.B.F., Mulligan, D.P., Beresford, A.R.: OpSets: Sequential Specifications for Replicated Datatypes (Extended Version). arXiv:1805.04263 [cs]. (2018)
48 | 46. OrbitDB, https://github.com/orbitdb
49 | 47. Verborgh, R.: Paradigm shifts for the decentralized Web, https://ruben.verborgh.org/blog/2017/12/20/paradigm-shifts-for-the-decentralized-web/
50 | 48. Human Rights Watch: “Race to the Bottom”: Corporate Complicity in Chinese Internet Censorship, https://www.hrw.org/reports/2006/china0806/5.htm
51 | 49. Bonér, J.: Reactive Microsystems: The Evolution of Microservices at Scale. O’Reilly Media, Inc (2017)
52 | 50. Scuttlebutt - a decent(ralised) secure gossip platform, https://www.scuttlebutt.nz/
53 | 51. Scuttlebutt Protocol Guide, https://ssbc.github.io/scuttlebutt-protocol-guide/#feeds
54 | 52. Hellerstein, J.M., Faleiro, J., Gonzalez, J.E., Schleier-Smith, J., Sreekanti, V., Tumanov, A., Wu, C.: Serverless Computing: One Step Forward, Two Steps Back. arXiv:1812.03651 [cs]. (2018)
55 | 53. Catalini, C., Gans, J.S.: Some Simple Economics of the Blockchain. Social Science Research Network, Rochester, NY (2017)
56 | 54. Textile, https://textile.io/
57 | 55. Barrera, C.: The Blockchain Effect, https://medium.com/mit-cryptoeconomics-lab/the-blockchain-effect-86bd01006ec2
58 | 56. Tabora, V.: The Evolution of the Internet, From Decentralized to Centralized, https://hackernoon.com/the-evolution-of-the-internet-from-decentralized-to-centralized-3e2fa65898f5
59 | 57. Seemann, M.: The Identity functor, https://blog.ploeh.dk/2018/09/03/the-identity-functor/
60 | 58. Hickey, R.: The Value of Values, https://gotocon.com/dl/goto-cph-2012/slides/value-of-values.pdf
61 | 59. Berners-Lee, T.: Three challenges for the web, according to its inventor, https://webfoundation.org/2017/03/web-turns-28-letter/
62 | 60. Lamport, L.: Time, clocks, and the ordering of events in a distributed system. Commun. ACM. 21, 558–565 (1978). doi:10.1145/359545.359563
63 | 61. Kwang, Y.S.: Total functional programming, https://kseo.github.io/posts/2015-06-18-total-functional-programming.html
64 | 62. Turner, D.A.: Total Functional Programming. J. UCS. 10, 751–768 (2004). doi:10.3217/jucs-010-07-0751
65 | 63. Hillston, J.: Tuning Systems: From Composition to Performance. The Computer Journal. 48, 385–400 (2005). doi:10.1093/comjnl/bxh097
66 | 64. Kreps, J.: What every software engineer should know about real-time data’s unifying abstraction, https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying
67 | 65. What is a Merkle DAG?, https://discuss.ipfs.io/t/what-is-a-merkle-dag/386
68 | 66. Dixon, C.: Why Decentralization Matters – Featured Stories, https://medium.com/s/story/why-decentralization-matters-5e3f79f7638e
69 | 67. Pressler, R.: Why Writing Correct Software Is Hard, http://blog.paralleluniverse.co/2016/07/23/correctness-and-complexity/
70 | 68. World’s Biggest Data Breaches & Hacks, https://informationisbeautiful.net/visualizations/worlds-biggest-data-breaches-hacks/
71 | 69. Zamyatin, A., Harz, D., Lind, J., Panayiotou, P., Gervais, A., Knottenbelt, W.J.: XCLAIM: Trustless, Interoperable Cryptocurrency-Backed Assets. (2018)
72 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Attribution-ShareAlike 4.0 International
2 |
3 | =======================================================================
4 |
5 | Creative Commons Corporation ("Creative Commons") is not a law firm and
6 | does not provide legal services or legal advice. Distribution of
7 | Creative Commons public licenses does not create a lawyer-client or
8 | other relationship. Creative Commons makes its licenses and related
9 | information available on an "as-is" basis. Creative Commons gives no
10 | warranties regarding its licenses, any material licensed under their
11 | terms and conditions, or any related information. Creative Commons
12 | disclaims all liability for damages resulting from their use to the
13 | fullest extent possible.
14 |
15 | Using Creative Commons Public Licenses
16 |
17 | Creative Commons public licenses provide a standard set of terms and
18 | conditions that creators and other rights holders may use to share
19 | original works of authorship and other material subject to copyright
20 | and certain other rights specified in the public license below. The
21 | following considerations are for informational purposes only, are not
22 | exhaustive, and do not form part of our licenses.
23 |
24 | Considerations for licensors: Our public licenses are
25 | intended for use by those authorized to give the public
26 | permission to use material in ways otherwise restricted by
27 | copyright and certain other rights. Our licenses are
28 | irrevocable. Licensors should read and understand the terms
29 | and conditions of the license they choose before applying it.
30 | Licensors should also secure all rights necessary before
31 | applying our licenses so that the public can reuse the
32 | material as expected. Licensors should clearly mark any
33 | material not subject to the license. This includes other CC-
34 | licensed material, or material used under an exception or
35 | limitation to copyright. More considerations for licensors:
36 | wiki.creativecommons.org/Considerations_for_licensors
37 |
38 | Considerations for the public: By using one of our public
39 | licenses, a licensor grants the public permission to use the
40 | licensed material under specified terms and conditions. If
41 | the licensor's permission is not necessary for any reason--for
42 | example, because of any applicable exception or limitation to
43 | copyright--then that use is not regulated by the license. Our
44 | licenses grant only permissions under copyright and certain
45 | other rights that a licensor has authority to grant. Use of
46 | the licensed material may still be restricted for other
47 | reasons, including because others have copyright or other
48 | rights in the material. A licensor may make special requests,
49 | such as asking that all changes be marked or described.
50 | Although not required by our licenses, you are encouraged to
51 | respect those requests where reasonable. More considerations
52 | for the public:
53 | wiki.creativecommons.org/Considerations_for_licensees
54 |
55 | =======================================================================
56 |
57 | Creative Commons Attribution-ShareAlike 4.0 International Public
58 | License
59 |
60 | By exercising the Licensed Rights (defined below), You accept and agree
61 | to be bound by the terms and conditions of this Creative Commons
62 | Attribution-ShareAlike 4.0 International Public License ("Public
63 | License"). To the extent this Public License may be interpreted as a
64 | contract, You are granted the Licensed Rights in consideration of Your
65 | acceptance of these terms and conditions, and the Licensor grants You
66 | such rights in consideration of benefits the Licensor receives from
67 | making the Licensed Material available under these terms and
68 | conditions.
69 |
70 |
71 | Section 1 -- Definitions.
72 |
73 | a. Adapted Material means material subject to Copyright and Similar
74 | Rights that is derived from or based upon the Licensed Material
75 | and in which the Licensed Material is translated, altered,
76 | arranged, transformed, or otherwise modified in a manner requiring
77 | permission under the Copyright and Similar Rights held by the
78 | Licensor. For purposes of this Public License, where the Licensed
79 | Material is a musical work, performance, or sound recording,
80 | Adapted Material is always produced where the Licensed Material is
81 | synched in timed relation with a moving image.
82 |
83 | b. Adapter's License means the license You apply to Your Copyright
84 | and Similar Rights in Your contributions to Adapted Material in
85 | accordance with the terms and conditions of this Public License.
86 |
87 | c. BY-SA Compatible License means a license listed at
88 | creativecommons.org/compatiblelicenses, approved by Creative
89 | Commons as essentially the equivalent of this Public License.
90 |
91 | d. Copyright and Similar Rights means copyright and/or similar rights
92 | closely related to copyright including, without limitation,
93 | performance, broadcast, sound recording, and Sui Generis Database
94 | Rights, without regard to how the rights are labeled or
95 | categorized. For purposes of this Public License, the rights
96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar
97 | Rights.
98 |
99 | e. Effective Technological Measures means those measures that, in the
100 | absence of proper authority, may not be circumvented under laws
101 | fulfilling obligations under Article 11 of the WIPO Copyright
102 | Treaty adopted on December 20, 1996, and/or similar international
103 | agreements.
104 |
105 | f. Exceptions and Limitations means fair use, fair dealing, and/or
106 | any other exception or limitation to Copyright and Similar Rights
107 | that applies to Your use of the Licensed Material.
108 |
109 | g. License Elements means the license attributes listed in the name
110 | of a Creative Commons Public License. The License Elements of this
111 | Public License are Attribution and ShareAlike.
112 |
113 | h. Licensed Material means the artistic or literary work, database,
114 | or other material to which the Licensor applied this Public
115 | License.
116 |
117 | i. Licensed Rights means the rights granted to You subject to the
118 | terms and conditions of this Public License, which are limited to
119 | all Copyright and Similar Rights that apply to Your use of the
120 | Licensed Material and that the Licensor has authority to license.
121 |
122 | j. Licensor means the individual(s) or entity(ies) granting rights
123 | under this Public License.
124 |
125 | k. Share means to provide material to the public by any means or
126 | process that requires permission under the Licensed Rights, such
127 | as reproduction, public display, public performance, distribution,
128 | dissemination, communication, or importation, and to make material
129 | available to the public including in ways that members of the
130 | public may access the material from a place and at a time
131 | individually chosen by them.
132 |
133 | l. Sui Generis Database Rights means rights other than copyright
134 | resulting from Directive 96/9/EC of the European Parliament and of
135 | the Council of 11 March 1996 on the legal protection of databases,
136 | as amended and/or succeeded, as well as other essentially
137 | equivalent rights anywhere in the world.
138 |
139 | m. You means the individual or entity exercising the Licensed Rights
140 | under this Public License. Your has a corresponding meaning.
141 |
142 |
143 | Section 2 -- Scope.
144 |
145 | a. License grant.
146 |
147 | 1. Subject to the terms and conditions of this Public License,
148 | the Licensor hereby grants You a worldwide, royalty-free,
149 | non-sublicensable, non-exclusive, irrevocable license to
150 | exercise the Licensed Rights in the Licensed Material to:
151 |
152 | a. reproduce and Share the Licensed Material, in whole or
153 | in part; and
154 |
155 | b. produce, reproduce, and Share Adapted Material.
156 |
157 | 2. Exceptions and Limitations. For the avoidance of doubt, where
158 | Exceptions and Limitations apply to Your use, this Public
159 | License does not apply, and You do not need to comply with
160 | its terms and conditions.
161 |
162 | 3. Term. The term of this Public License is specified in Section
163 | 6(a).
164 |
165 | 4. Media and formats; technical modifications allowed. The
166 | Licensor authorizes You to exercise the Licensed Rights in
167 | all media and formats whether now known or hereafter created,
168 | and to make technical modifications necessary to do so. The
169 | Licensor waives and/or agrees not to assert any right or
170 | authority to forbid You from making technical modifications
171 | necessary to exercise the Licensed Rights, including
172 | technical modifications necessary to circumvent Effective
173 | Technological Measures. For purposes of this Public License,
174 | simply making modifications authorized by this Section 2(a)
175 | (4) never produces Adapted Material.
176 |
177 | 5. Downstream recipients.
178 |
179 | a. Offer from the Licensor -- Licensed Material. Every
180 | recipient of the Licensed Material automatically
181 | receives an offer from the Licensor to exercise the
182 | Licensed Rights under the terms and conditions of this
183 | Public License.
184 |
185 | b. Additional offer from the Licensor -- Adapted Material.
186 | Every recipient of Adapted Material from You
187 | automatically receives an offer from the Licensor to
188 | exercise the Licensed Rights in the Adapted Material
189 | under the conditions of the Adapter's License You apply.
190 |
191 | c. No downstream restrictions. You may not offer or impose
192 | any additional or different terms or conditions on, or
193 | apply any Effective Technological Measures to, the
194 | Licensed Material if doing so restricts exercise of the
195 | Licensed Rights by any recipient of the Licensed
196 | Material.
197 |
198 | 6. No endorsement. Nothing in this Public License constitutes or
199 | may be construed as permission to assert or imply that You
200 | are, or that Your use of the Licensed Material is, connected
201 | with, or sponsored, endorsed, or granted official status by,
202 | the Licensor or others designated to receive attribution as
203 | provided in Section 3(a)(1)(A)(i).
204 |
205 | b. Other rights.
206 |
207 | 1. Moral rights, such as the right of integrity, are not
208 | licensed under this Public License, nor are publicity,
209 | privacy, and/or other similar personality rights; however, to
210 | the extent possible, the Licensor waives and/or agrees not to
211 | assert any such rights held by the Licensor to the limited
212 | extent necessary to allow You to exercise the Licensed
213 | Rights, but not otherwise.
214 |
215 | 2. Patent and trademark rights are not licensed under this
216 | Public License.
217 |
218 | 3. To the extent possible, the Licensor waives any right to
219 | collect royalties from You for the exercise of the Licensed
220 | Rights, whether directly or through a collecting society
221 | under any voluntary or waivable statutory or compulsory
222 | licensing scheme. In all other cases the Licensor expressly
223 | reserves any right to collect such royalties.
224 |
225 |
226 | Section 3 -- License Conditions.
227 |
228 | Your exercise of the Licensed Rights is expressly made subject to the
229 | following conditions.
230 |
231 | a. Attribution.
232 |
233 | 1. If You Share the Licensed Material (including in modified
234 | form), You must:
235 |
236 | a. retain the following if it is supplied by the Licensor
237 | with the Licensed Material:
238 |
239 | i. identification of the creator(s) of the Licensed
240 | Material and any others designated to receive
241 | attribution, in any reasonable manner requested by
242 | the Licensor (including by pseudonym if
243 | designated);
244 |
245 | ii. a copyright notice;
246 |
247 | iii. a notice that refers to this Public License;
248 |
249 | iv. a notice that refers to the disclaimer of
250 | warranties;
251 |
252 | v. a URI or hyperlink to the Licensed Material to the
253 | extent reasonably practicable;
254 |
255 | b. indicate if You modified the Licensed Material and
256 | retain an indication of any previous modifications; and
257 |
258 | c. indicate the Licensed Material is licensed under this
259 | Public License, and include the text of, or the URI or
260 | hyperlink to, this Public License.
261 |
262 | 2. You may satisfy the conditions in Section 3(a)(1) in any
263 | reasonable manner based on the medium, means, and context in
264 | which You Share the Licensed Material. For example, it may be
265 | reasonable to satisfy the conditions by providing a URI or
266 | hyperlink to a resource that includes the required
267 | information.
268 |
269 | 3. If requested by the Licensor, You must remove any of the
270 | information required by Section 3(a)(1)(A) to the extent
271 | reasonably practicable.
272 |
273 | b. ShareAlike.
274 |
275 | In addition to the conditions in Section 3(a), if You Share
276 | Adapted Material You produce, the following conditions also apply.
277 |
278 | 1. The Adapter's License You apply must be a Creative Commons
279 | license with the same License Elements, this version or
280 | later, or a BY-SA Compatible License.
281 |
282 | 2. You must include the text of, or the URI or hyperlink to, the
283 | Adapter's License You apply. You may satisfy this condition
284 | in any reasonable manner based on the medium, means, and
285 | context in which You Share Adapted Material.
286 |
287 | 3. You may not offer or impose any additional or different terms
288 | or conditions on, or apply any Effective Technological
289 | Measures to, Adapted Material that restrict exercise of the
290 | rights granted under the Adapter's License You apply.
291 |
292 |
293 | Section 4 -- Sui Generis Database Rights.
294 |
295 | Where the Licensed Rights include Sui Generis Database Rights that
296 | apply to Your use of the Licensed Material:
297 |
298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right
299 | to extract, reuse, reproduce, and Share all or a substantial
300 | portion of the contents of the database;
301 |
302 | b. if You include all or a substantial portion of the database
303 | contents in a database in which You have Sui Generis Database
304 | Rights, then the database in which You have Sui Generis Database
305 | Rights (but not its individual contents) is Adapted Material,
306 |
307 | including for purposes of Section 3(b); and
308 | c. You must comply with the conditions in Section 3(a) if You Share
309 | all or a substantial portion of the contents of the database.
310 |
311 | For the avoidance of doubt, this Section 4 supplements and does not
312 | replace Your obligations under this Public License where the Licensed
313 | Rights include other Copyright and Similar Rights.
314 |
315 |
316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability.
317 |
318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
328 |
329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
338 |
339 | c. The disclaimer of warranties and limitation of liability provided
340 | above shall be interpreted in a manner that, to the extent
341 | possible, most closely approximates an absolute disclaimer and
342 | waiver of all liability.
343 |
344 |
345 | Section 6 -- Term and Termination.
346 |
347 | a. This Public License applies for the term of the Copyright and
348 | Similar Rights licensed here. However, if You fail to comply with
349 | this Public License, then Your rights under this Public License
350 | terminate automatically.
351 |
352 | b. Where Your right to use the Licensed Material has terminated under
353 | Section 6(a), it reinstates:
354 |
355 | 1. automatically as of the date the violation is cured, provided
356 | it is cured within 30 days of Your discovery of the
357 | violation; or
358 |
359 | 2. upon express reinstatement by the Licensor.
360 |
361 | For the avoidance of doubt, this Section 6(b) does not affect any
362 | right the Licensor may have to seek remedies for Your violations
363 | of this Public License.
364 |
365 | c. For the avoidance of doubt, the Licensor may also offer the
366 | Licensed Material under separate terms or conditions or stop
367 | distributing the Licensed Material at any time; however, doing so
368 | will not terminate this Public License.
369 |
370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
371 | License.
372 |
373 |
374 | Section 7 -- Other Terms and Conditions.
375 |
376 | a. The Licensor shall not be bound by any additional or different
377 | terms or conditions communicated by You unless expressly agreed.
378 |
379 | b. Any arrangements, understandings, or agreements regarding the
380 | Licensed Material not stated herein are separate from and
381 | independent of the terms and conditions of this Public License.
382 |
383 |
384 | Section 8 -- Interpretation.
385 |
386 | a. For the avoidance of doubt, this Public License does not, and
387 | shall not be interpreted to, reduce, limit, restrict, or impose
388 | conditions on any use of the Licensed Material that could lawfully
389 | be made without permission under this Public License.
390 |
391 | b. To the extent possible, if any provision of this Public License is
392 | deemed unenforceable, it shall be automatically reformed to the
393 | minimum extent necessary to make it enforceable. If the provision
394 | cannot be reformed, it shall be severed from this Public License
395 | without affecting the enforceability of the remaining terms and
396 | conditions.
397 |
398 | c. No term or condition of this Public License will be waived and no
399 | failure to comply consented to unless expressly agreed to by the
400 | Licensor.
401 |
402 | d. Nothing in this Public License constitutes or may be interpreted
403 | as a limitation upon, or waiver of, any privileges and immunities
404 | that apply to the Licensor or You, including from the legal
405 | processes of any jurisdiction or authority.
406 |
407 |
408 | =======================================================================
409 |
410 | Creative Commons is not a party to its public
411 | licenses. Notwithstanding, Creative Commons may elect to apply one of
412 | its public licenses to material it publishes and in those instances
413 | will be considered the “Licensor.” The text of the Creative Commons
414 | public licenses is dedicated to the public domain under the CC0 Public
415 | Domain Dedication. Except for the limited purpose of indicating that
416 | material is shared under a Creative Commons public license or as
417 | otherwise permitted by the Creative Commons policies published at
418 | creativecommons.org/policies, Creative Commons does not authorize the
419 | use of the trademark "Creative Commons" or any other trademark or logo
420 | of Creative Commons without its prior written consent including,
421 | without limitation, in connection with any unauthorized modifications
422 | to any of its public licenses or any other arrangements,
423 | understandings, or agreements concerning use of licensed material. For
424 | the avoidance of doubt, this paragraph does not form part of the
425 | public licenses.
426 |
427 | Creative Commons may be contacted at creativecommons.org.
428 |
--------------------------------------------------------------------------------
/README-references.md:
--------------------------------------------------------------------------------
1 | # How to update references
2 |
3 | ## references.md
4 |
5 | Before doing updates to the references, you should know the following:
6 |
7 | - _references.md_ currently follows the [citation style](https://www.zotero.org/styles/distributed-computing?source=1) from the [_Distributed Computing_- journal](https://en.wikipedia.org/wiki/Distributed_Computing_(journal)).
8 | - The citations are numbered, and therefore the references must be in specific order. Currently, the references are sorted by title, in ascending alphabetical order.
9 | - In _references.md_, there are also anchor elements with a unique id for each source, so that we can have citations as intra-document links. Currently, the unique ids are MD5-hashes from the title of the source to make it agnostic to ordering (see the scripts below how to generate them).
10 |
11 | We've used [Zotero](https://www.zotero.org/) for bibliography management. The [_ambients.rdf_](/ambients.rdf)-file contains the bibliography in native Zotero format.
12 |
13 | If there is any wrong information, bad formatting etc in references, always make the changes to Zotero first and then commit the autogenerated _11-references.md_-file.
14 |
15 | 1. Update the reference in the Zotero collection
16 | 2. Generate a bibliography from the collection, with HTTP-links and using "Distributed Computing"-style (download it from settings if you don't have one already)
17 | 3. Copy the bibliography to clipboard and save to a file _11-references.md_
18 | 4. Run following commands (works in Linux but unfortunately not in MacOS, see [known issues](#known-issues)):
19 |
20 | ```
21 | sed -i -r 's_^([0-9])\._0\1._g' 11-references.md
22 | while read -r line; do printf "$line "; printf "%s\n" "${line:4}" | md5sum | grep -oP '^.{6}'; done < 11-references.md | sed -E 's_^(.+) ([0-9a-z]{6})$_\1 _g' > 11-references.md.temp && mv 11-references.md.temp 11-references.md
23 | sed -i -r 's_^0([0-9])\._\1._g' 11-references.md
24 | sed -i '1s/^/# IX. References {references}\n\n/' 11-references.md
25 | grep -P "^[0-9].+" 11-references.md | sed -r 's_^([0-9]+).+span id="([a-f0-9]{6})".+_s/\\[[0-9]+\\]\\(#\2\\)/[\1](#\2)/g_g' | sort | uniq > fix_citations.txt && while read -r line; do sed -i -r "$line" *.md; done < fix_citations.txt && rm fix_citations.txt
26 | ```
27 | for 1) prefixing the numbered items with zero 2) inserting spans after every reference with order-agnostic md5-hash as anchor link id 3) removing the zero-prefixes 4) reinserting the header 5) replacing every citation in the paper with the new order-number
28 | 5. Export the changed Zotero collection as new _ambients.rdf_-file.
29 |
30 | ## Known issues
31 |
32 | - Commands for citation update do not work in MacOS.
33 | - Citation updates should be part of the tools, not separate commands to run
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ambients Protocol White Paper
2 |
3 | This directory contains all the files and assets for the Ambients Protocol white paper, along with the tools to generate a PDF version.
4 |
5 | ### 📄 [Download the paper](https://ipfs.io/ipfs/QmPhPJE55GvqSz7Pwvkc8n9dbKmqGw6tUGTE1MgfNQvzsf)
6 |
7 | ## Paper contents
8 | The paper is written in Markdown format. Each section in the paper is in its own md-file, ordered by a numeric prefix.
9 |
10 | White paper contents:
11 | - [Abstract](/01-abstract.md)
12 | - [Introduction](/03-introduction.md)
13 | - [Protocol Overview](/04-protocol-overview.md)
14 | - [Distributed Programs as Ambients](/05-distributed-programs-as-ambients.md)
15 | - [Compilation Model](/06-compilation-model.md)
16 | - [Execution Model](/07-execution-model.md)
17 | - [Applications](/08-applications.md)
18 | - [Future Work](/09-future-work.md)
19 | - [Conclusion](/10-conclusion.md)
20 | - [References](/11-references.md)
21 |
22 | ### References
23 |
24 | Even if this white paper is not a strictly scientific work, we've been careful to keep the citations correct. The [_11-references.md_-file](/11-references.md) contains all the bibliographic references of the Ambients Protocol white paper (except the Wikipedia links). See the [_README-references.md_](/README-references.md) for more.
25 |
26 | ## Tools
27 | The _tools/_ directory contains the needed scripts to generate the PDF version of the paper. See the [README](/tools/README.md) for instructions on how to build the PDF.
28 |
29 | ## License
30 |
31 | [CC-BY 4.0](LICENSE), © 2019 Haja Networks Oy
32 |
--------------------------------------------------------------------------------
/ambients.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ambientsprotocol/whitepaper/aa79cc0e175ea280abb34bdeb4e1228920104617/ambients.pdf
--------------------------------------------------------------------------------
/tools/.gitignore:
--------------------------------------------------------------------------------
1 | *.pdf
2 | node_modules/
3 | dist/
4 |
--------------------------------------------------------------------------------
/tools/README.md:
--------------------------------------------------------------------------------
1 | # Build The Ambients Protocol Paper
2 |
3 | This tool will generate the paper as html and PDF.
4 |
5 | Install:
6 | ```
7 | npm install
8 | ```
9 |
10 | Build:
11 | ```
12 | npm run build
13 | ```
14 |
15 | The output files are in `dist/` directory.
16 |
--------------------------------------------------------------------------------
/tools/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ambients-paper-build-tools",
3 | "version": "0.0.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@types/node": {
8 | "version": "8.10.51",
9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz",
10 | "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q=="
11 | },
12 | "ansi-align": {
13 | "version": "2.0.0",
14 | "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
15 | "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
16 | "requires": {
17 | "string-width": "^2.0.0"
18 | }
19 | },
20 | "ansi-regex": {
21 | "version": "3.0.0",
22 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
23 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
24 | },
25 | "ansi-styles": {
26 | "version": "3.2.1",
27 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
28 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
29 | "requires": {
30 | "color-convert": "^1.9.0"
31 | }
32 | },
33 | "async-limiter": {
34 | "version": "1.0.0",
35 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
36 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
37 | },
38 | "babel-polyfill": {
39 | "version": "6.26.0",
40 | "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
41 | "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
42 | "requires": {
43 | "babel-runtime": "^6.26.0",
44 | "core-js": "^2.5.0",
45 | "regenerator-runtime": "^0.10.5"
46 | }
47 | },
48 | "babel-runtime": {
49 | "version": "6.26.0",
50 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
51 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
52 | "requires": {
53 | "core-js": "^2.4.0",
54 | "regenerator-runtime": "^0.11.0"
55 | },
56 | "dependencies": {
57 | "regenerator-runtime": {
58 | "version": "0.11.1",
59 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
60 | "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
61 | }
62 | }
63 | },
64 | "balanced-match": {
65 | "version": "1.0.0",
66 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
67 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
68 | },
69 | "boxen": {
70 | "version": "1.3.0",
71 | "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
72 | "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
73 | "requires": {
74 | "ansi-align": "^2.0.0",
75 | "camelcase": "^4.0.0",
76 | "chalk": "^2.0.1",
77 | "cli-boxes": "^1.0.0",
78 | "string-width": "^2.0.0",
79 | "term-size": "^1.2.0",
80 | "widest-line": "^2.0.0"
81 | }
82 | },
83 | "brace-expansion": {
84 | "version": "1.1.11",
85 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
86 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
87 | "requires": {
88 | "balanced-match": "^1.0.0",
89 | "concat-map": "0.0.1"
90 | }
91 | },
92 | "camelcase": {
93 | "version": "4.1.0",
94 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
95 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
96 | },
97 | "capture-stack-trace": {
98 | "version": "1.0.1",
99 | "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
100 | "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw=="
101 | },
102 | "chalk": {
103 | "version": "2.4.2",
104 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
105 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
106 | "requires": {
107 | "ansi-styles": "^3.2.1",
108 | "escape-string-regexp": "^1.0.5",
109 | "supports-color": "^5.3.0"
110 | }
111 | },
112 | "chrome-headless-render-pdf": {
113 | "version": "1.8.2",
114 | "resolved": "https://registry.npmjs.org/chrome-headless-render-pdf/-/chrome-headless-render-pdf-1.8.2.tgz",
115 | "integrity": "sha512-R8gfgN/+5q2IcJJsEXl5ZkfuV0BGv5bCKRRvMF0Fv5cAKNdVlkS8nO1ESw7ZN9VpdBEkJcAmgLiQwzgnD/ZQAQ==",
116 | "requires": {
117 | "@types/node": "^8.0.15",
118 | "babel-polyfill": "^6.23.0",
119 | "chrome-remote-interface": "^0.25.5",
120 | "command-exists": "^1.2.2",
121 | "minimist": "^1.2.0",
122 | "update-notifier": "^2.1.0"
123 | }
124 | },
125 | "chrome-remote-interface": {
126 | "version": "0.25.7",
127 | "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.25.7.tgz",
128 | "integrity": "sha512-6zI6LbR2IiGmduFZededaerEr9hHXabxT/L+fRrdq65a0CfyLMzpq0BKuZiqN0Upqcacsb6q2POj7fmobwBsEA==",
129 | "requires": {
130 | "commander": "2.11.x",
131 | "ws": "3.3.x"
132 | }
133 | },
134 | "ci-info": {
135 | "version": "1.6.0",
136 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
137 | "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A=="
138 | },
139 | "cli-boxes": {
140 | "version": "1.0.0",
141 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
142 | "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM="
143 | },
144 | "cliui": {
145 | "version": "5.0.0",
146 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
147 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
148 | "requires": {
149 | "string-width": "^3.1.0",
150 | "strip-ansi": "^5.2.0",
151 | "wrap-ansi": "^5.1.0"
152 | },
153 | "dependencies": {
154 | "ansi-regex": {
155 | "version": "4.1.0",
156 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
157 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
158 | },
159 | "string-width": {
160 | "version": "3.1.0",
161 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
162 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
163 | "requires": {
164 | "emoji-regex": "^7.0.1",
165 | "is-fullwidth-code-point": "^2.0.0",
166 | "strip-ansi": "^5.1.0"
167 | }
168 | },
169 | "strip-ansi": {
170 | "version": "5.2.0",
171 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
172 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
173 | "requires": {
174 | "ansi-regex": "^4.1.0"
175 | }
176 | }
177 | }
178 | },
179 | "color-convert": {
180 | "version": "1.9.3",
181 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
182 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
183 | "requires": {
184 | "color-name": "1.1.3"
185 | }
186 | },
187 | "color-name": {
188 | "version": "1.1.3",
189 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
190 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
191 | },
192 | "command-exists": {
193 | "version": "1.2.8",
194 | "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz",
195 | "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw=="
196 | },
197 | "commander": {
198 | "version": "2.11.0",
199 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
200 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ=="
201 | },
202 | "concat-map": {
203 | "version": "0.0.1",
204 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
205 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
206 | },
207 | "configstore": {
208 | "version": "3.1.2",
209 | "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
210 | "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
211 | "requires": {
212 | "dot-prop": "^4.1.0",
213 | "graceful-fs": "^4.1.2",
214 | "make-dir": "^1.0.0",
215 | "unique-string": "^1.0.0",
216 | "write-file-atomic": "^2.0.0",
217 | "xdg-basedir": "^3.0.0"
218 | }
219 | },
220 | "core-js": {
221 | "version": "2.6.9",
222 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
223 | "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A=="
224 | },
225 | "create-error-class": {
226 | "version": "3.0.2",
227 | "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
228 | "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
229 | "requires": {
230 | "capture-stack-trace": "^1.0.0"
231 | }
232 | },
233 | "cross-spawn": {
234 | "version": "5.1.0",
235 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
236 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
237 | "requires": {
238 | "lru-cache": "^4.0.1",
239 | "shebang-command": "^1.2.0",
240 | "which": "^1.2.9"
241 | }
242 | },
243 | "crypto-random-string": {
244 | "version": "1.0.0",
245 | "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
246 | "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
247 | },
248 | "decamelize": {
249 | "version": "1.2.0",
250 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
251 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
252 | },
253 | "deep-extend": {
254 | "version": "0.6.0",
255 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
256 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
257 | },
258 | "dot-prop": {
259 | "version": "4.2.1",
260 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz",
261 | "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
262 | "requires": {
263 | "is-obj": "^1.0.0"
264 | }
265 | },
266 | "duplexer3": {
267 | "version": "0.1.4",
268 | "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
269 | "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
270 | },
271 | "emoji-regex": {
272 | "version": "7.0.3",
273 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
274 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
275 | },
276 | "escape-string-regexp": {
277 | "version": "1.0.5",
278 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
279 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
280 | },
281 | "execa": {
282 | "version": "0.7.0",
283 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
284 | "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
285 | "requires": {
286 | "cross-spawn": "^5.0.1",
287 | "get-stream": "^3.0.0",
288 | "is-stream": "^1.1.0",
289 | "npm-run-path": "^2.0.0",
290 | "p-finally": "^1.0.0",
291 | "signal-exit": "^3.0.0",
292 | "strip-eof": "^1.0.0"
293 | }
294 | },
295 | "find-up": {
296 | "version": "3.0.0",
297 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
298 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
299 | "requires": {
300 | "locate-path": "^3.0.0"
301 | }
302 | },
303 | "fs.realpath": {
304 | "version": "1.0.0",
305 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
306 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
307 | },
308 | "get-caller-file": {
309 | "version": "2.0.5",
310 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
311 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
312 | },
313 | "get-stream": {
314 | "version": "3.0.0",
315 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
316 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
317 | },
318 | "git-rev-sync": {
319 | "version": "1.12.0",
320 | "resolved": "https://registry.npmjs.org/git-rev-sync/-/git-rev-sync-1.12.0.tgz",
321 | "integrity": "sha1-RGhAbH5sO6TPRYeZnhrbKNnRr1U=",
322 | "requires": {
323 | "escape-string-regexp": "1.0.5",
324 | "graceful-fs": "4.1.11",
325 | "shelljs": "0.7.7"
326 | },
327 | "dependencies": {
328 | "graceful-fs": {
329 | "version": "4.1.11",
330 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
331 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
332 | }
333 | }
334 | },
335 | "glob": {
336 | "version": "7.1.4",
337 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
338 | "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
339 | "requires": {
340 | "fs.realpath": "^1.0.0",
341 | "inflight": "^1.0.4",
342 | "inherits": "2",
343 | "minimatch": "^3.0.4",
344 | "once": "^1.3.0",
345 | "path-is-absolute": "^1.0.0"
346 | }
347 | },
348 | "global-dirs": {
349 | "version": "0.1.1",
350 | "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
351 | "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
352 | "requires": {
353 | "ini": "^1.3.4"
354 | }
355 | },
356 | "got": {
357 | "version": "6.7.1",
358 | "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
359 | "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
360 | "requires": {
361 | "create-error-class": "^3.0.0",
362 | "duplexer3": "^0.1.4",
363 | "get-stream": "^3.0.0",
364 | "is-redirect": "^1.0.0",
365 | "is-retry-allowed": "^1.0.0",
366 | "is-stream": "^1.0.0",
367 | "lowercase-keys": "^1.0.0",
368 | "safe-buffer": "^5.0.1",
369 | "timed-out": "^4.0.0",
370 | "unzip-response": "^2.0.1",
371 | "url-parse-lax": "^1.0.0"
372 | }
373 | },
374 | "graceful-fs": {
375 | "version": "4.2.0",
376 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
377 | "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg=="
378 | },
379 | "has-flag": {
380 | "version": "3.0.0",
381 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
382 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
383 | },
384 | "import-lazy": {
385 | "version": "2.1.0",
386 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
387 | "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
388 | },
389 | "imurmurhash": {
390 | "version": "0.1.4",
391 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
392 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
393 | },
394 | "inflight": {
395 | "version": "1.0.6",
396 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
397 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
398 | "requires": {
399 | "once": "^1.3.0",
400 | "wrappy": "1"
401 | }
402 | },
403 | "inherits": {
404 | "version": "2.0.4",
405 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
406 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
407 | },
408 | "ini": {
409 | "version": "1.3.7",
410 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
411 | "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ=="
412 | },
413 | "interpret": {
414 | "version": "1.2.0",
415 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
416 | "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw=="
417 | },
418 | "is-ci": {
419 | "version": "1.2.1",
420 | "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
421 | "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
422 | "requires": {
423 | "ci-info": "^1.5.0"
424 | }
425 | },
426 | "is-fullwidth-code-point": {
427 | "version": "2.0.0",
428 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
429 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
430 | },
431 | "is-installed-globally": {
432 | "version": "0.1.0",
433 | "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
434 | "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
435 | "requires": {
436 | "global-dirs": "^0.1.0",
437 | "is-path-inside": "^1.0.0"
438 | }
439 | },
440 | "is-npm": {
441 | "version": "1.0.0",
442 | "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
443 | "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ="
444 | },
445 | "is-obj": {
446 | "version": "1.0.1",
447 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
448 | "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
449 | },
450 | "is-path-inside": {
451 | "version": "1.0.1",
452 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
453 | "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
454 | "requires": {
455 | "path-is-inside": "^1.0.1"
456 | }
457 | },
458 | "is-redirect": {
459 | "version": "1.0.0",
460 | "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
461 | "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
462 | },
463 | "is-retry-allowed": {
464 | "version": "1.1.0",
465 | "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
466 | "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
467 | },
468 | "is-stream": {
469 | "version": "1.1.0",
470 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
471 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
472 | },
473 | "isexe": {
474 | "version": "2.0.0",
475 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
476 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
477 | },
478 | "latest-version": {
479 | "version": "3.1.0",
480 | "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
481 | "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
482 | "requires": {
483 | "package-json": "^4.0.0"
484 | }
485 | },
486 | "locate-path": {
487 | "version": "3.0.0",
488 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
489 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
490 | "requires": {
491 | "p-locate": "^3.0.0",
492 | "path-exists": "^3.0.0"
493 | }
494 | },
495 | "lowercase-keys": {
496 | "version": "1.0.1",
497 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
498 | "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
499 | },
500 | "lru-cache": {
501 | "version": "4.1.5",
502 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
503 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
504 | "requires": {
505 | "pseudomap": "^1.0.2",
506 | "yallist": "^2.1.2"
507 | }
508 | },
509 | "make-dir": {
510 | "version": "1.3.0",
511 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
512 | "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
513 | "requires": {
514 | "pify": "^3.0.0"
515 | }
516 | },
517 | "minimatch": {
518 | "version": "3.0.4",
519 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
520 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
521 | "requires": {
522 | "brace-expansion": "^1.1.7"
523 | }
524 | },
525 | "minimist": {
526 | "version": "1.2.0",
527 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
528 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
529 | },
530 | "npm-run-path": {
531 | "version": "2.0.2",
532 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
533 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
534 | "requires": {
535 | "path-key": "^2.0.0"
536 | }
537 | },
538 | "once": {
539 | "version": "1.4.0",
540 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
541 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
542 | "requires": {
543 | "wrappy": "1"
544 | }
545 | },
546 | "p-finally": {
547 | "version": "1.0.0",
548 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
549 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
550 | },
551 | "p-limit": {
552 | "version": "2.3.0",
553 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
554 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
555 | "requires": {
556 | "p-try": "^2.0.0"
557 | }
558 | },
559 | "p-locate": {
560 | "version": "3.0.0",
561 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
562 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
563 | "requires": {
564 | "p-limit": "^2.0.0"
565 | }
566 | },
567 | "p-try": {
568 | "version": "2.2.0",
569 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
570 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
571 | },
572 | "package-json": {
573 | "version": "4.0.1",
574 | "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
575 | "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
576 | "requires": {
577 | "got": "^6.7.1",
578 | "registry-auth-token": "^3.0.1",
579 | "registry-url": "^3.0.3",
580 | "semver": "^5.1.0"
581 | }
582 | },
583 | "path-exists": {
584 | "version": "3.0.0",
585 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
586 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
587 | },
588 | "path-is-absolute": {
589 | "version": "1.0.1",
590 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
591 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
592 | },
593 | "path-is-inside": {
594 | "version": "1.0.2",
595 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
596 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
597 | },
598 | "path-key": {
599 | "version": "2.0.1",
600 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
601 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
602 | },
603 | "path-parse": {
604 | "version": "1.0.6",
605 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
606 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
607 | },
608 | "pify": {
609 | "version": "3.0.0",
610 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
611 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
612 | },
613 | "prepend-http": {
614 | "version": "1.0.4",
615 | "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
616 | "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
617 | },
618 | "pseudomap": {
619 | "version": "1.0.2",
620 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
621 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
622 | },
623 | "rc": {
624 | "version": "1.2.8",
625 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
626 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
627 | "requires": {
628 | "deep-extend": "^0.6.0",
629 | "ini": "~1.3.0",
630 | "minimist": "^1.2.0",
631 | "strip-json-comments": "~2.0.1"
632 | }
633 | },
634 | "rechoir": {
635 | "version": "0.6.2",
636 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
637 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
638 | "requires": {
639 | "resolve": "^1.1.6"
640 | }
641 | },
642 | "regenerator-runtime": {
643 | "version": "0.10.5",
644 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
645 | "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg="
646 | },
647 | "registry-auth-token": {
648 | "version": "3.4.0",
649 | "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
650 | "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
651 | "requires": {
652 | "rc": "^1.1.6",
653 | "safe-buffer": "^5.0.1"
654 | }
655 | },
656 | "registry-url": {
657 | "version": "3.1.0",
658 | "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
659 | "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
660 | "requires": {
661 | "rc": "^1.0.1"
662 | }
663 | },
664 | "require-directory": {
665 | "version": "2.1.1",
666 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
667 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
668 | },
669 | "require-main-filename": {
670 | "version": "2.0.0",
671 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
672 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
673 | },
674 | "resolve": {
675 | "version": "1.11.1",
676 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
677 | "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
678 | "requires": {
679 | "path-parse": "^1.0.6"
680 | }
681 | },
682 | "safe-buffer": {
683 | "version": "5.1.2",
684 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
685 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
686 | },
687 | "semver": {
688 | "version": "5.7.0",
689 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
690 | "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
691 | },
692 | "semver-diff": {
693 | "version": "2.1.0",
694 | "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
695 | "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
696 | "requires": {
697 | "semver": "^5.0.3"
698 | }
699 | },
700 | "set-blocking": {
701 | "version": "2.0.0",
702 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
703 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
704 | },
705 | "shebang-command": {
706 | "version": "1.2.0",
707 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
708 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
709 | "requires": {
710 | "shebang-regex": "^1.0.0"
711 | }
712 | },
713 | "shebang-regex": {
714 | "version": "1.0.0",
715 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
716 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
717 | },
718 | "shelljs": {
719 | "version": "0.7.7",
720 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz",
721 | "integrity": "sha1-svXHfvlxSPS09uImguELuoZnz/E=",
722 | "requires": {
723 | "glob": "^7.0.0",
724 | "interpret": "^1.0.0",
725 | "rechoir": "^0.6.2"
726 | }
727 | },
728 | "showdown": {
729 | "version": "1.9.1",
730 | "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz",
731 | "integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==",
732 | "requires": {
733 | "yargs": "^14.2"
734 | }
735 | },
736 | "signal-exit": {
737 | "version": "3.0.2",
738 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
739 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
740 | },
741 | "string-width": {
742 | "version": "2.1.1",
743 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
744 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
745 | "requires": {
746 | "is-fullwidth-code-point": "^2.0.0",
747 | "strip-ansi": "^4.0.0"
748 | }
749 | },
750 | "strip-ansi": {
751 | "version": "4.0.0",
752 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
753 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
754 | "requires": {
755 | "ansi-regex": "^3.0.0"
756 | }
757 | },
758 | "strip-eof": {
759 | "version": "1.0.0",
760 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
761 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
762 | },
763 | "strip-json-comments": {
764 | "version": "2.0.1",
765 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
766 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
767 | },
768 | "supports-color": {
769 | "version": "5.5.0",
770 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
771 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
772 | "requires": {
773 | "has-flag": "^3.0.0"
774 | }
775 | },
776 | "term-size": {
777 | "version": "1.2.0",
778 | "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
779 | "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
780 | "requires": {
781 | "execa": "^0.7.0"
782 | }
783 | },
784 | "timed-out": {
785 | "version": "4.0.1",
786 | "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
787 | "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
788 | },
789 | "ultron": {
790 | "version": "1.1.1",
791 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
792 | "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
793 | },
794 | "unique-string": {
795 | "version": "1.0.0",
796 | "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
797 | "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
798 | "requires": {
799 | "crypto-random-string": "^1.0.0"
800 | }
801 | },
802 | "unzip-response": {
803 | "version": "2.0.1",
804 | "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
805 | "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c="
806 | },
807 | "update-notifier": {
808 | "version": "2.5.0",
809 | "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
810 | "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
811 | "requires": {
812 | "boxen": "^1.2.1",
813 | "chalk": "^2.0.1",
814 | "configstore": "^3.0.0",
815 | "import-lazy": "^2.1.0",
816 | "is-ci": "^1.0.10",
817 | "is-installed-globally": "^0.1.0",
818 | "is-npm": "^1.0.0",
819 | "latest-version": "^3.0.0",
820 | "semver-diff": "^2.0.0",
821 | "xdg-basedir": "^3.0.0"
822 | }
823 | },
824 | "url-parse-lax": {
825 | "version": "1.0.0",
826 | "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
827 | "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
828 | "requires": {
829 | "prepend-http": "^1.0.1"
830 | }
831 | },
832 | "which": {
833 | "version": "1.3.1",
834 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
835 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
836 | "requires": {
837 | "isexe": "^2.0.0"
838 | }
839 | },
840 | "which-module": {
841 | "version": "2.0.0",
842 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
843 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
844 | },
845 | "widest-line": {
846 | "version": "2.0.1",
847 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
848 | "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
849 | "requires": {
850 | "string-width": "^2.1.1"
851 | }
852 | },
853 | "wrap-ansi": {
854 | "version": "5.1.0",
855 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
856 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
857 | "requires": {
858 | "ansi-styles": "^3.2.0",
859 | "string-width": "^3.0.0",
860 | "strip-ansi": "^5.0.0"
861 | },
862 | "dependencies": {
863 | "ansi-regex": {
864 | "version": "4.1.0",
865 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
866 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
867 | },
868 | "string-width": {
869 | "version": "3.1.0",
870 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
871 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
872 | "requires": {
873 | "emoji-regex": "^7.0.1",
874 | "is-fullwidth-code-point": "^2.0.0",
875 | "strip-ansi": "^5.1.0"
876 | }
877 | },
878 | "strip-ansi": {
879 | "version": "5.2.0",
880 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
881 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
882 | "requires": {
883 | "ansi-regex": "^4.1.0"
884 | }
885 | }
886 | }
887 | },
888 | "wrappy": {
889 | "version": "1.0.2",
890 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
891 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
892 | },
893 | "write-file-atomic": {
894 | "version": "2.4.3",
895 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
896 | "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
897 | "requires": {
898 | "graceful-fs": "^4.1.11",
899 | "imurmurhash": "^0.1.4",
900 | "signal-exit": "^3.0.2"
901 | }
902 | },
903 | "ws": {
904 | "version": "3.3.3",
905 | "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
906 | "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
907 | "requires": {
908 | "async-limiter": "~1.0.0",
909 | "safe-buffer": "~5.1.0",
910 | "ultron": "~1.1.0"
911 | }
912 | },
913 | "xdg-basedir": {
914 | "version": "3.0.0",
915 | "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
916 | "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
917 | },
918 | "y18n": {
919 | "version": "4.0.0",
920 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
921 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
922 | },
923 | "yallist": {
924 | "version": "2.1.2",
925 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
926 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
927 | },
928 | "yargs": {
929 | "version": "14.2.3",
930 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz",
931 | "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==",
932 | "requires": {
933 | "cliui": "^5.0.0",
934 | "decamelize": "^1.2.0",
935 | "find-up": "^3.0.0",
936 | "get-caller-file": "^2.0.1",
937 | "require-directory": "^2.1.1",
938 | "require-main-filename": "^2.0.0",
939 | "set-blocking": "^2.0.0",
940 | "string-width": "^3.0.0",
941 | "which-module": "^2.0.0",
942 | "y18n": "^4.0.0",
943 | "yargs-parser": "^15.0.1"
944 | },
945 | "dependencies": {
946 | "ansi-regex": {
947 | "version": "4.1.0",
948 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
949 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
950 | },
951 | "string-width": {
952 | "version": "3.1.0",
953 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
954 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
955 | "requires": {
956 | "emoji-regex": "^7.0.1",
957 | "is-fullwidth-code-point": "^2.0.0",
958 | "strip-ansi": "^5.1.0"
959 | }
960 | },
961 | "strip-ansi": {
962 | "version": "5.2.0",
963 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
964 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
965 | "requires": {
966 | "ansi-regex": "^4.1.0"
967 | }
968 | }
969 | }
970 | },
971 | "yargs-parser": {
972 | "version": "15.0.1",
973 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz",
974 | "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==",
975 | "requires": {
976 | "camelcase": "^5.0.0",
977 | "decamelize": "^1.2.0"
978 | },
979 | "dependencies": {
980 | "camelcase": {
981 | "version": "5.3.1",
982 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
983 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
984 | }
985 | }
986 | }
987 | }
988 | }
989 |
--------------------------------------------------------------------------------
/tools/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ambients-paper-build-tools",
3 | "version": "0.0.1",
4 | "description": "",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1",
7 | "build:concat": "node src/concat.js ../ dist/ambients.md ---",
8 | "build:md2html": "node src/md-to-html.js dist/ambients.md dist/ambients.html && cp src/html/style.css dist/style.css",
9 | "build:html2pdf": "./node_modules/.bin/chrome-headless-render-pdf --pdf=dist/ambients.pdf --url=file://${PWD}/dist/ambients.html --scale=0.8 --include-background",
10 | "build": "mkdir -p dist && npm run build:concat && npm run build:md2html && npm run build:html2pdf",
11 | "clean": "rm -rf dist/"
12 | },
13 | "author": "Haad",
14 | "license": "MIT",
15 | "dependencies": {
16 | "chrome-headless-render-pdf": "^1.8.2",
17 | "showdown": "^1.9.1",
18 | "git-rev-sync": "^1.12.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tools/src/concat.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const getFiles = require('./get-files')
4 |
5 | const inputPath = process.argv[2] || './'
6 | const outputFile = process.argv[3] || 'index.md'
7 | const pagebreak = process.argv[4] || null
8 |
9 | const run = async () => {
10 | const files = await getFiles(inputPath, 'md', { ignore: [outputFile, 'readme.md', 'readme-references.md'] })
11 | console.log('Merge files:')
12 | files.forEach(e => console.log(e))
13 | const contents = files.map(e => fs.readFileSync(path.join(inputPath, e)))
14 | const eof = (pagebreak ? ('\n\n' + pagebreak + '\n') : '') + '\n'
15 | const output = contents.join(eof) + '\n'
16 | fs.writeFileSync(outputFile, output)
17 | console.log(files.length + ' files merged to ' + outputFile)
18 | }
19 |
20 | run()
21 |
--------------------------------------------------------------------------------
/tools/src/get-files.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 |
3 | const getFiles = (dir, fileEnding, options) => new Promise((resolve, reject) => {
4 | // Default options
5 | options = Object.assign({}, { ignore: [] }, options)
6 |
7 | fs.readdir(dir, function(err, items) {
8 | if (err) {
9 | reject(err)
10 | }
11 |
12 | //console.log("All files:", items);
13 | const files = items
14 | .filter(e => e.split('.').pop().toLowerCase() === fileEnding)
15 | .filter(e => !options.ignore.includes(e.toLowerCase()))
16 |
17 |
18 | resolve(files)
19 | })
20 | })
21 |
22 | module.exports = getFiles
23 |
--------------------------------------------------------------------------------
/tools/src/html/footer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |