From 628d818163fd51a95dd6663a7d27a46286b59371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20=C5=A0ima?= Date: Thu, 7 Nov 2019 23:19:27 +0000 Subject: [PATCH] Revert "Merge with dev" This reverts commit 6ffe220d928dc3137496bcea0cc0f4d72edc2846. --- .../docs/advanced/entrypoints-contracts.md | 114 ++++ gitlab-pages/docs/advanced/first-contract.md | 152 ++++++ .../src/entrypoints-contracts/amount.ligo | 4 + .../src/entrypoints-contracts/owner.ligo | 5 + .../transaction/counter.ligo | 9 + .../transaction/counter.types.ligo | 4 + .../transaction/proxy.ligo | 14 + .../advanced/src/timestamps/timestamp.ligo | 9 + .../docs/advanced/timestamps-addresses.md | 69 +++ .../documentation-and-releases.md | 6 +- .../docs/contributors/getting-started.md | 61 ++- .../docs/contributors/ligo_test_guide.md | 106 ++-- gitlab-pages/docs/contributors/origin.md | 4 +- gitlab-pages/docs/contributors/philosophy.md | 11 +- gitlab-pages/docs/intro/editor-support.md | 12 + .../docs/{setup => intro}/installation.md | 23 +- .../docs/intro/src/what-and-why/counter.js | 15 + .../docs/intro/src/what-and-why/counter.tz | 7 + .../intro/src/what-and-why/ligo-counter.ligo | 12 + .../intro/src/what-and-why/ligo-counter.tz | 41 ++ gitlab-pages/docs/intro/what-and-why.md | 115 ++++ .../docs/language-basics/boolean-if-else.md | 153 ++++++ .../docs/language-basics/cheat-sheet.md | 2 +- .../docs/language-basics/entrypoints.md | 6 +- .../docs/language-basics/functions.md | 70 ++- .../docs/language-basics/maps-records.md | 157 ++++++ .../docs/language-basics/math-numbers-tez.md | 154 ++++++ .../docs/language-basics/operators.md | 2 +- .../language-basics/sets-lists-touples.md | 240 +++++++++ .../src/math-numbers-tez/addition.ligo | 13 + .../src/math-numbers-tez/casting.ligo | 2 + .../src/math-numbers-tez/division.ligo | 5 + .../src/math-numbers-tez/multiplication.ligo | 3 + .../src/math-numbers-tez/substraction.ligo | 6 + .../src/sets-lists-touples/empty-set.ligo | 3 + .../language-basics/src/strings/concat.ligo | 1 + .../docs/language-basics/src/types/alias.ligo | 2 + .../src/types/composed-types.ligo | 19 + .../src/types/simple-type.ligo | 6 + .../src/variables-and-constants/add.ligo | 7 + .../src/variables-and-constants/const.ligo | 1 + gitlab-pages/docs/language-basics/strings.md | 81 +++ gitlab-pages/docs/language-basics/types.md | 61 ++- .../unit-option-pattern-matching.md | 116 ++++ .../variables-and-constants.md | 88 ++++ .../docs/language-basics/variables.md | 40 -- gitlab-pages/docs/setup/editor-support.md | 8 - gitlab-pages/owner.pp.ligo | 0 gitlab-pages/timestamp.pp.ligo | 0 gitlab-pages/website/core/Footer.js | 3 +- gitlab-pages/website/package-lock.json | 495 +++++++++--------- gitlab-pages/website/package.json | 2 +- gitlab-pages/website/pages/en/index.js | 20 +- gitlab-pages/website/sidebars.json | 17 +- gitlab-pages/website/siteConfig.js | 2 +- gitlab-pages/website/static/css/custom.css | 211 ++++++-- .../intro/editor-support/error-reporting.png | Bin 0 -> 69426 bytes .../language-basics-entrypoints.md | 45 -- .../version-next/language-basics-functions.md | 23 - .../version-next/language-basics-operators.md | 13 - .../version-next/language-basics-variables.md | 19 - .../version-next-sidebars.json | 7 +- 62 files changed, 2330 insertions(+), 566 deletions(-) create mode 100644 gitlab-pages/docs/advanced/entrypoints-contracts.md create mode 100644 gitlab-pages/docs/advanced/first-contract.md create mode 100644 gitlab-pages/docs/advanced/src/entrypoints-contracts/amount.ligo create mode 100644 gitlab-pages/docs/advanced/src/entrypoints-contracts/owner.ligo create mode 100644 gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.ligo create mode 100644 gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.types.ligo create mode 100644 gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/proxy.ligo create mode 100644 gitlab-pages/docs/advanced/src/timestamps/timestamp.ligo create mode 100644 gitlab-pages/docs/advanced/timestamps-addresses.md create mode 100644 gitlab-pages/docs/intro/editor-support.md rename gitlab-pages/docs/{setup => intro}/installation.md (62%) create mode 100644 gitlab-pages/docs/intro/src/what-and-why/counter.js create mode 100644 gitlab-pages/docs/intro/src/what-and-why/counter.tz create mode 100644 gitlab-pages/docs/intro/src/what-and-why/ligo-counter.ligo create mode 100644 gitlab-pages/docs/intro/src/what-and-why/ligo-counter.tz create mode 100644 gitlab-pages/docs/intro/what-and-why.md create mode 100644 gitlab-pages/docs/language-basics/boolean-if-else.md create mode 100644 gitlab-pages/docs/language-basics/maps-records.md create mode 100644 gitlab-pages/docs/language-basics/math-numbers-tez.md create mode 100644 gitlab-pages/docs/language-basics/sets-lists-touples.md create mode 100644 gitlab-pages/docs/language-basics/src/math-numbers-tez/addition.ligo create mode 100644 gitlab-pages/docs/language-basics/src/math-numbers-tez/casting.ligo create mode 100644 gitlab-pages/docs/language-basics/src/math-numbers-tez/division.ligo create mode 100644 gitlab-pages/docs/language-basics/src/math-numbers-tez/multiplication.ligo create mode 100644 gitlab-pages/docs/language-basics/src/math-numbers-tez/substraction.ligo create mode 100644 gitlab-pages/docs/language-basics/src/sets-lists-touples/empty-set.ligo create mode 100644 gitlab-pages/docs/language-basics/src/strings/concat.ligo create mode 100644 gitlab-pages/docs/language-basics/src/types/alias.ligo create mode 100644 gitlab-pages/docs/language-basics/src/types/composed-types.ligo create mode 100644 gitlab-pages/docs/language-basics/src/types/simple-type.ligo create mode 100644 gitlab-pages/docs/language-basics/src/variables-and-constants/add.ligo create mode 100644 gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo create mode 100644 gitlab-pages/docs/language-basics/strings.md create mode 100644 gitlab-pages/docs/language-basics/unit-option-pattern-matching.md create mode 100644 gitlab-pages/docs/language-basics/variables-and-constants.md delete mode 100644 gitlab-pages/docs/language-basics/variables.md delete mode 100644 gitlab-pages/docs/setup/editor-support.md create mode 100644 gitlab-pages/owner.pp.ligo create mode 100644 gitlab-pages/timestamp.pp.ligo create mode 100644 gitlab-pages/website/static/img/docs/intro/editor-support/error-reporting.png delete mode 100644 gitlab-pages/website/versioned_docs/version-next/language-basics-entrypoints.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/language-basics-functions.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/language-basics-operators.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/language-basics-variables.md diff --git a/gitlab-pages/docs/advanced/entrypoints-contracts.md b/gitlab-pages/docs/advanced/entrypoints-contracts.md new file mode 100644 index 000000000..50b24d333 --- /dev/null +++ b/gitlab-pages/docs/advanced/entrypoints-contracts.md @@ -0,0 +1,114 @@ +--- +id: entrypoints-contracts +title: Entrypoints, Contracts +--- + +## Entrypoints + +Each LIGO smart contract is essentially a single function, that has the following *(pseudo)* type signature: + + + +``` +(const parameter: my_type, const store: my_store_type): (list(operation), my_store_type) +``` + + +This means that every smart contract needs at least one entrypoint function, here's an example: + +> 💡 The contract below literally does *nothing* + + + +``` +type parameter is unit; +type store is unit; +function main(const parameter: parameter; const store: store): (list(operation) * store) is + block { skip } with ((nil : list(operation)), store) +``` + + +Each entrypoint function receives two arguments: +- `parameter` - this is the parameter received in the invocation operation +- `storage` - this is the current (real) on-chain storage value + +Storage can only be modified by running the smart contract entrypoint, which is responsible for returning a list of operations, and a new storage at the end of it's execution. + + +## Built-in contract variables + +Each LIGO smart contract deployed on the Tezos blockchain, has access to certain built-in variables/constants that can be used to determine a range +of useful things. In this section you'll find how those built-ins can be utilized. + +### Accepting/declining money in a smart contract + +This example shows how `amount` and `failwith` can be used to decline a transaction that sends more tez than `0mutez`. + + + +``` +function main (const p : unit ; const s : unit) : (list(operation) * unit) is + block { + if amount > 0mutez then failwith("This contract does not accept tez") else skip + } with ((nil : list(operation)), unit); +``` + + +### Access control locking + +This example shows how `sender` or `source` can be used to deny access to an entrypoint. + + + +``` +const owner: address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address); +function main (const p : unit ; const s : unit) : (list(operation) * unit) is + block { + if source =/= owner then failwith("This address can't call the contract") else skip + } with ((nil : list(operation)), unit); +``` + + +### Cross contract calls + +This example shows how a contract can invoke another contract by emiting a transaction operation at the end of an entrypoint. + +> The same technique can be used to transfer tez to an implicit account (tz1, ...), all you have to do is use `unit` instead of a parameter for a smart contract. + +In our case, we have a `counter.ligo` contract that accepts a parameter of type `action`, and we have a `proxy.ligo` contract that accepts the same parameter type, and forwards the call to the deployed counter contract. + + + +``` +// counter.types.ligo +type action is +| Increment of int +| Decrement of int +| Reset of unit +``` + +``` +// counter.ligo +type action is +| Increment of int +| Decrement of int +| Reset of unit +``` + +``` +// proxy.ligo +#include "counter.types.ligo" + +const address: address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3": address); + +function proxy(const param: action; const store: unit): (list(operation) * unit) + is block { + const counter: contract(action) = get_contract(address); + // re-use the param passed to the proxy in the subsequent transaction + // e.g.: + // const mockParam: action = Increment(5); + const op: operation = transaction(param, 0mutez, counter); + const opList: list(operation) = list op; end; + } with (opList, store) +``` + \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/first-contract.md b/gitlab-pages/docs/advanced/first-contract.md new file mode 100644 index 000000000..4932cd5f5 --- /dev/null +++ b/gitlab-pages/docs/advanced/first-contract.md @@ -0,0 +1,152 @@ +--- +id: first-contract +title: First contract +--- + +So far so good, we've learned enough of the LIGO language, we're confident enough to write out first smart contract. + +We'll be implementing a counter contract, let's go. + +## Dry-running a contract + +Testing a contract can be quite easy if we utilize LIGO's built-in dry run feature. Dry-run works by simulating the entrypoint execution, as if it were deployed on a real chain. You need to provide the following: + +- `file` - contract to run +- `entrypoint` - name of the function to execute +- `parameter` - parameter passed to the entrypoint (in a theoretical invocation operation) +- `storage` - a mock storage value, as if it were stored on a real chain + +Here's a full example: + + + +``` +ligo dry-run src/basic.ligo main Unit Unit +// Outputs: +// tuple[ list[] +// Unit +// ] +``` + + +Output of the `dry-run` is the return value of our entrypoint function, we can see the operations emited - in our case an empty list, and the new storage value being returned - which in our case is still `Unit`. + +## Building a counter contract + +Our counter contract will store a single `int` as it's storage, and will accept an `action` variant in order to re-route our single `main` entrypoint into two entrypoints for `addition` and `subtraction`. + + + +``` +type action is +| Increment of int +| Decrement of int + +function main (const p : action ; const s : int) : (list(operation) * int) is + block {skip} with ((nil : list(operation)), + case p of + | Increment (n) -> s + n + | Decrement (n) -> s - n + end) +``` + + +To dry-run the counter contract, we will use the `main` entrypoint, provide a variant parameter of `Increment(5)` and an initial storage value of `5`. + + + + +``` +ligo dry-run src/counter.ligo main "Increment(5)" 5 +// tuple[ list[] +// 10 +// ] +``` + + + +Yay, our contract's storage has been successfuly incremented to `10`. + +## Deploying and interacting with a contract on a live-chain + +In order to deploy the counter contract to a real Tezos network, we'd have to compile it first, this can be done with the help of the `compile-contract` CLI command: + + + +``` +ligo compile-contract src/counter.ligo main +``` + + + +Command above will output the following Michelson code: + + + +``` +{ parameter (or (int %decrement) (int %increment)) ; + storage int ; + code { DUP ; + CAR ; + DIP { DUP } ; + SWAP ; + CDR ; + DIP { DUP } ; + SWAP ; + IF_LEFT + { DUP ; + DIP 2 { DUP } ; + DIG 2 ; + DIP { DUP } ; + SUB ; + SWAP ; + DROP ; + SWAP ; + DROP } + { DUP ; + DIP 2 { DUP } ; + DIG 2 ; + DIP { DUP } ; + ADD ; + SWAP ; + DROP ; + SWAP ; + DROP } ; + NIL operation ; + PAIR ; + SWAP ; + DROP ; + SWAP ; + DROP ; + SWAP ; + DROP } } +``` + + +However in order to originate a Michelson contract on Tezos, we also need to provide the initial storage value, we can use `compile-storage` to compile the LIGO representation of the storage to Michelson. + + + +``` +ligo compile-storage src/counter.ligo main 5 +// Outputs: 5 +``` + + + +In our case the LIGO storage value maps 1:1 to it's Michelson representation, however this will not be the case once the parameter is of a more complex data type, like a record. + +## Invoking a LIGO contract + +Same rules apply for parameters, as apply for translating LIGO storage values to Michelson. We will need to use `compile-parameter` to compile our `action` variant into Michelson, here's how: + + + +``` +ligo compile-parameter src/counter.ligo main 'Increment(5)' +// Outputs: (Right 5) +``` + + + +Now we can use `(Right 5)` which is a Michelson value, to invoke our contract - e.g. via `tezos-client` \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/src/entrypoints-contracts/amount.ligo b/gitlab-pages/docs/advanced/src/entrypoints-contracts/amount.ligo new file mode 100644 index 000000000..fce71cde2 --- /dev/null +++ b/gitlab-pages/docs/advanced/src/entrypoints-contracts/amount.ligo @@ -0,0 +1,4 @@ +function main (const p : unit ; const s : unit) : (list(operation) * unit) is + block { + if amount > 0mutez then failwith("This contract does not accept tez") else skip + } with ((nil : list(operation)), unit); \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/src/entrypoints-contracts/owner.ligo b/gitlab-pages/docs/advanced/src/entrypoints-contracts/owner.ligo new file mode 100644 index 000000000..b35b7c9fc --- /dev/null +++ b/gitlab-pages/docs/advanced/src/entrypoints-contracts/owner.ligo @@ -0,0 +1,5 @@ +const owner: address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address); +function main (const p : unit ; const s : unit) : (list(operation) * unit) is + block { + if source =/= owner then failwith("This address can't call the contract") else skip + } with ((nil : list(operation)), unit); \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.ligo b/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.ligo new file mode 100644 index 000000000..0c5f0c6d7 --- /dev/null +++ b/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.ligo @@ -0,0 +1,9 @@ +#include "counter.types.ligo" + +function counter (const p : action ; const s : int): (list(operation) * int) is + block { skip } with ((nil : list(operation)), + case p of + | Increment(n) -> s + n + | Decrement(n) -> s - n + | Reset(n) -> 0 + end) \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.types.ligo b/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.types.ligo new file mode 100644 index 000000000..be37bbf30 --- /dev/null +++ b/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/counter.types.ligo @@ -0,0 +1,4 @@ +type action is +| Increment of int +| Decrement of int +| Reset of unit \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/proxy.ligo b/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/proxy.ligo new file mode 100644 index 000000000..47b7b1f64 --- /dev/null +++ b/gitlab-pages/docs/advanced/src/entrypoints-contracts/transaction/proxy.ligo @@ -0,0 +1,14 @@ +#include "counter.types.ligo" + +// Replace the following address with your deployed counter contract address +const address: address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3": address); + +function proxy(const param: action; const store: unit): (list(operation) * unit) + is block { + const counter: contract(action) = get_contract(address); + // re-use the param passed to the proxy in the subsequent transaction + // e.g.: + // const mockParam: action = Increment(5); + const op: operation = transaction(param, 0mutez, counter); + const opList: list(operation) = list op; end; + } with (opList, store) \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/src/timestamps/timestamp.ligo b/gitlab-pages/docs/advanced/src/timestamps/timestamp.ligo new file mode 100644 index 000000000..5c46e43b6 --- /dev/null +++ b/gitlab-pages/docs/advanced/src/timestamps/timestamp.ligo @@ -0,0 +1,9 @@ +const today: timestamp = now; +const one_day: int = 86400; +const in_24_hrs: timestamp = today + one_day; + +const today: timestamp = now; +const one_day: int = 86400; +const a_24_hrs_ago: timestamp = today - one_day; + +const not_tommorow: bool = (now = in_24_hrs) \ No newline at end of file diff --git a/gitlab-pages/docs/advanced/timestamps-addresses.md b/gitlab-pages/docs/advanced/timestamps-addresses.md new file mode 100644 index 000000000..638942458 --- /dev/null +++ b/gitlab-pages/docs/advanced/timestamps-addresses.md @@ -0,0 +1,69 @@ +--- +id: timestamps-addresses +title: Timestamps, Addresses +--- + +## Timestamps + +Timestamps in LIGO, or in Michelson in general are available in smart contracts, while bakers baking the block (including the transaction in a block) are responsible for providing the given current timestamp for the contract. + +### Current time + +You can obtain the current time using the built-in syntax specific expression, please be aware that it's up to the baker to set the current timestamp value. + + + + +```pascaligo +const today: timestamp = now; +``` + + +### Timestamp arithmetic + +In LIGO, timestamps can be added with `int`(s), this enables you to set e.g. time constraints for your smart contracts like this: + +#### In 24 hours + + +```pascaligo +const today: timestamp = now; +const one_day: int = 86400; +const in_24_hrs: timestamp = today + one_day; +``` + + +#### 24 hours ago + + +```pascaligo +const today: timestamp = now; +const one_day: int = 86400; +const 24_hrs_ago: timestamp = today - one_day; +``` + + +### Comparing timestamps + +You can also compare timestamps using the same comparison operators as for numbers: + + + +```pascaligo +const not_tommorow: bool = (now = in_24_hrs) +``` + + +## Addresses + +`address` is a LIGO datatype used for Tezos addresses (tz1, tz2, tz3, KT1, ...). + +Here's how you can define an address: + + + +```pascaligo +const my_account: address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address); +``` + + diff --git a/gitlab-pages/docs/contributors/documentation-and-releases.md b/gitlab-pages/docs/contributors/documentation-and-releases.md index 977c9a9c7..16ca2ef49 100644 --- a/gitlab-pages/docs/contributors/documentation-and-releases.md +++ b/gitlab-pages/docs/contributors/documentation-and-releases.md @@ -6,15 +6,15 @@ title: Documentation and releases ## Documentation -In case you'd like to contribute to the docs, you can find them at [`gitlab-pages/docs`]() in their raw markdown form. +If you'd like to contribute to the docs you can find them at [`gitlab-pages/docs`]() in raw markdown form. Deployment of the docs/website for LIGO is taken care of within the CI, from `dev` and `master` branches. ## Releases & versioning ### Development releases (next) -Development releases of Ligo are tagged as `next` and are built with each commit to the `dev` branch. Both the docker image & the website are published automatically. +Development releases of Ligo are tagged `next` and are built with each commit to the `dev` branch. Both the docker image & the website are published automatically. ### Stable releases -Releases tagged with version numbers `x.x.x` are built manually, both docs & the docker image. While deployment of the website is handled by the CI. +Releases tagged with version numbers `x.x.x` are built manually, both docs & the docker image. Deployment of the website is handled by the CI. diff --git a/gitlab-pages/docs/contributors/getting-started.md b/gitlab-pages/docs/contributors/getting-started.md index 315adceb3..7b186dfad 100644 --- a/gitlab-pages/docs/contributors/getting-started.md +++ b/gitlab-pages/docs/contributors/getting-started.md @@ -4,37 +4,46 @@ title: Getting started --- ## Where -As we’ve seen, LIGO is big, as such, it is easier to start focus on a specific part of LIGO. As very vague suggestions: -If you want to immediately see the result of your contributions, you might want to start with the Front-End. This is what most people will directly see of LIGO. -If you want to get into Programming Language Theory, you might want to start with the Middle-End. This is where the Type System and the Language Definition are (the closest thing so far that you’ll find in a research paper). -If you want to get into the nitty gritty details of compiling to special targets, you’ll want to focus on the Back-End. -If you want to develop tooling on top of LIGO (editor integration, for instance), you’ll want to look at `Ast_typed/types.ml`. This is where most information that is relevant to devs will be (for now). -If you really want to get a grasp of the whole pipeline, search for issues tagged with “Everything”, they’ll have you look at multiple parts of the code base. +LIGO is big, so it is easier to focus on a specific part of LIGO. As starting suggestions: +* If you want to immediately see the result of your contributions, you might want to start with the Front-End. This is what most people will directly see of LIGO. +* If you want to get into Programming Language Theory, you might want to start with the Middle-End. This is where the Type System and the Language Definition are (the closest thing so far that you’ll find in a research paper). +* If you want to get into the nitty gritty details of compiling to special targets, focus on the Back-End. +* If you want to develop tooling on top of LIGO (editor integration for instance), look at `Ast_typed/types.ml`. This is where most information that is relevant to devs will be (for now). +* If you want to get a grasp of the whole pipeline, search for issues tagged with “Everything.” They’ll help you look at multiple parts of the code base. + ## What -Likely, the first issues will be about: -Adding tests -Extending the languages by adding new operators -Adding tests -Refactoring -Writing documentation and tutorials for users -Adding tests -Writing internal documentation when you understand a part of the code base ->Tests are **really** important, we don’t have lots of them, and mostly regression ones. This can’t be stressed enough. Some features are missing not because we can’t add them, but because we don’t know so as no tests tell us they are missing. +The first issues will most likely be: +* Adding tests +* Extending the languages by adding new operators +* *Adding tests* +* Refactoring +* Writing documentation and tutorials for users +* **_Adding tests_** +* Writing internal documentation when you understand a part of the code base +>Tests are **really** important, we don’t have lots of them, and mostly regression ones. This can’t be stressed enough. Some features are missing not because we can’t add them, but because we don’t know as no tests tell us they are missing. + ## How -Issues will be added to the Gitlab, tagged with On-boarding and Front-End / Middle-End / Back-End / Everything. If you try to tackle one issue, and you have **any** problem, please tell us, by creating a new Gitlab issue, contacting us on Riot, Discord or even by mail! Problems might include: -Installing the repository or the tools needed to work on it -OCaml weirdness -Understanding undocumented parts of the code base -Documented parts of the code base too -**Anything really** +Issues will be added to Gitlab tagged with `On-boarding and Front-End` / `Middle-End` / `Back-End` / `Everything`. + +If you try to tackle an issue and you have **any** problem, please tell us by creating a new Gitlab issue, contacting us on Riot, on Discord, or even by mail! + +Problems might include: +* Installing the repository or the tools needed to work on it +* OCaml weirdness +* Understanding undocumented parts of the code base +* Understanding documented parts of the code base + +**Anything, really.** --- ## FAQ -### I don’t know much about OCaml, where should I start? What should I have in mind? -I’d suggesting going through Real World OCaml to get a feel for the language, to know what are its features, and to know what to Google when you’re lost. -Beyond that, I’d say, start hacking! Either on LIGO’s code base, or on any personal project. -There is a Discord server if you want real-time help (which makes things go way faster than waiting for an answer on stackoverflow or looking mindlessly at the monitor). + +### I don’t know much about OCaml. Where should I start? What should I keep in mind? +I’d suggesting going through Real World OCaml to get a feel for the language, to know its features, and to know what to Google when you’re lost. +Beyond that, I’d say, start hacking! Either on LIGO’s code base or on any personal project. +There is a Discord server if you want real-time help (which makes things go way faster than waiting for an answer on StackOverflow or staring mindlessly at the monitor). + ### I want to add [X] to LIGO! Where should I begin? -Trying to add a new feature from scratch instead of building upon one can be quite complicated. However, if you’re motivated, contact us! We’ll tell you what we see as the most likely plan to get the result you want to achieve. +Trying to add a new feature from scratch instead of building on one can be complicated. However, if you’re motivated, contact us! We’ll tell you what we see as the best plan to get the result you want. diff --git a/gitlab-pages/docs/contributors/ligo_test_guide.md b/gitlab-pages/docs/contributors/ligo_test_guide.md index 114b662c1..4726c7fe3 100644 --- a/gitlab-pages/docs/contributors/ligo_test_guide.md +++ b/gitlab-pages/docs/contributors/ligo_test_guide.md @@ -1,72 +1,108 @@ # Testing LIGO -Adding to the LIGO test suite is one of the more accessible ways to contribute. It exposes you to the compiler structure and primitives without necessarily demanding a deep understanding of OCaml or compiler development. And you'll probably become more familiar with LIGO itself in the process, which is helpful. +Adding to the LIGO test suite is one of the most accessible ways to contribute. It exposes you to the compiler structure and primitives without demanding a deep understanding of OCaml or compiler development. -Unfortunately right now LIGO itself doesn't have a good way to do automated testing. So the tests are written in OCaml, outside of the LIGO language. Thankfully the test code is typically less demanding than the features being tested. These tests are currently contained in [src/test](https://gitlab.com/ligolang/ligo/tree/dev/src/test), but the bulk are integration tests which rely on test contracts kept in [src/test/contracts](https://gitlab.com/ligolang/ligo/tree/dev/src/test/contracts). If you're new to LIGO, reading these contracts can be a useful introduction to a given syntax. In the future we plan +Bonus: you'll become more familiar with LIGO in the process! + +Tests are written in OCaml, as LIGO doesn't (yet) have a good way to do automated testing. Thankfully the test code is typically less demanding than the features being tested. + +Tests are currently contained in [src/test](https://gitlab.com/ligolang/ligo/tree/dev/src/test), but most are integration tests which rely on test contracts kept in [src/test/contracts](https://gitlab.com/ligolang/ligo/tree/dev/src/test/contracts). If you're new to LIGO, reading these contracts can be a useful introduction to a particular LIGO syntax. In the future we plan to have detailed documentation for each syntax, but at the moment we only have a reference manual for [PascaLIGO](https://gitlab.com/ligolang/ligo/blob/dev/src/passes/1-parser/pascaligo/Doc/pascaligo.md) ## How To Find Good Test Cases -Your first question is probably "If I'm not already experienced, how do I know what to test?". There's a handful of things you can do to systematically find good test cases. All of them will either get you more familiar with the LIGO code base or LIGO itself. +Your first question is probably "If I'm not already experienced, how do I know what to test?". There are a handful of things you can do to systematically find good test cases. All of them will either get you more familiar with the LIGO code base or LIGO itself. ### Extending Existing Test Cases -The fastest way to improve LIGO's test coverage is to extend existing test cases. This means considering the test cases that already exist, and thinking of things they don't cover or situations they'll fail on. A good deal of inference is required for this, but it requires minimal experience with the existing code. +The fastest way to improve LIGO's test coverage is to extend existing test cases. Consider the test cases that already exist, and think of things they don't cover or situations they'll fail in. A good deal of inference is required for this, but it requires minimal experience with the existing code. ### Studying The Parsers For Gaps In Coverage -LIGO is divided into a **front end** which handles syntax and a **backend** which optimizes and compiles a core language shared between syntaxes. You can find basic test cases for a particular LIGO syntax by studying its parser. You will find these under [src/passes/1-parser](https://gitlab.com/ligolang/ligo/tree/dev/src/passes/1-parser). One kind of useful test focuses on **coverage**, whether we have any testing at all for a particular aspect of a syntax. You can find these by carefully going over the syntax tree for a syntax (probably best read by looking at its `Parser.mly`) and comparing each branch to the test suite. While these tests are plentiful at the time of writing, they will eventually be filled in reliably as part of writing a new syntax. +LIGO is divided into two parts +- the **front end** handles syntax +- the **backend** optimizes and compiles a core language shared between syntaxes -### Creating Interesting Test Cases By Using LIGO +You can find basic test cases for a particular LIGO syntax by studying its parser. You will find the parser under [src/passes/1-parser](https://gitlab.com/ligolang/ligo/tree/dev/src/passes/1-parser). -Another kind of useful test focuses on **depth**, whether the features are put through a wide variety of complex scenarios to make sure they stand up to real world use. One of the best ways to write these -is to use LIGO for a real project. This will require some time and energy, not just to learn LIGO but to write projects complex enough to stretch the limits of what the language can do. At the same time however it will get you used to engaging with LIGO from a developers perspective, asking how things could be better or what features are underdeveloped. If your project has practical uses, you will also be contributing to the Tezos/LIGO ecosystem while you learn. Note that because LIGO is open source, in under for us to incorporate your work as a test case it needs to be licensed in a way that's compatible with LIGO. +### Two Useful Test Cases Using LIGO + +#### Coverage +> whether we have any testing at all for a particular aspect of a syntax + +You can find coverage tests by carefully going over the syntax tree for a syntax (probably best read by looking at its `Parser.mly`) and comparing each branch to the test suite. (These tests are plentiful at the time of writing, but they will eventually be filled in reliably as part of writing a new syntax.) + +#### Depth +> features are put through a wide variety of complex scenarios to make sure they stand up to real world use + +One of the best ways to find these is to use LIGO for a real project. This will require some time and energy—not just to learn LIGO but to write projects complex enough to stretch the limits of what the language can do. However, it will also get you used to engaging with LIGO from a developers perspective, asking how things could be better or what features are underdeveloped. If your project has practical use, you will also be contributing to the Tezos/LIGO ecosystem while you learn. + +*Note: because LIGO is open source, in order for us to add your work as a test case it needs to be licensed in a way that's compatible with LIGO.* ### Fuzzing (Speculative) -In the future you'll be able to [use fuzzing](https://en.wikipedia.org/wiki/Fuzzing) to generate test cases for LIGO. Fuzzing is often useful for finding 'weird' bugs on code paths that humans normally wouldn't stumble into. This makes it a useful supplement to human testing. +In the future you'll be able to [use fuzzing](https://en.wikipedia.org/wiki/Fuzzing) to generate test cases for LIGO. Fuzzing is often useful for finding 'weird' bugs on code paths that humans normally wouldn't stumble onto. This makes it a useful supplement to human testing. ## Structure of LIGO Tests -LIGO's OCaml-based tests are written in [alcotest](https://github.com/mirage/alcotest/). However the tests you encounter in [src/test/integration_tests.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/test/integration_tests.ml) are built on top of some abstractions, currently defined in [src/test/test_helpers.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/test/test_helpers.ml). The use of these can be inferred fairly well from looking at existing tests, but lets break a few of them down for analysis. We'll first analyze a short integration test for assignment: - +LIGO's OCaml-based tests are written in [alcotest](https://github.com/mirage/alcotest/). However, the tests you encounter in [src/test/integration_tests.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/test/integration_tests.ml) are built on top of some abstractions, currently defined in [src/test/test_helpers.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/test/test_helpers.ml). The use of these can be inferred fairly well from looking at existing tests, but let's break a few of them down for analysis. + ### Assignment Test + +We'll first analyze a short integration test for assignment. + let assign () : unit result = let%bind program = type_file "./contracts/assign.ligo" in let make_expect = fun n -> n + 1 in expect_eq_n_int program "main" make_expect -### assign.ligo - function main (const i : int) : int is - begin - i := i + 1 ; - end with i +#### assign.ligo + function main (const i : int) : int is + begin + i := i + 1 ; + end with i -So what's going on here? We have a function which takes no arguments and returns a `unit result`. We then define two variables, a `program` which is read from disk and fed to the LIGO compiler; and a comparison function `make_expect` which takes an integer and adds one to it. Using `expect_eq_n_int` the `program`'s main function is run and compared to the result of providing the same input to `make_expect`. This gives us some flavor of what to expect from these integration tests. Notice that the `main` argument given to `expect_eq_n_int` corresponds to the name of the function in `assign.ligo`. We can see in more complex tests that we're able to pull the values of arbitrary expressions or function calls from LIGO test contracts. Consider: - +What's going on here? + +We have a function which takes no arguments and returns a `unit result`. +We then define two variables: +- a `program` which is read from disk and fed to the LIGO compiler +- a comparison function `make_expect` which takes an integer and adds one to it + +Using `expect_eq_n_int` the `program`'s main function is run and compared to the result of the same input provided to `make_expect`. Notice that the `main` argument given to `expect_eq_n_int` corresponds to the name of the function in `assign.ligo`. + +This gives us a taste of what to expect from these integration tests. + ### Annotation Test - let annotation () : unit result = - let%bind program = type_file "./contracts/annotation.ligo" in - let%bind () = - expect_eq_evaluate program "lst" (e_list []) - in - let%bind () = - expect_eq_evaluate program "address" (e_address "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") - in - let%bind () = - expect_eq_evaluate program "address_2" (e_address "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") - in - ok () + +We can see in more complex tests that we're able to pull the values of arbitrary expressions or function calls from LIGO test contracts. Consider: -### annotation.ligo - const lst : list(int) = list [] ; + let annotation () : unit result = + let%bind program = type_file "./contracts/annotation.ligo" in + let%bind () = + expect_eq_evaluate program "lst" (e_list []) + in + let%bind () = + expect_eq_evaluate program "address" (e_address "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") + in + let%bind () = + expect_eq_evaluate program "address_2" (e_address "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") + in + ok () + +#### annotation.ligo + const lst : list(int) = list [] ; - const address : address = "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; + const address : address = "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; - const address_2 : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) ; + const address_2 : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) ; -Here what's going on is similar to the last program; `expect_eq_evaluate` runs a program and then pulls a particular named value from the final program state. For example, once the program stops running the value of `address` is `"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"`. The *comparison* however is made to a constructed expression. Remember that we're testing from OCaml, but the program is written and evaluated as LIGO. In order to provide a proper comparison, we convert our expected test values into LIGO expressions and data. Constructors such as `e_list` and `e_address` provide a bridge between LIGO and OCaml. Their definitions can be found in files such as [src/stages/ast_simplified/combinators.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/stages/ast_simplified/combinators.ml), or using [Merlin's definition point finder](https://github.com/ocaml/merlin/wiki). These same functions are used during the simplification stage of LIGO compilation, so becoming familiar with them will help prepare you to work on the [front end](contributors/big-picture/front-end/). +What's going on is similar to the last program: `expect_eq_evaluate` runs a program and then pulls a particular named value from the final program state. + +For example, once the program stops running the value of `address` is `"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"`. The *comparison*, however, is made to a constructed expression. + +Remember that we're testing from OCaml, but the program is written and evaluated as LIGO. In order to provide a proper comparison, we convert our expected test values into LIGO expressions and data. Constructors such as `e_list` and `e_address` provide a bridge between LIGO and OCaml. Their definitions can be found in files such as [src/stages/ast_simplified/combinators.ml](https://gitlab.com/ligolang/ligo/blob/dev/src/stages/ast_simplified/combinators.ml), or using [Merlin's definition point finder](https://github.com/ocaml/merlin/wiki). These same functions are used during the simplification stage of LIGO compilation, so becoming familiar with them will help prepare you to work on the [front end](contributors/big-picture/front-end/). ## How To Write A Test For LIGO diff --git a/gitlab-pages/docs/contributors/origin.md b/gitlab-pages/docs/contributors/origin.md index aba239b67..9c8df5900 100644 --- a/gitlab-pages/docs/contributors/origin.md +++ b/gitlab-pages/docs/contributors/origin.md @@ -3,8 +3,8 @@ id: origin title: Origin --- -LIGO is a programming language that aims to provide developers with an uncomplicated and safer way to implement smart-contracts. LIGO is currently being implemented for the Tezos blockchain and as a result, it compiles down to Michelson - the native smart-contract language of Tezos. +LIGO is a programming language that aims to provide developers with an uncomplicated and safe way to implement smart-contracts. Since it is being implemented for the Tezos blockchain LIGO compiles to Michelson—the native smart-contract language of Tezos. > Smart-contracts are programs that run within a blockchain network. -LIGO was initially meant to be a language for developing Marigold, on top of a hacky framework called Meta-Michelson. However, due to the attention received by the Tezos community, a decision has been put into action to develop LIGO as a standalone language that will support Tezos directly as well. \ No newline at end of file +LIGO was meant to be a language for developing Marigold on top of a hacky framework called Meta-Michelson. However, due to the attention received by the Tezos community, LIGO is now a standalone language being developed to support Tezos directly. \ No newline at end of file diff --git a/gitlab-pages/docs/contributors/philosophy.md b/gitlab-pages/docs/contributors/philosophy.md index 25804ad04..0af6e606b 100644 --- a/gitlab-pages/docs/contributors/philosophy.md +++ b/gitlab-pages/docs/contributors/philosophy.md @@ -3,23 +3,22 @@ id: philosophy title: Philosophy --- -To understand LIGO’s design choices, it’s important to get its philosophy. There are two main concerns that we have in mind when building LIGO. - - +To understand LIGO’s design choices it’s important to understand its philosophy. We have two main concerns in mind while building LIGO. ## Safety Once a smart-contract is deployed, it will likely be impossible to change it. You must get it right on the first try, and LIGO should help as much as possible. There are multiple ways to make LIGO a safer language for smart-contracts. ### Automated Testing -Automated Testing is the process through which a program will run some other program, and check that this other program behaves correctly. +Automated Testing is the process through which a program runs another program, and checks that this other program behaves correctly. + There already is a testing library for LIGO programs written in OCaml that is used to test LIGO itself. Making it accessible to users will greatly improve safety. A way to do so would be to make it accessible from within LIGO. ### Static Analysis Static analysis is the process of having a program analyze another one. -For instance, type systems are a kind of static analysis through which it is possible to find lots of bugs. There is already a fairly simple type system in LIGO, and we plan to make it much stronger. +For instance, type systems are a kind of static analysis through which it is possible to find lots of bugs. LIGO already has a simple type system, and we plan to make it much stronger. ### Conciseness -Writing less code gives you less room to introduce errors and that's why LIGO encourages writing lean rather than chunky smart-contracts. +Writing less code gives you less room to introduce errors. That's why LIGO encourages writing lean rather than chunky smart-contracts. --- diff --git a/gitlab-pages/docs/intro/editor-support.md b/gitlab-pages/docs/intro/editor-support.md new file mode 100644 index 000000000..488ce0382 --- /dev/null +++ b/gitlab-pages/docs/intro/editor-support.md @@ -0,0 +1,12 @@ +--- +id: editor-support +title: Editor Support +--- + +Painters need a brush and a canvas. Developers need a good IDE experience. LIGO currently offers support for [VSCode](https://code.visualstudio.com), including syntax highlighting and on-the-fly compilation error reporting. + +Available extensions: +- **[Syntax highlighting for PascaLIGO](https://marketplace.visualstudio.com/items?itemName=LigoLang.pascaligo-vscode)** +- **[On-the-fly compilation error reporting](https://marketplace.visualstudio.com/items?itemName=Ligo.ligo-tools)** + +![error reporting](/img/docs/intro/editor-support/error-reporting.png) \ No newline at end of file diff --git a/gitlab-pages/docs/setup/installation.md b/gitlab-pages/docs/intro/installation.md similarity index 62% rename from gitlab-pages/docs/setup/installation.md rename to gitlab-pages/docs/intro/installation.md index 280fd144f..cd45491ab 100644 --- a/gitlab-pages/docs/setup/installation.md +++ b/gitlab-pages/docs/intro/installation.md @@ -3,19 +3,20 @@ id: installation title: Installation --- -There are currently two ways to get started with Ligo. You can choose to either use a Docker image, or to install packages for your Debian Linux distribution. +There are currently two ways to get started with Ligo. You can choose to use a Docker image, or to install packages for your Debian Linux distribution. ## Dockerized installation (recommended) > 🐳 You can find instructions on how to install Docker [here](https://docs.docker.com/install/). -It's easiest to use LIGO through one of its Docker images. You have two options, -the first is to use our installation script to set up a globally available LIGO -executable (see below). This manages the Docker bits for you. The second -is to directly use the Docker image available at [Docker Hub](https://hub.docker.com/r/ligolang/ligo). +It's easiest to use LIGO through one of its Docker images. You have two options: +* Use our installation script to set up a globally available LIGO +executable (see below). This manages the Docker bits for you. +* Use the Docker image available at [Docker Hub](https://hub.docker.com/r/ligolang/ligo). This lets you run multiple versions and keep your installation(s) self contained, but requires more familiarity with Docker. + Sources for the image can be found on [Gitlab](https://gitlab.com/ligolang/ligo/blob/master/docker/Dockerfile). -If this is your first time using Docker, you probably want to set up a global ligo executable as shown below. +If this is your first time using Docker, you probably want to set up a global LIGO executable as shown below. ### Setting up a globally available `ligo` executable @@ -42,10 +43,18 @@ ligo --help ## Debian Linux package installation -We have produced .deb packages for a few Debian Linuxes. They will install a global `ligo` executable. You can install them in the usual way. +We have produced .deb packages for a few Debian Linux versions. They will install a global `ligo` executable. +First download one of the packages below, and then install using: + +``` +sudo apt install ./.deb +``` - [Ubuntu 18.04](/deb/ligo_ubuntu-18.04.deb) - [Ubuntu 19.04](/deb/ligo_ubuntu-19.04.deb) - [Debian 9](/deb/ligo_debian-9.deb) - [Debian 10](/deb/ligo_debian-10.deb) +## Release schedule + +Important: LIGO is currently being released on a rolling release schedule. This means that you always get the latest development features. You can find our [rolling builds at the CI](https://gitlab.com/ligolang/ligo/pipelines). diff --git a/gitlab-pages/docs/intro/src/what-and-why/counter.js b/gitlab-pages/docs/intro/src/what-and-why/counter.js new file mode 100644 index 000000000..dfad8569e --- /dev/null +++ b/gitlab-pages/docs/intro/src/what-and-why/counter.js @@ -0,0 +1,15 @@ +var storage = 0; + +function add(a) { + storage += a +} + +function sub(a) { + storage -= a +} + +// We're calling this function reset instead of default +// because `default` is a javascript keyword +function reset() { + storage = 0; +} \ No newline at end of file diff --git a/gitlab-pages/docs/intro/src/what-and-why/counter.tz b/gitlab-pages/docs/intro/src/what-and-why/counter.tz new file mode 100644 index 000000000..73799f7c8 --- /dev/null +++ b/gitlab-pages/docs/intro/src/what-and-why/counter.tz @@ -0,0 +1,7 @@ +{ parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; + storage int ; + code { AMOUNT ; PUSH mutez 0 ; ASSERT_CMPEQ ; UNPAIR ; + IF_LEFT + { IF_LEFT { ADD } { SWAP ; SUB } } + { DROP ; DROP ; PUSH int 0 } ; + NIL operation ; PAIR } } \ No newline at end of file diff --git a/gitlab-pages/docs/intro/src/what-and-why/ligo-counter.ligo b/gitlab-pages/docs/intro/src/what-and-why/ligo-counter.ligo new file mode 100644 index 000000000..989afba07 --- /dev/null +++ b/gitlab-pages/docs/intro/src/what-and-why/ligo-counter.ligo @@ -0,0 +1,12 @@ +type action is +| Increment of int +| Decrement of int +| Reset of unit + +function main (const p : action ; const s : int) : (list(operation) * int) is + block { skip } with ((nil : list(operation)), + case p of + | Increment(n) -> s + n + | Decrement(n) -> s - n + | Reset(n) -> 0 + end) \ No newline at end of file diff --git a/gitlab-pages/docs/intro/src/what-and-why/ligo-counter.tz b/gitlab-pages/docs/intro/src/what-and-why/ligo-counter.tz new file mode 100644 index 000000000..2c5e6dbc2 --- /dev/null +++ b/gitlab-pages/docs/intro/src/what-and-why/ligo-counter.tz @@ -0,0 +1,41 @@ +{ parameter (or (or int int) unit) ; + storage int ; + code { DUP ; + CAR ; + DIP { DUP } ; + SWAP ; + CDR ; + DIP { DUP } ; + SWAP ; + IF_LEFT + { DUP ; + IF_LEFT + { DUP ; + DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; + SWAP ; + DIP { DUP } ; + SUB ; + SWAP ; + DROP ; + SWAP ; + DROP } + { DUP ; + DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; + SWAP ; + DIP { DUP } ; + ADD ; + SWAP ; + DROP ; + SWAP ; + DROP } ; + SWAP ; + DROP } + { DROP ; PUSH int 0 } ; + NIL operation ; + PAIR ; + SWAP ; + DROP ; + SWAP ; + DROP ; + SWAP ; + DROP } } \ No newline at end of file diff --git a/gitlab-pages/docs/intro/what-and-why.md b/gitlab-pages/docs/intro/what-and-why.md new file mode 100644 index 000000000..444822720 --- /dev/null +++ b/gitlab-pages/docs/intro/what-and-why.md @@ -0,0 +1,115 @@ +--- +id: what-and-why +title: What & Why +--- + +Before we get into what LIGO is and why LIGO needs to exist, let's take a look at what options the Tezos blockchain offers us out of the box. If you want to implement smart contracts natively on Tezos, you have to learn [Michelson](https://tezos.gitlab.io/whitedoc/michelson.html). + +> 💡 The (Michelson) language is stack-based, with high level data types and primitives and strict static type checking. + + +Here's an example of Michelson code: + +**`counter.tz`** +```text +{ parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; + storage int ; + code { AMOUNT ; PUSH mutez 0 ; ASSERT_CMPEQ ; UNPAIR ; + IF_LEFT + { IF_LEFT { ADD } { SWAP ; SUB } } + { DROP ; DROP ; PUSH int 0 } ; + NIL operation ; PAIR } } +``` + +The contract above maintains an `int` in its storage. It has two entrypoints *(functions)* `add` and `sub` to modify it, and the default *entrypoint* of type unit will reset it to 0. + +The contract itself contains three main parts: + +- `parameter` - Argument provided by a transaction invoking the contract +- `storage` - Type definition for the contract's data storage. +- `code` - Actual Michelson code that has the provided parameter & the current storage value in its initial stack. It outputs a pair of operations and a new storage value as its resulting stack. + +Michelson code consists of *instructions* like `IF_LEFT`, `PUSH ...`, `UNPAIR` that are bundled togeter in what is called a *sequence*. Stack represents an intermediate state of the program, while **storage represents a persistent state**. Instructions are used to modify the run-time stack in order to yield a desired stack value when the program terminates. + +> 💡 A Michelson program running on the Tezos blockchain is meant to output a pair of values including a `list of operations` to emit and a new `storage` value to persist + +## Differences between a stack and traditional variable management + +Stack management might be a little bit challanging, especially if you're coming from a *C-like language*. Let's implement a similar program in Javascript: + +**`counter.js`** +```javascript +var storage = 0; + +function add(a) { + storage += a +} + +function sub(a) { + storage -= a +} + +// We're calling this function reset instead of default +// because `default` is a javascript keyword +function reset() { + storage = 0; +} +``` + +In our javascript program the initial `storage` value is `0` and it can be modified by running the functions `add(a)`, `sub(a)` and `reset()`. + +Unfortunately (???), we **can't run Javascript on the Tezos blockchain** at the moment. But we can choose LIGO, which will abstract the stack management and allow us to create readable, type-safe, and efficient smart contracts. + +> 💡 You can try running the javascript program [here](https://codepen.io/maht0rz/pen/dyyvoPQ?editors=0012) + +## C-like smart contracts instead of Michelson + +Let's take a look at a similar LIGO program. Don't worry if it's a little confusing at first; we'll explain all the syntax in the upcoming sections of the documentation. + + + +```pascaligo +type action is +| Increment of int +| Decrement of int +| Reset of unit + +function main (const p : action ; const s : int) : (list(operation) * int) is + block { skip } with ((nil : list(operation)), + case p of + | Increment(n) -> s + n + | Decrement(n) -> s - n + | Reset(n) -> 0 + end) +``` + + + + +> 💡 You can find the Michelson compilation output of the contract above in **`ligo-counter.tz`** + +The LIGO contract behaves exactly* like the Michelson contract we've saw first, and it accepts the following LIGO expressions/values: `Increment(n)`, `Decrement(n)` and `Reset(n)`. Those serve as `entrypoint` identification, same as `%add` `%sub` or `%default` in the Michelson contract. + +**not exactly, the Michelson contract also checks if the `AMOUNT` sent is `0`* + +--- + +## Runnable code snippets & exercises + +Some of the sections in this documentation will include runnable code snippets and exercises. Sources for those are available at +the [LIGO Gitlab repository](https://gitlab.com/ligolang/ligo). + +### Snippets +For example **code snippets** for the *Types* subsection of this doc, can be found here: +`gitlab-pages/docs/language-basics/src/types/**` + +### Exercises +Solutions to exercises can be found e.g. here: `gitlab-pages/docs/language-basics/exercises/types/**/solutions/**` + +### Running snippets / excercise solutions +In certain cases it makes sense to be able to run/evaluate the given snippet or a solution, usually there'll be an example command which you can use, such as: + +```shell +ligo evaluate-value -s pascaligo gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo age +# Outputs: 25 +``` \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/boolean-if-else.md b/gitlab-pages/docs/language-basics/boolean-if-else.md new file mode 100644 index 000000000..fd4384c29 --- /dev/null +++ b/gitlab-pages/docs/language-basics/boolean-if-else.md @@ -0,0 +1,153 @@ +--- +id: boolean-if-else +title: Boolean, If, Else +--- + +## Boolean + +The type of a Boolean is `bool` and the possible values are `True` and `False`. + +Here's how to define a boolean: + + + +```pascaligo +const a: bool = True; +const b: bool = False; +``` + +```cameligo +let a: bool = true +let b: bool = false +``` + + + +## Comparing two values + +In LIGO, only values of the same type can be compared. We call these "comparable types." Comparable types include e.g. `int`, `nat`, `string`, `tez`, `timestamp`, `address`, ... + +### Comparing strings + + + +```pascaligo +const a: string = "Alice"; +const b: string = "Alice"; +// True +const c: bool = (a = b); +``` + +```cameligo +let a: string = "Alice" +let b: string = "Alice" +// true +let c: bool = (a = b) +``` + + + +### Comparing numbers + + + +```pascaligo +const a: int = 5; +const b: int = 4; +const c: bool = (a = b); +const d: bool = (a > b); +const e: bool = (a < b); +const f: bool = (a <= b); +const g: bool = (a >= b); +const h: bool = (a =/= b); +``` + +```cameligo +let a: int = 5 +let b: int = 4 +let c: bool = (a = b) +let d: bool = (a > b) +let e: bool = (a < b) +let f: bool = (a <= b) +let g: bool = (a >= b) +let h: bool = (a =/= b) +``` + + + +### Comparing tez + +> 💡 Comparing `tez` values is especially useful when dealing with an `amount` sent in a transaction. + + + +```pascaligo +const a: tez = 5mtz; +const b: tez = 10mtz; +const c: bool = (a = b); +``` + +```cameligo +let a: tez = 5mtz +let b: tez = 10mtz +// false +let c: bool = (a = b) +``` + + + +## Conditionals, if staments, and more + +Conditional logic is an important part of every real world program. + +### If/else statements + + + +```pascaligo +const min_age: nat = 16n; + +(* + This function is really obnoxious, but it showcases + how the if statement and it's syntax can be used. + + Normally, you'd use `with (age > min_age)` instead. +*) +function is_adult(const age: nat): bool is + block { + var is_adult: bool := False; + if (age > min_age) then begin + is_adult := True; + end else begin + is_adult := False; + end + } with is_adult +``` + +> You can run the function above with +> ``` +> ligo run-function -s pascaligo src/if-else.ligo is_adult 21n +> ``` + + +```cameligo +let min_age: nat = 16n + +(** + + This function is really obnoxious, but it showcases + how the if statement and it's syntax can be used. + + Normally, you'd use `with (age > min_age)` instead. + +*) +let is_adult (age: nat) : bool = + if (age > min_age) then true else false +``` + +> You can run the function above with +> ``` +> ligo run-function -s cameligo src/if-else.mligo is_adult 21n +> ``` + + \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/cheat-sheet.md b/gitlab-pages/docs/language-basics/cheat-sheet.md index a93cd6efd..db7035b9d 100644 --- a/gitlab-pages/docs/language-basics/cheat-sheet.md +++ b/gitlab-pages/docs/language-basics/cheat-sheet.md @@ -38,7 +38,7 @@ title: Cheat Sheet |Maps|
type prices is map(nat, tez);

const prices : prices = map
  10n -> 60mutez;
  50n -> 30mutez;
  100n -> 10mutez;
end

const price: option(tez) = prices[50n];

prices[200n] := 5mutez;
| |Contracts & Accounts|
const destinationAddress : address = "tz1...";
const contract : contract(unit) = get_contract(destinationAddress);
| |Transactions|
const payment : operation = transaction(unit, amount, receiver);
| -|Exception/Failure|`fail("Your descriptive error message for the user goes here.")`| +|Exception/Failure|`failwith("Your descriptive error message for the user goes here.")`| diff --git a/gitlab-pages/docs/language-basics/entrypoints.md b/gitlab-pages/docs/language-basics/entrypoints.md index 30ba46b65..fca89e7db 100644 --- a/gitlab-pages/docs/language-basics/entrypoints.md +++ b/gitlab-pages/docs/language-basics/entrypoints.md @@ -3,13 +3,13 @@ id: entrypoints title: Entrypoints --- -Entrypoints serve as a gate to our smart contracts. In LIGO each entrypoint is a function that accepts two arguments - first one is the parameter used to invoke the contract, and the second is the current storage of the contract. Each entrypoint has to return a list of operations to apply as a result of the smart contract call, and a new storage value. +Entrypoints are the gates to a smart contract. In LIGO each entrypoint is a function that accepts two arguments. The first is the parameter used to invoke the contract, and the second is the current storage of the contract. Each entrypoint must return a list of operations to apply as a result of the smart contract call, and a new storage value. > If you don't want to update the storage, don't worry, just re-cycle your last storage value. ## Defining an entry point -Contract below is effectively an empty contract, that takes a `unit` as a parameter, and returns a `unit` as well. +The contract below is effectively an empty contract. It takes a `unit` as a parameter, and returns a `unit`. @@ -21,7 +21,7 @@ function main (const p : unit ; const s : unit) : (list(operation) * unit) is ## Multiple entry points -Multiple entrypoints are currently not supported in Michelson yet, however with Ligo, you can work that around by using variants & pattern matching. +Multiple entrypoints are currently not supported in Michelson. But with Ligo you can work around that by using variants & pattern matching. In the example below we have a simple counter contract, that can be either `Increment(int)`-ed, or `Decrement(int)`-ed. diff --git a/gitlab-pages/docs/language-basics/functions.md b/gitlab-pages/docs/language-basics/functions.md index 15574aea0..f19c96ad4 100644 --- a/gitlab-pages/docs/language-basics/functions.md +++ b/gitlab-pages/docs/language-basics/functions.md @@ -3,41 +3,65 @@ id: functions title: Functions --- -## Defining a function +Writing code is fun as long as it doesn't get out of hand. To make sure our code doesn't turn into spaghetti we can group some logic into functions. -Body of a function consists of two parts, the first part (**`block {}`** or **`begin ... end`**) - normally consists of logic *(flow conditions, variable declarations, etc.)*, and the second part (**`with ...`**) usually defines the return value of your function. +## Instruction blocks + +With `block`(s) you can wrap *instructions* and *expressions* into an isolated scope. +Each `block` needs to include at least one `instruction`, or a *placeholder* instruction called `skip`. + ```pascaligo -const availableSupply: nat = 15n; -const totalSupply: nat = 100n; - -function calculatePrice(const available: nat; const total: nat): nat is - begin - const price: nat = total / available - end with price - -const price: nat = calculatePrice(availableSupply, totalSupply); +// shorthand syntax +block { skip } +// verbose syntax +begin + skip +end ``` +## Defining a function -### Functions without an explicit body (shorter syntax) - -A short hand syntax for the same function as above can inline the price calculation directly into the return statement. -While this approach can have it's benefits, it can decrease readability. + +Functions in PascaLIGO are defined using the `function` keyword followed by their `name`, `parameters` and `return` type definitions. + +Here's how you define a basic function that accepts two `ints` and returns a single `int`: + + ```pascaligo -const availableSupply: nat = 15n; -const totalSupply: nat = 100n; - -function calculatePrice(const available: nat; const total: nat): nat is - block { skip } with total / available - -const price: nat = calculatePrice(availableSupply, totalSupply); +function add(const a: int; const b: int): int is + block { skip } with a + b ``` - \ No newline at end of file +The function body consists of two parts: + +- `block {}` - logic of the function +- `with ` - the return value of the function + +> 💡 `skip` can be used as a placeholder for empty function blocks, when all the neccessary logic fits into `with` at the end. It is also possible to omit `block { skip } with` +in the above example, leaving only `a + b`. + + + + +Functions in CameLIGO are defined using the `let` keyword, like value bindings. +The difference is that after the value name a list of function parameters is provided, +along with a return type. + +Here's how you define a basic function that accepts two `ints` and returns an `int` as well: + +```cameligo +let add (a: int) (b: int) : int = a + b +``` + +The function body is a series of expressions, which are evaluated to give the return +value. + + + diff --git a/gitlab-pages/docs/language-basics/maps-records.md b/gitlab-pages/docs/language-basics/maps-records.md new file mode 100644 index 000000000..b81dfd8c7 --- /dev/null +++ b/gitlab-pages/docs/language-basics/maps-records.md @@ -0,0 +1,157 @@ +--- +id: maps-records +title: Maps, Records +--- + +So far we've seen pretty basic data types. LIGO also offers more complex built-in constructs, such as Maps and Records. + +## Maps + +Maps are natively available in Michelson, and LIGO builds on top of them. A requirement for a Map is that its keys be of the same type, and that type must be comparable. + +Here's how a custom map type is defined: + + + +```pascaligo +type ledger is map(address, tez); +``` + + +```cameligo +type ledger = (address, tez) map +``` + + + +And here's how a map value is populated: + + + + +```pascaligo +const ledger: ledger = map + ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> 1000mtz; + ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) -> 2000mtz; +end +``` +> Notice the `->` between the key and its value and `;` to separate individual map entries. +> +> `("": address)` means that we type-cast a string into an address. + + + +```cameligo +let ledger: ledger = Map.literal + [ (("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), 1000mtz) ; + (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), 2000mtz) ; + ] +``` +> Map.literal constructs the map from a list of key-value pair tuples, `(, )`. +> Note also the `;` to separate individual map entries. +> +> `("": address)` means that we type-cast a string into an address. + + +### Accessing map values by key + +If we want to access a balance from our ledger above, we can use the `[]` operator/accessor to read the associated `tez` value. However, the value we'll get will be wrapped as an optional; in our case `option(tez)`. Here's an example: + + + +```pascaligo +const balance: option(tez) = ledger[("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)]; +``` + + + +```cameligo +let balance: tez option = Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) ledger +``` + + +#### Obtaining a map value forcefully + +Accessing a value in a map yields an option, however you can also get the value directly: + + + +```pascaligo +const balance: tez = get_force(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), ledger); +``` + + + +```cameligo +let balance: tez = Map.find ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) ledger +``` + + + +## Records + +Records are a construct introduced in LIGO, and are not natively available in Michelson. The LIGO compiler translates records into Michelson `Pairs`. + +Here's how a custom record type is defined: + + + +```pascaligo +type user is record + id: nat; + is_admin: bool; + name: string; +end +``` + + +```cameligo +type user = { + id: nat; + is_admin: bool; + name: string; +} +``` + + + +And here's how a record value is populated: + + + +```pascaligo +const user: user = record + id = 1n; + is_admin = True; + name = "Alice"; +end +``` + + +```cameligo +let user: user = { + id = 1n; + is_admin = true; + name = "Alice"; +} +``` + + + + +### Accessing record keys by name + +If we want to obtain a value from a record for a given key, we can do the following: + + + +```pascaligo +const is_admin: bool = user.is_admin; +``` + + +```cameligo +let is_admin: bool = user.is_admin +``` + + diff --git a/gitlab-pages/docs/language-basics/math-numbers-tez.md b/gitlab-pages/docs/language-basics/math-numbers-tez.md new file mode 100644 index 000000000..83a591ecd --- /dev/null +++ b/gitlab-pages/docs/language-basics/math-numbers-tez.md @@ -0,0 +1,154 @@ +--- +id: math-numbers-tez +title: Math, Numbers & Tez +--- + +LIGO offers three built-in numerical types: `int`, `nat` and `tez`. + +## Addition + +Addition in ligo is acomplished by using the `+` operator. Some type constraints apply; for example you can't add `tez + nat`. + +In the following example you can find a series of arithmetic operations, including various numerical types. However, some bits of the example won't compile because adding an `int` to a `nat` produces an `int`, not a `nat`. Similiar rules apply for `tez`: + + + + +```pascaligo +// int + int produces int +const a: int = 5 + 10; +// nat + int produces int +const b: int = 5n + 10; +// tez + tez produces tez +const c: tez = 5mutez + 10mutez; +// you can't add tez + int or tez + nat, this won't compile +// const d: tez = 5mutez + 10n; +// two nats produce a nat +const e: nat = 5n + 10n; +// nat + int produces an int, this won't compile +// const f: nat = 5n + 10; +const g: int = 1_000_000; +``` + +> Pro tip: you can use underscores for readability when defining large numbers +> +>```pascaligo +>const g: int = 1_000_000; +>``` + + + +```cameligo +// int + int produces int +let a: int = 5 + 10 +// nat + int produces int +let b: int = 5n + 10 +// tez + tez produces tez +let c: tez = 5mutez + 10mutez +// you can't add tez + int or tez + nat, this won't compile +// const d: tez = 5mutez + 10n +// two nats produce a nat +let e: nat = 5n + 10n +// nat + int produces an int, this won't compile +// const f: nat = 5n + 10 +let g: int = 1_000_000 +``` + +> Pro tip: you can use underscores for readability when defining large numbers +> +>```cameligo +>let g: int = 1_000_000; +>``` + + + +## Subtraction + +The simpliest substraction looks like this: + +> ⚠️ Even when subtracting two `nats`, the result is an `int` + + + +```pascaligo +const a: int = 5 - 10; +// substraction of two nats, yields an int +const b: int = 5n - 2n; +// won't compile, result is an int, not a nat +// const c: nat = 5n - 2n; +const d: tez = 5mutez - 1mt; +``` + + +```cameligo +let a: int = 5 - 10 +// substraction of two nats, yields an int +let b: int = 5n - 2n +// won't compile, result is an int, not a nat +// const c: nat = 5n - 2n +let d: tez = 5mutez - 1mt +``` + + + + +## Multiplication + +You can multiply values of the same type, such as: + + + + +```pascaligo +const a: int = 5 * 5; +const b: nat = 5n * 5n; +// you can also multiply `nat` and `tez` +const c: tez = 5n * 5mutez; +``` + + +```cameligo +let a: int = 5 * 5 +let b: nat = 5n * 5n +// you can also multiply `nat` and `tez` +let c: tez = 5n * 5mutez +``` + + + + +## Division + +In LIGO you can divide `int`, `nat`, and `tez`. Here's how: + +> ⚠️ Division of two `tez` values results into a `nat` + + + +```pascaligo +const a: int = 10 / 3; +const b: nat = 10n / 3n; +const c: nat = 10mutez / 3mutez; +``` + + +```cameligo +let a: int = 10 / 3 +let b: nat = 10n / 3n +let c: nat = 10mutez / 3mutez +``` + + + +## From `int` to `nat` and back + +You can *cast* an `int` to a `nat` and vice versa, here's how: + + + +```pascaligo +const a: int = int(1n); +const b: nat = abs(1); +``` + + \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/operators.md b/gitlab-pages/docs/language-basics/operators.md index 9403a0d92..fc988c658 100644 --- a/gitlab-pages/docs/language-basics/operators.md +++ b/gitlab-pages/docs/language-basics/operators.md @@ -5,7 +5,7 @@ title: Operators ## Available operators -> This list is non-exhaustive, more operators will be added in the upcoming LIGO releases. +> This list is non-exhaustive. More operators will be added in upcoming LIGO releases. |Michelson |Pascaligo |Description | |--- |--- |--- | diff --git a/gitlab-pages/docs/language-basics/sets-lists-touples.md b/gitlab-pages/docs/language-basics/sets-lists-touples.md new file mode 100644 index 000000000..ec1bfa43f --- /dev/null +++ b/gitlab-pages/docs/language-basics/sets-lists-touples.md @@ -0,0 +1,240 @@ +--- +id: sets-lists-touples +title: Sets, Lists, Tuples +--- + +Apart from complex data types such as `maps` and `records`, ligo also exposes `sets`, `lists` and `tuples`. + +> ⚠️ Make sure to pick the appropriate data type for your use case; it carries not only semantic but also gas related costs. + +## Sets + +Sets are similar to lists. The main difference is that elements of a `set` must be *unique*. + +### Defining a set + + + +```pascaligo +type int_set is set(int); +const my_set: int_set = set + 1; + 2; + 3; +end +``` + + +```cameligo +type int_set = int set +let my_set: int_set = + Set.add 3 (Set.add 2 (Set.add 1 Set.empty)) +``` + + + +### Empty sets + + + +```pascaligo +const my_set: int_set = set end; +const my_set_2: int_set = set_empty; +``` + + + + +### Checking if set contains an element + + + +```pascaligo +const contains_three: bool = my_set contains 3; +// or alternatively +const contains_three_fn: bool = set_mem(3, my_set); +``` + + +```cameligo +let contains_three: bool = Set.mem 3 my_set +``` + + + + +### Obtaining the size of a set + + +```pascaligo +const set_size: nat = size(my_set); +``` + + +```cameligo +let set_size: nat = Set.size my_set +``` + + + + +### Modifying a set + + +```pascaligo +const larger_set: int_set = set_add(4, my_set); +const smaller_set: int_set = set_remove(3, my_set); +``` + + + +```cameligo +let larger_set: int_set = Set.add 4 my_set +let smaller_set: int_set = Set.remove 3 my_set +``` + + + + +### Folding a set + + +```pascaligo +function sum(const result: int; const i: int): int is result + i; +// Outputs 6 +const sum_of_a_set: int = set_fold(my_set, 0, sum); +``` + + +```cameligo +let sum (result: int) (i: int) : int = result + i +let sum_of_a_set: int = Set.fold my_set 0 sum +``` + + + +## Lists + +Lists are similar to sets, but their elements don't need to be unique and they don't offer the same range of built-in functions. + +> 💡 Lists are useful when returning operations from a smart contract's entrypoint. + +### Defining a list + + + +```pascaligo +type int_list is list(int); +const my_list: int_list = list + 1; + 2; + 3; +end +``` + + +```cameligo +type int_list = int list +let my_list: int_list = [1; 2; 3] +``` + + + + +### Appending an element to a list + + + +```pascaligo +const larger_list: int_list = cons(4, my_list); +const even_larger_list: int_list = 5 # larger_list; +``` + + +```cameligo +let larger_list: int_list = 4 :: my_list +(* CameLIGO doesn't have a List.cons *) +``` + + + +
+> 💡 Lists can be iterated, folded or mapped to different values. You can find additional examples [here](https://gitlab.com/ligolang/ligo/tree/dev/src/test/contracts) and other built-in operators [here](https://gitlab.com/ligolang/ligo/blob/dev/src/passes/operators/operators.ml#L59) + +### Mapping of a list + + + +```pascaligo +function increment(const i: int): int is block { skip } with i + 1; +// Creates a new list with elements incremented by 1 +const incremented_list: int_list = list_map(even_larger_list, increment); +``` + + + +```cameligo +let increment (i: int) : int = i + 1 +(* Creates a new list with elements incremented by 1 *) +let incremented_list: int_list = List.map larger_list increment +``` + + + + +### Folding of a list: + + +```pascaligo +function sum(const result: int; const i: int): int is block { skip } with result + i; +// Outputs 6 +const sum_of_a_list: int = list_fold(my_list, 0, sum); +``` + + + +```cameligo +let sum (result: int) (i: int) : int = result + i +// Outputs 6 +let sum_of_a_list: int = List.fold my_list 0 sum +``` + + + + +## Tuples + +Tuples are useful for data that belong together but don't have an index or a specific name. + +### Defining a tuple + + + +```pascaligo +type full_name is string * string; +const full_name: full_name = ("Alice", "Johnson"); +``` + + +```cameligo +type full_name = string * string +(* The parenthesis here are optional *) +let full_name: full_name = ("Alice", "Johnson") +``` + + + + +### Accessing an element in a tuple + + +```pascaligo +const first_name: string = full_name.1; +``` + + +```cameligo +let first_name: string = full_name.1 +``` + + \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/math-numbers-tez/addition.ligo b/gitlab-pages/docs/language-basics/src/math-numbers-tez/addition.ligo new file mode 100644 index 000000000..690b22836 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/math-numbers-tez/addition.ligo @@ -0,0 +1,13 @@ +// int + int produces int +const a: int = 5 + 10; +// nat + int produces int +const b: int = 5n + 10; +// tez + tez produces tez +const c: tez = 5mutez + 10mutez; +// you can't add tez + int or tez + nat, this won't compile +// const d: tez = 5mutez + 10n; +// two nats produce a nat +const e: nat = 5n + 10n; +// nat + int produces an int, this won't compile +// const f: nat = 5n + 10; +const g: int = 1_000_000; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/math-numbers-tez/casting.ligo b/gitlab-pages/docs/language-basics/src/math-numbers-tez/casting.ligo new file mode 100644 index 000000000..a0a5c9f83 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/math-numbers-tez/casting.ligo @@ -0,0 +1,2 @@ +const a: int = int(1n); +const b: nat = abs(1); \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/math-numbers-tez/division.ligo b/gitlab-pages/docs/language-basics/src/math-numbers-tez/division.ligo new file mode 100644 index 000000000..622235e3e --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/math-numbers-tez/division.ligo @@ -0,0 +1,5 @@ +const a: int = 10 / 3; +const b: nat = 10n / 3n; +const c: nat = 10mutez / 3mutez; + +const d: int = 10 / 5 / 2 * 5; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/math-numbers-tez/multiplication.ligo b/gitlab-pages/docs/language-basics/src/math-numbers-tez/multiplication.ligo new file mode 100644 index 000000000..95bdef4ab --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/math-numbers-tez/multiplication.ligo @@ -0,0 +1,3 @@ +const a: int = 5 * 5; +const b: nat = 5n * 5n; +const c: tez = 5n * 5mutez; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/math-numbers-tez/substraction.ligo b/gitlab-pages/docs/language-basics/src/math-numbers-tez/substraction.ligo new file mode 100644 index 000000000..cefcd4947 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/math-numbers-tez/substraction.ligo @@ -0,0 +1,6 @@ +const a: int = 5 - 10; +// substraction of two nats, yields an int +const b: int = 5n - 2n; +// won't compile, result is an int, not a nat +// const c: nat = 5n - 2n; +const d: tez = 5mutez - 1mutez; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/sets-lists-touples/empty-set.ligo b/gitlab-pages/docs/language-basics/src/sets-lists-touples/empty-set.ligo new file mode 100644 index 000000000..a836a3620 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/sets-lists-touples/empty-set.ligo @@ -0,0 +1,3 @@ +type int_set is set(int); +const my_set: int_set = set end; +const my_set_2: int_set = set_empty; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/strings/concat.ligo b/gitlab-pages/docs/language-basics/src/strings/concat.ligo new file mode 100644 index 000000000..7b80e8510 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/strings/concat.ligo @@ -0,0 +1 @@ +const a: string = string_concat("Hello ", "World"); \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/types/alias.ligo b/gitlab-pages/docs/language-basics/src/types/alias.ligo new file mode 100644 index 000000000..d0b6414e6 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/types/alias.ligo @@ -0,0 +1,2 @@ +type animalBreed is string; +const dogBreed : animalBreed = "Saluki"; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/types/composed-types.ligo b/gitlab-pages/docs/language-basics/src/types/composed-types.ligo new file mode 100644 index 000000000..3929e9de6 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/types/composed-types.ligo @@ -0,0 +1,19 @@ +// alias two types +type account is address; +type numberOfTransactions is nat; +// accountData consists of a record with two fields (balance, numberOfTransactions) +type accountData is record + balance: tez; + numberOfTransactions: numberOfTransactions; +end +// our ledger / accountBalances is a map of account <-> accountData +type accountBalances is map(account, accountData); + +// pseudo-JSON representation of our map +// { "tz1...": {balance: 10mutez, numberOfTransactions: 5n} } +const ledger: accountBalances = map + ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> record + balance = 10mutez; + numberOfTransactions = 5n; + end +end \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/types/simple-type.ligo b/gitlab-pages/docs/language-basics/src/types/simple-type.ligo new file mode 100644 index 000000000..be96bd52a --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/types/simple-type.ligo @@ -0,0 +1,6 @@ +// accountBalances is a simple type, a map of address <-> tez +type accountBalances is map(address, tez); + +const ledger: accountBalances = map + ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> 10mutez +end \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/variables-and-constants/add.ligo b/gitlab-pages/docs/language-basics/src/variables-and-constants/add.ligo new file mode 100644 index 000000000..148d7f2ee --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/variables-and-constants/add.ligo @@ -0,0 +1,7 @@ +// won't work, use const for global values instead +// var four: int = 4; + +function add(const a: int; const b: int) : int is + block { + var c : int := a + b; + } with c \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo b/gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo new file mode 100644 index 000000000..370037096 --- /dev/null +++ b/gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo @@ -0,0 +1 @@ +const age : int = 25; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/strings.md b/gitlab-pages/docs/language-basics/strings.md new file mode 100644 index 000000000..608fd64e8 --- /dev/null +++ b/gitlab-pages/docs/language-basics/strings.md @@ -0,0 +1,81 @@ +--- +id: strings +title: Strings +--- + + + +Strings are defined using the built-in `string` type like this: + + + +``` +const a: string = "Hello Alice"; +``` + +``` +let a: string = "Hello Alice" +``` + + + +## Concatenating strings + +Strings can be concatenated using the `^` operator. + + + +```pascaligo +const name: string = "Alice"; +const greeting: string = "Hello"; +// Hello Alice +const full_greeting: string = greeting ^ " " ^ name; +// Hello Alice! (alternatively) +const full_greeting_exclamation: string = string_concat(full_greeting, "!"); +``` + +```cameligo +let name: string = "Alice" +let greeting: string = "Hello" +let full_greeting: string = greeting ^ " " ^ name +``` + + + +## Slicing strings + +Strings can be sliced using the syntax specific built-in built-in function: + + + +```pascaligo +const name: string = "Alice"; +// slice = "A" +const slice: string = string_slice(0n, 1n, name); +``` + +```cameligo +let name: string = "Alice" +let slice: string = String.slice 0n 1n name +``` + + +> ⚠️ Notice that the `offset` and slice `length` are `nats` + +## Aquiring the length of a string + +The length of a string can be found using the syntax specific built-in function: + + + +```pascaligo +const name: string = "Alice"; +// length = 5 +const length: nat = size(name); +``` + +```cameligo +let name: string = "Alice" +let length: nat = String.size name +``` + \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/types.md b/gitlab-pages/docs/language-basics/types.md index 501f77544..614e4b11b 100644 --- a/gitlab-pages/docs/language-basics/types.md +++ b/gitlab-pages/docs/language-basics/types.md @@ -3,27 +3,33 @@ id: types title: Types --- +LIGO is strongly and statically typed. This means that the compiler checks your program at compilation time and makes sure there won't be any type related runtime errors. LIGO types are built on top of Michelson's type system. + ## Built-in types -For the list of built-in types, please refer to the [Cheat Sheet](language-basics/cheat-sheet.md). LIGO's type system is built on top of Michelson, but offers a handful of features like type aliasing, or groupping of multiple types into a single powerful type. +For quick referrence, you can find all the built-in types [here](https://gitlab.com/ligolang/ligo/blob/dev/src/passes/operators/operators.ml#L35). ## Type aliases -Type aliasing is a great choice when working towards a readable / maintainable smart contract. One well typed variable is worth a thousand words. For example we can choose to *alias* a string, as an animal breed - this will allow us to comunicate our intent with added clarity. +Type aliasing is great for creating a readable / maintainable smart contract. One well typed type/variable is worth a thousand words. For example we can choose to *alias* a string as an animal breed - this will allow us to comunicate our intent with added clarity. ```pascaligo type animalBreed is string; +const dogBreed : animalBreed = "Saluki"; +``` -const dogBreed: animalBreed = "Saluki"; + + +```cameligo +type animal_breed = string +let dog_breed: animal_breed = "Saluki" ``` -## Defining custom types - -### Simple types +## Simple types ```pascaligo @@ -35,14 +41,22 @@ const ledger: accountBalances = map end ``` + +```cameligo +// account_balances is a simple type, a map of address <-> tez +type account_balances is (address, tez) map + +let ledger: account_balances = Map.literal + [(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), 10mutez)] +``` + +## Composed types -### Composed types +Often contracts require complex data structures, which in turn require well-typed storage or functions to work with. LIGO offers a simple way to compose simple types into larger & more expressive composed types. -Often our contracts will require complex data structures, which will in turn require a well-typed storage, or functions to work with. LIGO offers a simple way to compose simple types, into larger & more expressive composed types. - -In the example below you can see definition of data types for a ledger, that keeps a balance & number of previous transactions for a given account. +In the example below you can see the definition of data types for a ledger that keeps the balance and number of previous transactions for a given account. @@ -50,7 +64,6 @@ In the example below you can see definition of data types for a ledger, that kee // alias two types type account is address; type numberOfTransactions is nat; - // accountData consists of a record with two fields (balance, numberOfTransactions) type accountData is record balance: tez; @@ -59,7 +72,7 @@ end // our ledger / accountBalances is a map of account <-> accountData type accountBalances is map(account, accountData); -// pseudo-JSON representation of our map +// pseudo-JSON representation of our map // { "tz1...": {balance: 10mutez, numberOfTransactions: 5n} } const ledger: accountBalances = map ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> record @@ -69,4 +82,26 @@ const ledger: accountBalances = map end ``` - \ No newline at end of file + +```cameligo +(* alias two types *) +type account = address +type number_of_transactions = nat +(* account_data consists of a record with two fields (balance, number_of_transactions) *) +type account_data = { + balance: tez; + number_of_transactions: number_of_transactions; +} +(* our ledger / account_balances is a map of account <-> account_data *) +type account_balances = (account, account_data) map + +// pseudo-JSON representation of our map +// {"tz1...": {balance: 10mutez, number_of_transactions: 5n}} +let ledger: account_balances = Map.literal + [(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), + {balance = 10mutez; + number_of_transactions = 5n;} + )] +``` + + diff --git a/gitlab-pages/docs/language-basics/unit-option-pattern-matching.md b/gitlab-pages/docs/language-basics/unit-option-pattern-matching.md new file mode 100644 index 000000000..cbd7ddecc --- /dev/null +++ b/gitlab-pages/docs/language-basics/unit-option-pattern-matching.md @@ -0,0 +1,116 @@ +--- +id: unit-option-pattern-matching +title: Unit, Option, Pattern matching +--- + +Optionals are a programing pattern seen in OCaml. Since Michelson and LIGO are both inspired by OCaml, you'll have the *option* to use them in LIGO as well. + +## Type unit + +Units in Michelson or LIGO represent *for the lack of better words* - an empty/useless/not needed value. + +Here's how they're defined: + +> 💡 Units come in handy when we try pattern matching on custom variants below. + + + +```pascaligo +const n: unit = Unit; +``` + + +```cameligo +let n: unit = () +``` + + + +## Variants + +Variant is a user-defined or a built-in type (in case of optionals) that can be compared to Enum (from javascript). + +Here's how to define a new variant type: + + + +```pascaligo +type id is nat +type user is +| Admin of id +| Manager of id +| Guest; + +const u: user = Admin(1000n); +const g: user = Guest(Unit); +``` + + +```cameligo +type id = nat +type user = +| Admin of id +| Manager of id +| Guest of unit + +let u: user = Admin 1000n +let g: user = Guest () +``` + + + +Defining a varient can be extremely useful for building semantically appealing contracts. We'll learn how to use variants for 'logic purposes' shortly. + +## Optional values + +Optionals are a type of built-in variant that can be used to determine if a variable holds a certain value or not. This is especially useful when (for example) your program's state allows for a certain variable value to be empty, like this: + + + +```pascaligo +type dinner is option(string); + +// stay hungry +const p1: dinner = None; +// have some hamburgers +const p2: dinner = Some("Hamburgers") +``` + + +```cameligo +type dinner = string option + +let p1: dinner = None +let p2: dinner = Some "Hamburgers" +``` + + + + +## Pattern matching + +Pattern matching is very similiar to e.g. `switch` in Javascript, and can be used to re-route the program's flow based on a value of a variant. + + + +```pascaligo +type dinner is option(string); +function is_hungry(const dinner: dinner): bool is block { skip } + with ( + case dinner of + | None -> True + | Some(d) -> False + end + ) +``` + + +```cameligo +type dinner = string option +let is_hungry (d: dinner) : bool = + match d with + | None -> true + | Some s -> false +``` + + diff --git a/gitlab-pages/docs/language-basics/variables-and-constants.md b/gitlab-pages/docs/language-basics/variables-and-constants.md new file mode 100644 index 000000000..55bee7a64 --- /dev/null +++ b/gitlab-pages/docs/language-basics/variables-and-constants.md @@ -0,0 +1,88 @@ +--- +id: constants-and-variables +title: Constants & Variables +--- + +The next building block after types are constants and variables. + +## Constants + +Constants are immutable by design, which means their values can't be reassigned. +When defining a constant you need to provide a `name`, `type` and a `value`: + + + +```pascaligo +const age : int = 25; +``` + +You can evaluate the constant definition above using the following CLI command: +```shell +ligo evaluate-value -s pascaligo gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo age +# Outputs: 25 +``` + +```cameligo +let age: int = 25 +``` + +You can evaluate the constant definition above using the following CLI command: +```shell +ligo evaluate-value -s cameligo gitlab-pages/docs/language-basics/src/variables-and-constants/const.mligo age +# Outputs: 25 +``` + + + +## Variables + + + + +Variables, unlike constants, are mutable. They can't be used in a *global scope*, but they can be used within functions, or function arguments. + +> 💡 Don't worry if you don't understand the function syntax yet. We'll get to it in upcoming sections of the docs. + + +```pascaligo +// won't work, use const for global values instead +// var four: int = 4; + +function add(const a: int; const b: int) : int is + block { + var c : int := a + b; + } with c +``` + + +> ⚠️ Notice the different assignment operator `:=` + +You can run the `add` function defined above using the LIGO compiler like this: + +```shell +ligo run-function -s pascaligo gitlab-pages/docs/language-basics/src/variables-and-constants/add.ligo add '(1,1)' +# Outputs: 2 +``` + + + +As expected from a functional language, CameLIGO uses value-binding +for variables rather than assignment. Variables are changed by replacement, +with a new value being bound in place of the old one. + +> 💡 Don't worry if you don't understand the function syntax yet. We'll get to it in upcoming sections of the docs. + +```cameligo + +let add(const a: int; const b: int) : int = + let c : int = a + b in c +``` + +You can run the `add` function defined above using the LIGO compiler like this: + +```shell +ligo run-function -s cameligo gitlab-pages/docs/language-basics/src/variables-and-constants/add.mligo add '(1,1)' +# Outputs: 2 +``` + + diff --git a/gitlab-pages/docs/language-basics/variables.md b/gitlab-pages/docs/language-basics/variables.md deleted file mode 100644 index 4092a3eb9..000000000 --- a/gitlab-pages/docs/language-basics/variables.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -id: variables -title: Variables ---- - -## Defining a variable - -Variables in LIGO can be defined in two ways - by using either the `const` or `var` keywords. `const` can be used both at global (top-level) and local scope (within functions/blocks), while `var` can be used for mutable values in the local scope. - - -### Imutable variables using `const` - -> ⚠️ Currently const values are mutable as well, however this is something that will change in the upcoming release. For the time being think of `const` as a semantical way to indicate developer intentions. - - - -```Pascal -const four: int = 4; -``` - - - -### Mutable variables using `var` - -> ⚠️ `var` can't be used in the global scope - - - -```Pascal -// won't work, use const for global values instead -var four: int = 4; - -// value of `number` can be mutated within local scope -function addFour(var number: int): int is - block { - number := number + 4; - } with number; -``` - - \ No newline at end of file diff --git a/gitlab-pages/docs/setup/editor-support.md b/gitlab-pages/docs/setup/editor-support.md deleted file mode 100644 index 197e5b2bf..000000000 --- a/gitlab-pages/docs/setup/editor-support.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: editor-support -title: Editor Support ---- - -Good editor support is the basic component of proper development experience - currently, we provide support for VSCode via an [extension](https://marketplace.visualstudio.com/items?itemName=Brice.ligo). - -Currently the extension supports Pascaligo for syntax highlighting (work in progress). But it aims to support debug, gas optimization, dry run and other relevant features in the near future. \ No newline at end of file diff --git a/gitlab-pages/owner.pp.ligo b/gitlab-pages/owner.pp.ligo new file mode 100644 index 000000000..e69de29bb diff --git a/gitlab-pages/timestamp.pp.ligo b/gitlab-pages/timestamp.pp.ligo new file mode 100644 index 000000000..e69de29bb diff --git a/gitlab-pages/website/core/Footer.js b/gitlab-pages/website/core/Footer.js index 8153941f8..d5f79c25b 100644 --- a/gitlab-pages/website/core/Footer.js +++ b/gitlab-pages/website/core/Footer.js @@ -26,7 +26,6 @@ class Footer extends React.Component { ); diff --git a/gitlab-pages/website/package-lock.json b/gitlab-pages/website/package-lock.json index 064293c9d..aedc47552 100644 --- a/gitlab-pages/website/package-lock.json +++ b/gitlab-pages/website/package-lock.json @@ -12,18 +12,18 @@ } }, "@babel/core": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.2.tgz", - "integrity": "sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz", + "integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.4", "@babel/helpers": "^7.6.2", - "@babel/parser": "^7.6.2", + "@babel/parser": "^7.6.4", "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/traverse": "^7.6.3", + "@babel/types": "^7.6.3", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -34,12 +34,12 @@ } }, "@babel/generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", - "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -284,9 +284,9 @@ } }, "@babel/parser": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", - "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -445,9 +445,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz", - "integrity": "sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz", + "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -600,9 +600,9 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz", - "integrity": "sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.3.tgz", + "integrity": "sha512-jTkk7/uE6H2s5w6VlMHeWuH+Pcy2lmdwFoeWCVnvIrDUnB5gQqTVI8WfmEAhF2CDEarGrknZcmSFg1+bkfCoSw==", "dev": true, "requires": { "regexpu-core": "^4.6.0" @@ -774,9 +774,9 @@ } }, "@babel/preset-env": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.2.tgz", - "integrity": "sha512-Ru7+mfzy9M1/YTEtlDS8CD45jd22ngb9tXnn64DvQK3ooyqSw9K4K9DUWmYknTTVk4TqygL9dqCrZgm1HMea/Q==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.3.tgz", + "integrity": "sha512-CWQkn7EVnwzlOdR5NOm2+pfgSNEZmvGjOhlCHBDq0J8/EStr+G+FvPEiz9B56dR6MoiUFjXhfE4hjLoAKKJtIQ==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -795,7 +795,7 @@ "@babel/plugin-transform-arrow-functions": "^7.2.0", "@babel/plugin-transform-async-to-generator": "^7.5.0", "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.6.2", + "@babel/plugin-transform-block-scoping": "^7.6.3", "@babel/plugin-transform-classes": "^7.5.5", "@babel/plugin-transform-computed-properties": "^7.2.0", "@babel/plugin-transform-destructuring": "^7.6.0", @@ -810,7 +810,7 @@ "@babel/plugin-transform-modules-commonjs": "^7.6.0", "@babel/plugin-transform-modules-systemjs": "^7.5.0", "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.2", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.3", "@babel/plugin-transform-new-target": "^7.4.4", "@babel/plugin-transform-object-super": "^7.5.5", "@babel/plugin-transform-parameters": "^7.4.4", @@ -823,7 +823,7 @@ "@babel/plugin-transform-template-literals": "^7.4.4", "@babel/plugin-transform-typeof-symbol": "^7.2.0", "@babel/plugin-transform-unicode-regex": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/types": "^7.6.3", "browserslist": "^4.6.0", "core-js-compat": "^3.1.1", "invariant": "^2.2.2", @@ -832,9 +832,9 @@ } }, "@babel/preset-react": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", - "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.6.3.tgz", + "integrity": "sha512-07yQhmkZmRAfwREYIQgW0HEwMY9GBJVuPY4Q12UC72AbfaawuupVWa8zQs2tlL+yun45Nv/1KreII/0PLfEsgA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -869,26 +869,26 @@ } }, "@babel/traverse": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", - "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.2", + "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.2", - "@babel/types": "^7.6.0", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -928,9 +928,9 @@ } }, "@types/node": { - "version": "12.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.7.tgz", - "integrity": "sha512-4jUncNe2tj1nmrO/34PsRpZqYVnRV1svbU78cKhuQKkMntKB/AmdLyGgswcZKjFHEHGpiY8pVD8CuVI55nP54w==", + "version": "12.12.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", "dev": true }, "@types/q": { @@ -1010,9 +1010,9 @@ "dev": true }, "anymatch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.0.tgz", - "integrity": "sha512-Ozz7l4ixzI7Oxj2+cw+p0tVUt27BpaJ+1+q1TCeANWxHpvyn2+Un+YamBdfKu0uh8xLodGhoa1v7595NhKDAuA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -1130,10 +1130,13 @@ "dev": true }, "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } }, "async-each": { "version": "1.0.3", @@ -1163,18 +1166,18 @@ } }, "autoprefixer": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz", - "integrity": "sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==", + "version": "9.7.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.1.tgz", + "integrity": "sha512-w3b5y1PXWlhYulevrTJ0lizkQ5CyqfeU6BIRDbuhsMupstHQOeb1Ur80tcB1zxSu7AwyY/qCQ7Vvqklh31ZBFw==", "dev": true, "requires": { - "browserslist": "^4.6.3", - "caniuse-lite": "^1.0.30000980", + "browserslist": "^4.7.2", + "caniuse-lite": "^1.0.30001006", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.17", - "postcss-value-parser": "^4.0.0" + "postcss": "^7.0.21", + "postcss-value-parser": "^4.0.2" } }, "aws-sign2": { @@ -1664,14 +1667,14 @@ } }, "browserslist": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz", - "integrity": "sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.2.tgz", + "integrity": "sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000989", - "electron-to-chromium": "^1.3.247", - "node-releases": "^1.1.29" + "caniuse-lite": "^1.0.30001004", + "electron-to-chromium": "^1.3.295", + "node-releases": "^1.1.38" } }, "buffer": { @@ -1849,9 +1852,9 @@ } }, "caniuse-lite": { - "version": "1.0.30000997", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000997.tgz", - "integrity": "sha512-BQLFPIdj2ntgBNWp9Q64LGUIEmvhKkzzHhUHR3CD5A9Lb7ZKF20/+sgadhFap69lk5XmK1fTUleDclaRFvgVUA==", + "version": "1.0.30001006", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001006.tgz", + "integrity": "sha512-MXnUVX27aGs/QINz+QG1sWSLDr3P1A3Hq5EUWoIt0T7K24DuvMxZEnh3Y5aHlJW6Bz2aApJdSewdYLd8zQnUuw==", "dev": true }, "caseless": { @@ -1962,19 +1965,19 @@ } }, "chokidar": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.1.1.tgz", - "integrity": "sha512-df4o16uZmMHzVQwECZRHwfguOt5ixpuQVaZHjYMvYisgKhE+JXwcj/Tcr3+3bu/XeOJQ9ycYmzu7Mv8XrGxJDQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", "dev": true, "requires": { - "anymatch": "^3.1.0", - "braces": "^3.0.2", - "fsevents": "^2.0.6", - "glob-parent": "^5.0.0", - "is-binary-path": "^2.1.0", - "is-glob": "^4.0.1", - "normalize-path": "^3.0.0", - "readdirp": "^3.1.1" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" } }, "class-utils": { @@ -2114,9 +2117,9 @@ } }, "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "commondir": { @@ -2231,18 +2234,18 @@ "dev": true }, "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", "dev": true }, "core-js-compat": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz", - "integrity": "sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.3.6.tgz", + "integrity": "sha512-YnwZG/+0/f7Pf6Lr3jxtVAFjtGBW9lsLYcqrxhYJai1GfvrP8DEyEpnNzj/FRQfIkOOfk1j5tTBvPBLWVVJm4A==", "dev": true, "requires": { - "browserslist": "^4.6.6", + "browserslist": "^4.7.2", "semver": "^6.3.0" }, "dependencies": { @@ -2331,13 +2334,21 @@ "dev": true }, "css-tree": { - "version": "1.0.0-alpha.33", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", - "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", "dev": true, "requires": { "mdn-data": "2.0.4", - "source-map": "^0.5.3" + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "css-unit-converter": { @@ -2436,30 +2447,12 @@ "dev": true }, "csso": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", - "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz", + "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==", "dev": true, "requires": { - "css-tree": "1.0.0-alpha.29" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.29", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", - "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", - "dev": true, - "requires": { - "mdn-data": "~1.1.0", - "source-map": "^0.5.3" - } - }, - "mdn-data": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", - "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", - "dev": true - } + "css-tree": "1.0.0-alpha.37" } }, "currently-unhandled": { @@ -2771,20 +2764,20 @@ } }, "docusaurus": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/docusaurus/-/docusaurus-1.13.0.tgz", - "integrity": "sha512-3L/0p7CVM4jzAKoUzDDO4IFvLAJ6aA/8zin00tvLk32VQSdw+6S8JggE2ZFKOg+c+oxQ5MQUnsUxL/n5HyBtVg==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/docusaurus/-/docusaurus-1.14.0.tgz", + "integrity": "sha512-wdjdAQAk6Ndypl0F3BIg/EUtYgSCxN9g90KbZ+BkObs0Haz62ehCGPeCNqv97m88YVaYbFzk3geQk1jL77gz5g==", "dev": true, "requires": { - "@babel/core": "^7.5.5", + "@babel/core": "^7.6.2", "@babel/plugin-proposal-class-properties": "^7.5.5", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-proposal-object-rest-spread": "^7.6.2", "@babel/polyfill": "^7.4.4", - "@babel/preset-env": "^7.5.5", + "@babel/preset-env": "^7.6.2", "@babel/preset-react": "^7.0.0", - "@babel/register": "^7.5.5", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5", + "@babel/register": "^7.6.2", + "@babel/traverse": "^7.6.2", + "@babel/types": "^7.6.1", "autoprefixer": "^9.6.1", "babylon": "^6.18.0", "chalk": "^2.4.2", @@ -2950,9 +2943,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.265", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.265.tgz", - "integrity": "sha512-ypHt5Nv1Abr27QvJqk3VC4YDNqsrrWYMCmpmR7BNfCpcgYEwmCDoi3uJpp6kvj/MIjpScQoZMCQzLqfMQGmOsg==", + "version": "1.3.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.302.tgz", + "integrity": "sha512-1qConyiVEbj4xZRBXqtGR003+9tV0rJF0PS6aeO0Ln/UL637js9hdwweCl07meh/kJoI2N4W8q3R3g3F5z46ww==", "dev": true }, "emojis-list": { @@ -2968,9 +2961,9 @@ "dev": true }, "end-of-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.3.tgz", - "integrity": "sha512-cbNhPFS6MlYlWTGncSiDYbdqKhwWFy7kNeb1YSOG6K65i/wPTkLVCJQj0hXA4j0m5Da+hBWnqopEnu1FFelisQ==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { "once": "^1.4.0" @@ -3009,9 +3002,9 @@ } }, "es-abstract": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", - "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", "dev": true, "requires": { "es-to-primitive": "^1.2.0", @@ -3022,8 +3015,8 @@ "is-regex": "^1.0.4", "object-inspect": "^1.6.0", "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.0.0", - "string.prototype.trimright": "^2.0.0" + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" } }, "es-to-primitive": { @@ -3768,8 +3761,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -3790,14 +3782,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3812,20 +3802,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -3942,8 +3929,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -3955,7 +3941,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3970,7 +3955,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3978,14 +3962,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4004,7 +3986,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -4085,8 +4066,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -4098,7 +4078,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -4184,8 +4163,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -4221,7 +4199,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4241,7 +4218,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4285,14 +4261,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -4433,9 +4407,9 @@ "dev": true }, "fsevents": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", - "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.1.tgz", + "integrity": "sha512-4FRPXWETxtigtJW/gxzEDsX1LVbPAM93VleB83kZB+ellqbHMkyt2aJfuzNLRvFPnGi6bcE5SvfxgbXPeKteJw==", "dev": true, "optional": true }, @@ -4529,9 +4503,9 @@ } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -4650,9 +4624,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, "graceful-readlink": { @@ -4826,15 +4800,15 @@ "dev": true }, "highlight.js": { - "version": "9.15.10", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz", - "integrity": "sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==", + "version": "9.16.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.16.2.tgz", + "integrity": "sha512-feMUrVLZvjy0oC7FVJQcSQRqbBq9kwqnYE4+Kj9ZjbHh3g+BisiPgF49NyQbVLNdrL/qqZr3Ca9yOKwgn2i/tw==", "dev": true }, "hosted-git-info": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", - "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", "dev": true }, "hsl-regex": { @@ -5606,9 +5580,9 @@ "dev": true }, "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -5650,6 +5624,15 @@ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, + "klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, "lazy-cache": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", @@ -6329,12 +6312,20 @@ "dev": true }, "node-releases": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.32.tgz", - "integrity": "sha512-VhVknkitq8dqtWoluagsGPn3dxTvN9fwgR59fV3D7sLBHe0JfDramsMI8n8mY//ccq/Kkrf8ZRHRpsyVZ3qw1A==", + "version": "1.1.39", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.39.tgz", + "integrity": "sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA==", "dev": true, "requires": { - "semver": "^5.3.0" + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "normalize-package-data": { @@ -6762,9 +6753,9 @@ "dev": true }, "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.0.tgz", + "integrity": "sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw==", "dev": true }, "pify": { @@ -6861,30 +6852,24 @@ } }, "portfinder": { - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.24.tgz", - "integrity": "sha512-ekRl7zD2qxYndYflwiryJwMioBI7LI7rVXg3EnLK3sjkouT5eOuhS3gS255XxBksa30VG8UPZYZCdgfGOfkSUg==", + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", + "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", "dev": true, "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -6895,9 +6880,9 @@ "dev": true }, "postcss": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz", - "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==", + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -7427,6 +7412,15 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, + "preprocess": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/preprocess/-/preprocess-3.1.0.tgz", + "integrity": "sha1-pE5c3Vu7WlTwrSiaru2AmV19k4o=", + "dev": true, + "requires": { + "xregexp": "3.1.0" + } + }, "prismjs": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", @@ -7570,9 +7564,9 @@ } }, "react": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", - "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.11.0.tgz", + "integrity": "sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -7581,9 +7575,9 @@ } }, "react-dev-utils": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-9.0.4.tgz", - "integrity": "sha512-VwR+mBUXPLdYk/rOz6s6qpasIFGd7GW0KXd/3bih+/qGcMQvPG19XxtjDMtiAg0zWiFwp1ugCzAjLThbzFjVqw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-9.1.0.tgz", + "integrity": "sha512-X2KYF/lIGyGwP/F/oXgGDF24nxDA2KC4b7AFto+eqzc/t838gpSGiaU8trTqHXOohuLxxc5qi1eDzsl9ucPDpg==", "dev": true, "requires": { "@babel/code-frame": "7.5.5", @@ -7605,7 +7599,7 @@ "loader-utils": "1.2.3", "open": "^6.3.0", "pkg-up": "2.0.0", - "react-error-overlay": "^6.0.2", + "react-error-overlay": "^6.0.3", "recursive-readdir": "2.2.2", "shell-quote": "1.7.2", "sockjs-client": "1.4.0", @@ -7619,6 +7613,17 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "browserslist": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz", + "integrity": "sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000989", + "electron-to-chromium": "^1.3.247", + "node-releases": "^1.1.29" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -7637,27 +7642,27 @@ } }, "react-dom": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.9.0.tgz", - "integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==", + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.11.0.tgz", + "integrity": "sha512-nrRyIUE1e7j8PaXSPtyRKtz+2y9ubW/ghNgqKFHHAHaeP0fpF5uXR+sq8IMRHC+ZUxw7W9NyCDTBtwWxvkb0iA==", "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.15.0" + "scheduler": "^0.17.0" } }, "react-error-overlay": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.2.tgz", - "integrity": "sha512-DHRuRk3K4Lg9obI6J4Y+nKvtwjasYRU9CFL3ud42x9YJG1HbQjSNublapC/WBJOA726gNUbqbj0U2df9+uzspQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.3.tgz", + "integrity": "sha512-bOUvMWFQVk5oz8Ded9Xb7WVdEi3QGLC8tH7HmYP0Fdp4Bn3qw0tRFmr5TW6mvahzvmrK4a6bqWGfCevBflP+Xw==", "dev": true }, "react-is": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", - "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==", + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.11.0.tgz", + "integrity": "sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw==", "dev": true }, "read-pkg": { @@ -7737,9 +7742,9 @@ } }, "readdirp": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.2.tgz", - "integrity": "sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", "dev": true, "requires": { "picomatch": "^2.0.4" @@ -7828,9 +7833,9 @@ } }, "regjsgen": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", - "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", "dev": true }, "regjsparser": { @@ -8046,9 +8051,9 @@ "dev": true }, "scheduler": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", - "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz", + "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -8449,9 +8454,9 @@ } }, "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -8786,17 +8791,17 @@ } }, "svgo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", - "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", "dev": true, "requires": { "chalk": "^2.4.1", "coa": "^2.0.2", "css-select": "^2.0.0", "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.33", - "csso": "^3.5.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", "js-yaml": "^3.13.1", "mkdirp": "~0.5.1", "object.values": "^1.1.0", @@ -9376,9 +9381,9 @@ "dev": true }, "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -9428,6 +9433,12 @@ "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==", "dev": true }, + "xregexp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-3.1.0.tgz", + "integrity": "sha1-FNhGHgvdOCJL/uUDmgiY/EL80zY=", + "dev": true + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/gitlab-pages/website/package.json b/gitlab-pages/website/package.json index 41c8d5dde..e32ea799e 100644 --- a/gitlab-pages/website/package.json +++ b/gitlab-pages/website/package.json @@ -11,6 +11,6 @@ "rename-version": "docusaurus-rename-version" }, "devDependencies": { - "docusaurus": "^1.13.0" + "docusaurus": "^1.14.0" } } diff --git a/gitlab-pages/website/pages/en/index.js b/gitlab-pages/website/pages/en/index.js index 6fa3459de..7f2cf0fde 100644 --- a/gitlab-pages/website/pages/en/index.js +++ b/gitlab-pages/website/pages/en/index.js @@ -185,17 +185,16 @@ class HomeSplash extends React.Component {
- {siteConfig.title} + LIGO is a statically typed high-level smart-contract programming language that compiles to Michelson
-

{siteConfig.tagline}

-

{siteConfig.taglineSub}

+ {/*

{siteConfig.tagline}

*/} +

It seeks to be easy to use, extensible and safe.

Try Online -

- {PartnerShowcase} -
-

Partners

- +
+
+ {PartnerShowcase} +
+

Partners

+

We're not alone in this world.

+
+
); }; diff --git a/gitlab-pages/website/sidebars.json b/gitlab-pages/website/sidebars.json index 7936cdc34..71827e978 100644 --- a/gitlab-pages/website/sidebars.json +++ b/gitlab-pages/website/sidebars.json @@ -1,13 +1,22 @@ { "docs": { - "Setup": ["setup/installation", "setup/editor-support"], + "Intro": ["intro/what-and-why", "intro/installation", "intro/editor-support"], "Language Basics": [ "language-basics/cheat-sheet", "language-basics/types", - "language-basics/variables", + "language-basics/constants-and-variables", + "language-basics/math-numbers-tez", + "language-basics/strings", "language-basics/functions", - "language-basics/entrypoints", - "language-basics/operators" + "language-basics/boolean-if-else", + "language-basics/unit-option-pattern-matching", + "language-basics/maps-records", + "language-basics/sets-lists-touples" + ], + "Advanced": [ + "advanced/timestamps-addresses", + "advanced/entrypoints-contracts", + "advanced/first-contract" ], "API": ["api-cli-commands"] }, diff --git a/gitlab-pages/website/siteConfig.js b/gitlab-pages/website/siteConfig.js index 2c87660a7..4a7895414 100644 --- a/gitlab-pages/website/siteConfig.js +++ b/gitlab-pages/website/siteConfig.js @@ -99,7 +99,7 @@ const siteConfig = { // For no header links in the top nav bar -> headerLinks: [], headerLinks: [ - { doc: "setup/installation", label: "Docs" }, + { doc: "intro/what-and-why", label: "Docs" }, { doc: "tutorials/get-started/tezos-taco-shop-smart-contract", label: "Tutorials" diff --git a/gitlab-pages/website/static/css/custom.css b/gitlab-pages/website/static/css/custom.css index b9342db76..8bfefb6a0 100644 --- a/gitlab-pages/website/static/css/custom.css +++ b/gitlab-pages/website/static/css/custom.css @@ -30,7 +30,7 @@ h4, font-family: "DM Sans", sans-serif; font-weight: bold; /** Override docusaurus rule that makes a huge top margin **/ - margin-top: 1rem; + margin-top: 2rem; } body, @@ -63,6 +63,8 @@ h1 { } h2 { font-size: 2.25rem; + margin-bottom: 0.5rem; + margin-top: 1.5rem; } .landing h2 { font-size: 3rem; @@ -76,6 +78,9 @@ h3 { h4 { font-size: 1.125rem; } +p { + line-height: 25px; +} .landing h4 { font-size: 1.5rem; } @@ -89,6 +94,7 @@ h4 { body, .body { font-size: 1rem; + color: var(--color-primary-text); } .landing .body, .landing { @@ -115,6 +121,7 @@ footnote { .fixedHeaderContainer { background-color: #ffffff; color: var(--color-primary-text); + padding: 0px; } .fixedHeaderContainer a { @@ -141,6 +148,7 @@ footnote { .fixedHeaderContainer { left: 0; + min-height: 80px; } .nav-footer { @@ -149,17 +157,16 @@ footnote { .nav-footer .copyright { text-align: left; - margin-left: 92px; margin-top: 3em; border-top: 1px solid white; padding-top: 3em; - margin-right: 92px; } .nav-footer .footer-wrapper { - margin: 0 auto 3em; - max-width: 1080px; + margin: 0 auto; + margin-top: var(--padding-level-4); + max-width: 1500px; } .nav-footer .sitemap { @@ -211,6 +218,8 @@ footnote { background-color: white; } + + .hljs { text-align: left; background: transparent; @@ -219,7 +228,6 @@ footnote { .tabs { margin: 0 auto; border-top: none; - border-bottom: 4px solid #e0e0e0; } .tabs .nav-tabs > div { @@ -228,16 +236,24 @@ footnote { border-bottom: none; padding-bottom: 8px; } -.tab-content { - padding-top: 12px; + +/* .tabs blockquote { + margin-top: 16px; } +.tabs p { + margin-top: 16px; +} */ + .tabs .nav-tabs > div.active { border-bottom: 4px solid #1a1a1a; } .tab-content { border-top: 4px solid #e0e0e0; + padding-top: 16px; + border-bottom: 4px solid #e0e0e0; + margin-bottom: 16px; } .nav-tabs { @@ -255,27 +271,40 @@ footnote { } blockquote { - background-color: rgba(26, 26, 26, 0.3); - border-left: 8px solid rgba(26, 26, 26, 0.1); - color: rgba(255, 255, 255, 1); + background-color: #EFEFEF; + border-left: 5px solid var(--color-primary-text); + color: var(--color-primary-text); + border-radius: 2px; } blockquote code { - opacity: 0.5; + opacity: 1; + background: var(--color-code-background2); } -a { - color: var(--color-primary-text); -} - -a:hover { +a, a:hover { color: var(--color-primary-brand); } +/* blockquote a { + color: rgba(255, 255, 255, 1); + opacity: 0.9; +} */ + +.docMainWrapper a:hover { + text-decoration: underline; +} + .landing a { color: var(--color-white); } + + +.landing .hljs { + background-color: rgba(255,255,255,0.5); +} + .landing a:hover { font-weight: bold; } @@ -329,7 +358,6 @@ html { body { margin: 0 auto; - max-width: 1500px; } .copyright a { @@ -357,9 +385,50 @@ body { visibility: hidden; } +.toc .toggleNav ul li a { + font-size: 16px; + line-height: 25px; + color: var(--color-primary-text); +} + +.toc .toggleNav .navGroup .navGroupCategoryTitle { + color: var(--color-secondary-text); + font-size: 12px; + line-height: 16px; + margin-bottom: 20px; +} + +.toc .toggleNav .navGroup { + margin-bottom: 30px; +} + +.toc .toggleNav ul { + padding: 0px; +} + +.navListItemActive a{ + color: var(--color-primary-brand) !important; +} + +.onPageNav > .toc-headings { + border-color: var(--color-gray); +} + +.onPageNav .toc-headings > li > a { + color: var(--color-secondary-text); +} + +.onPageNav .toc-headings > li > a.active { + color: var(--color-primary-text); +} + code { - background: rgb(240, 240, 240); - color: #444; + background: var(--color-code-background1); + margin-left: 2px; + margin-right: 2px; + border-radius: 2px; + border: none; + outline: none; } body @@ -374,8 +443,9 @@ body background-repeat: no-repeat; background-position: center center; min-width: 50px; - padding-top: 5px; opacity: 0.8; + position: relative; + top: 1px; } body @@ -527,7 +597,6 @@ body justify-content: center; max-width: fit-content; color: var(--color-primary-text); - padding: 0 var(--padding-level-1); } .profileContainer a { @@ -555,6 +624,31 @@ body flex-wrap: wrap; } +.subtagline-text { + text-align: left; + margin-bottom: 25px; +} + +.projectTitle { + font-size: 2.5rem; + text-align: left; + margin-bottom: 25px; + line-height: 47px; +} + +.home-text { + text-align: left; + margin-top: -50px; +} + +.home-text a:nth-of-type(2) { + margin-left: 24px; +} + +.nav-footer .sitemap { + max-width: 1500px; +} + @media only screen and (min-device-width: 360px) and (max-device-width: 736px) { } @@ -578,12 +672,20 @@ body .flex-inline-container { display: flex; flex-direction: row; - justify-content: space-around; - padding: var(--padding-level-1); + justify-content: space-between; flex-wrap: wrap; align-items: stretch; } +.features h2, .team h2 { + margin-bottom: 70px; +} + +.features, .team, .home-container, .partners-container { + max-width: 1500px; + margin: 0 auto; +} + .team .flex-inline-container { align-items: flex-start; } @@ -603,14 +705,20 @@ body text-align: center; } +.partners-container-wrapper { + padding-bottom: 0px; + padding-top: 0px; + margin-top: 45px; + background-color: var(--color-light-gray); +} + /** Partners **/ .partners-container { - background-color: var(--color-light-gray); display: flex; justify-content: space-around; align-content: center; - padding: var(--padding-level-3); - margin: var(--padding-level-4) 0; + padding-top: var(--padding-level-5); + padding-bottom: var(--padding-level-5); } .partners-container a { @@ -623,12 +731,45 @@ body .partners-text { padding: 0 var(--padding-level-1); border-left: 5px solid var(--color-primary-brand); + font-size: 18px; + line-height: 28px; + color: var(--color-primary-text); +} + +.partners-text h3 { + margin-bottom: 10px; } .code-snippet > div:nth-child(2) { display: none; } +.navigationSlider .slidingNav ul li a { + text-transform: lowercase; + font-size: 16px; + line-height: 22px; +} + +.headerWrapper.wrapper { + margin-top: 21px; +} + +.home-container .tab-pane pre { + margin: 0; +} + +pre { + margin: 0px; +} + +.home-container { + margin-top: 50px; +} + +.landing .mainContainer { + padding-bottom: 0px; +} + @media only screen and (min-width: 1024px) { .code-snippet > div:nth-child(2) { display: block; @@ -649,7 +790,7 @@ body } .home-container .tab-pane { - height: 500px; + height: 520px; } } @@ -730,13 +871,9 @@ body } } + @media only screen and (min-width: 1280px) { - .home-container { - flex-direction: row; - margin: var(--padding-level-1); - max-width: 90%; - padding: var(--padding-level-3); - } + } @@ -766,9 +903,10 @@ input#search_input_react::placeholder { .hljs { display:block; overflow-x:hidden; - padding:.5em; - background:white; + padding:20px; + background: var(--color-code-background1); color:black; + margin-bottom: 16px; } .hljs-comment, .hljs-quote, @@ -818,6 +956,5 @@ input#search_input_react::placeholder { } .docMainWrapper .hljs { - border: solid 1px lightgray; overflow-x: auto; } \ No newline at end of file diff --git a/gitlab-pages/website/static/img/docs/intro/editor-support/error-reporting.png b/gitlab-pages/website/static/img/docs/intro/editor-support/error-reporting.png new file mode 100644 index 0000000000000000000000000000000000000000..c27e7888870616ae22b55b1a50bdfdfcbfe7efb0 GIT binary patch literal 69426 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 Q2K^EjmJuoy_~P~d03!jQa{vGU literal 0 HcmV?d00001 diff --git a/gitlab-pages/website/versioned_docs/version-next/language-basics-entrypoints.md b/gitlab-pages/website/versioned_docs/version-next/language-basics-entrypoints.md deleted file mode 100644 index d32ea7bfd..000000000 --- a/gitlab-pages/website/versioned_docs/version-next/language-basics-entrypoints.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -id: version-next-language-basics-entrypoints -title: Entrypoints -original_id: language-basics-entrypoints ---- - -## Defining an entry point - - - -```Pascal -function main (const p : int ; const s : int) : (list(operation) * int) is - block {skip} with ((nil : list(operation)), s + 1) -``` - - -## Multiple entry points - -Multiple entrypoints are currently not supported in Michelson, however with Ligo, you can work that around by using variants. - - - -```Pascal -// variant defining pseudo multi-entrypoint actions -type action is -| Increment of int -| Decrement of int - -function add (const a : int ; const b : int) : int is - block { skip } with a + b - -function subtract (const a : int ; const b : int) : int is - block { skip } with a - b - -// real entrypoint that re-routes the flow based on the action provided -function main (const p : action ; const s : int) : (list(operation) * int) is - block {skip} with ((nil : list(operation)), - case p of - | Increment n -> add(s, n) - | Decrement n -> subtract(s, n) - end) -``` - - - diff --git a/gitlab-pages/website/versioned_docs/version-next/language-basics-functions.md b/gitlab-pages/website/versioned_docs/version-next/language-basics-functions.md deleted file mode 100644 index eace19496..000000000 --- a/gitlab-pages/website/versioned_docs/version-next/language-basics-functions.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -id: version-next-language-basics-functions -title: Functions -original_id: language-basics-functions ---- - -## Defining a function - - - -```Pascal -// multiply(1, 2) = 2 -function multiply (const a : int ; const b : int) : int is - begin - const result : int = a * b ; - end with result - -// add(1, 2) = 3 -function add (const a : int ; const b : int) : int is - block { skip } with a + b -``` - - \ No newline at end of file diff --git a/gitlab-pages/website/versioned_docs/version-next/language-basics-operators.md b/gitlab-pages/website/versioned_docs/version-next/language-basics-operators.md deleted file mode 100644 index 1a044a7ed..000000000 --- a/gitlab-pages/website/versioned_docs/version-next/language-basics-operators.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -id: version-next-language-basics-operators -title: Operators -original_id: language-basics-operators ---- - -## Available operators - -|Michelson |Pascaligo |Description | -|--- |--- |--- | -| `SENDER` | `sender` | Address that initiated the current transaction -| `SOURCE` | `source` | Address that initiated the transaction, which triggered the current transaction. (useful e.g. when there's a transaction sent by another contract) -| `AMOUNT` | `amount` | Amount of tez sent by the transaction that invoked the contract \ No newline at end of file diff --git a/gitlab-pages/website/versioned_docs/version-next/language-basics-variables.md b/gitlab-pages/website/versioned_docs/version-next/language-basics-variables.md deleted file mode 100644 index eafcff363..000000000 --- a/gitlab-pages/website/versioned_docs/version-next/language-basics-variables.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -id: version-next-language-basics-variables -title: Variables -original_id: language-basics-variables ---- - -## Defining a variable - - - -```Pascal -// int -const four : int = 4; - -// string -const name : string = "John Doe"; -``` - - \ No newline at end of file diff --git a/gitlab-pages/website/versioned_sidebars/version-next-sidebars.json b/gitlab-pages/website/versioned_sidebars/version-next-sidebars.json index 0c0c19056..e74ff6d36 100644 --- a/gitlab-pages/website/versioned_sidebars/version-next-sidebars.json +++ b/gitlab-pages/website/versioned_sidebars/version-next-sidebars.json @@ -1,8 +1,9 @@ { "version-next-docs": { - "Setup": [ - "version-next-setup/installation", - "version-next-setup/editor-support" + "Intro": [ + "version-next-intro/what-and-why", + "version-next-intro/installation", + "version-next-intro/editor-support" ], "Language Basics": [ "version-next-language-basics/cheat-sheet",