diff --git a/EnvelopeGenerator.Common/Entities/EnvelopeDocument.vb b/EnvelopeGenerator.Common/Entities/EnvelopeDocument.vb
index 80a7dda9..208161a7 100644
--- a/EnvelopeGenerator.Common/Entities/EnvelopeDocument.vb
+++ b/EnvelopeGenerator.Common/Entities/EnvelopeDocument.vb
@@ -9,6 +9,8 @@ Public Class EnvelopeDocument
Public Property EnvelopeId As Integer = 0
+ Public Property Elements As New List(Of EnvelopeDocumentElement)
+
Public ReadOnly Property Filename As String
Get
Return FileInfo.Name
diff --git a/EnvelopeGenerator.Common/Models/DocumentModel.vb b/EnvelopeGenerator.Common/Models/DocumentModel.vb
index 3a42949d..df8854eb 100644
--- a/EnvelopeGenerator.Common/Models/DocumentModel.vb
+++ b/EnvelopeGenerator.Common/Models/DocumentModel.vb
@@ -7,19 +7,39 @@ Imports EnvelopeGenerator.Common.My.Resources
Public Class DocumentModel
Inherits BaseModel
+ Private ElementModel As ElementModel
+
Public Sub New(pState As State)
MyBase.New(pState)
+ ElementModel = New ElementModel(pState)
End Sub
Private Function ToDocument(pRow As DataRow) As EnvelopeDocument
+ Dim oDocumentId = pRow.ItemEx("GUID", 0)
Return New EnvelopeDocument() With {
- .Id = pRow.ItemEx("GUID", 0),
+ .Id = oDocumentId,
.EnvelopeId = pRow.ItemEx("ENVELOPE_ID", 0),
.FileInfo = New IO.FileInfo(pRow.ItemEx("FILEPATH", "")),
- .IsTempFile = False
+ .IsTempFile = False,
+ .Elements = ElementModel.List(oDocumentId)
}
End Function
+ Public Function GetById(pDocumentId As Integer) As EnvelopeDocument
+ Try
+ Dim oSql = $"SELECT * FROM [dbo].[TBSIG_ENVELOPE_DOCUMENT] WHERE GUID = {pDocumentId}"
+ Dim oTable = Database.GetDatatable(oSql)
+
+ Return oTable?.Rows.Cast(Of DataRow).
+ Select(AddressOf ToDocument).
+ Single()
+
+ Catch ex As Exception
+ Logger.Error(ex)
+ Return Nothing
+ End Try
+ End Function
+
Public Function List(pEnvelopeId As Integer) As IEnumerable(Of EnvelopeDocument)
Try
Dim oSql = $"SELECT * FROM [dbo].[TBSIG_ENVELOPE_DOCUMENT] WHERE ENVELOPE_ID = {pEnvelopeId}"
diff --git a/EnvelopeGenerator.Common/Models/EnvelopeModel.vb b/EnvelopeGenerator.Common/Models/EnvelopeModel.vb
index b0c4a435..f5026750 100644
--- a/EnvelopeGenerator.Common/Models/EnvelopeModel.vb
+++ b/EnvelopeGenerator.Common/Models/EnvelopeModel.vb
@@ -23,6 +23,20 @@ Public Class EnvelopeModel
Return oEnvelope
End Function
+ Public Function GetByUuid(pEnvelopeUuid As String) As Envelope
+ Try
+ Dim oSql = $"SELECT * FROM [dbo].[TBSIG_ENVELOPE] WHERE ENVELOPE_UUID = '{pEnvelopeUuid}'"
+ Dim oTable = Database.GetDatatable(oSql)
+
+ Return oTable?.Rows.Cast(Of DataRow).
+ Select(AddressOf ToEnvelope).
+ Single()
+ Catch ex As Exception
+ Logger.Error(ex)
+ Return Nothing
+ End Try
+ End Function
+
Public Function List() As IEnumerable(Of Envelope)
Try
Dim oSql = $"SELECT * FROM [dbo].[TBSIG_ENVELOPE] WHERE USER_ID = {State.UserId}"
diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj
index cd698dfd..cddb48a6 100644
--- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj
+++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj
@@ -8,6 +8,7 @@
+
diff --git a/EnvelopeGenerator.Web/Handler/FileHandler.cs b/EnvelopeGenerator.Web/Handler/FileHandler.cs
new file mode 100644
index 00000000..7d0a9218
--- /dev/null
+++ b/EnvelopeGenerator.Web/Handler/FileHandler.cs
@@ -0,0 +1,18 @@
+using EnvelopeGenerator.Web.Services;
+
+namespace EnvelopeGenerator.Web.Handler
+{
+ public class FileHandler
+ {
+ public async static Task HandleFile(HttpContext ctx, DatabaseService database, LoggingService logging)
+ {
+ var logger = logging.LogConfig.GetLogger("FileHandler");
+ int docId = int.Parse((string)ctx.Request.RouteValues["docId"]);
+ var document = database.LoadDocument(docId);
+ var bytes = await File.ReadAllBytesAsync(document.Filepath);
+
+ return Results.File(bytes);
+
+ }
+ }
+}
diff --git a/EnvelopeGenerator.Web/Pages/Index.razor b/EnvelopeGenerator.Web/Pages/Index.razor
index 6dff56b1..b4e31ba5 100644
--- a/EnvelopeGenerator.Web/Pages/Index.razor
+++ b/EnvelopeGenerator.Web/Pages/Index.razor
@@ -1,8 +1,24 @@
@page "/"
+@using EnvelopeGenerator.Common;
+@using EnvelopeGenerator.Web.Services;
+@inject DatabaseService Database;
Index
-Hello, world!
+
-Welcome to your new app.
+@code {
+ public List envelopes = new();
+ protected override void OnInitialized()
+ {
+ envelopes = Database.LoadEnvelopes();
+ }
+
+
+}
diff --git a/EnvelopeGenerator.Web/Pages/ShowEnvelope.cshtml b/EnvelopeGenerator.Web/Pages/ShowEnvelope.cshtml
deleted file mode 100644
index fa42b6fc..00000000
--- a/EnvelopeGenerator.Web/Pages/ShowEnvelope.cshtml
+++ /dev/null
@@ -1,3 +0,0 @@
-@page "/EnvelopeKey/{EnvelopeReceiverId:int}"
-
-Envelope
\ No newline at end of file
diff --git a/EnvelopeGenerator.Web/Pages/ShowEnvelope.cshtml.cs b/EnvelopeGenerator.Web/Pages/ShowEnvelope.cshtml.cs
deleted file mode 100644
index e95d1ff6..00000000
--- a/EnvelopeGenerator.Web/Pages/ShowEnvelope.cshtml.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.RazorPages;
-
-namespace EnvelopeGenerator.Web.Pages
-{
- public class ShowEnvelopeModel : PageModel
- {
- public void OnGet()
- {
- }
- }
-}
diff --git a/EnvelopeGenerator.Web/Pages/ShowEnvelope.razor b/EnvelopeGenerator.Web/Pages/ShowEnvelope.razor
new file mode 100644
index 00000000..1904b1f0
--- /dev/null
+++ b/EnvelopeGenerator.Web/Pages/ShowEnvelope.razor
@@ -0,0 +1,30 @@
+@page "/EnvelopeKey/{EnvelopeReceiverId}"
+
+@using EnvelopeGenerator.Common;
+@using EnvelopeGenerator.Web.Services;
+@inject DatabaseService Database
+@inject IJSRuntime JS
+
+
+
+@code {
+ [Parameter] public string EnvelopeReceiverId { get; set; }
+
+ private Envelope envelope;
+ private EnvelopeDocument document;
+
+ protected override void OnInitialized()
+ {
+ envelope = Database.LoadEnvelope(EnvelopeReceiverId);
+ document = envelope.Documents.First();
+ }
+
+ protected override async void OnAfterRender(bool firstRender)
+ {
+ if (firstRender)
+ {
+
+ await JS.InvokeVoidAsync("loadPDFFromUrl", "#container", $"/api/download/{document.Id}");
+ }
+ }
+}
diff --git a/EnvelopeGenerator.Web/Pages/_Host.cshtml b/EnvelopeGenerator.Web/Pages/_Host.cshtml
index d8b09c91..ac807189 100644
--- a/EnvelopeGenerator.Web/Pages/_Host.cshtml
+++ b/EnvelopeGenerator.Web/Pages/_Host.cshtml
@@ -5,4 +5,8 @@
Layout = "_Layout";
}
+@* Include pspdfkit.js in your Pages/_Host.cshtml file *@
+
+
+
diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs
index 229cdcfa..c105617f 100644
--- a/EnvelopeGenerator.Web/Program.cs
+++ b/EnvelopeGenerator.Web/Program.cs
@@ -1,3 +1,4 @@
+using EnvelopeGenerator.Web.Handler;
using EnvelopeGenerator.Web.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
@@ -33,6 +34,9 @@ app.UseStaticFiles();
// Add a router
app.UseRouting();
+// Add file download endpoint
+app.MapGet("/api/download/{docId}", FileHandler.HandleFile);
+
// Blazor plumbing
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
diff --git a/EnvelopeGenerator.Web/Services/DatabaseService.cs b/EnvelopeGenerator.Web/Services/DatabaseService.cs
index 47a7b6b1..d6c2053e 100644
--- a/EnvelopeGenerator.Web/Services/DatabaseService.cs
+++ b/EnvelopeGenerator.Web/Services/DatabaseService.cs
@@ -1,5 +1,6 @@
using DigitalData.Modules.Database;
using DigitalData.Modules.Logging;
+using EnvelopeGenerator.Common;
namespace EnvelopeGenerator.Web.Services
{
@@ -7,9 +8,14 @@ namespace EnvelopeGenerator.Web.Services
{
public MSSQLServer MSSQL { get; set; }
+ private EnvelopeModel envelopeModel;
+ private DocumentModel documentModel;
+ private ElementModel elementModel;
+
private readonly LogConfig _logConfig;
private readonly Logger _logger;
+
public DatabaseService(LoggingService Logging, IConfiguration Config)
{
_logConfig = Logging.LogConfig;
@@ -21,6 +27,9 @@ namespace EnvelopeGenerator.Web.Services
if (MSSQL.DBInitialized == true)
{
_logger.Debug("MSSQL Connection: [{0}]", MSSQL.CurrentConnectionString);
+
+ var state = GetState();
+ InitializeModels(state);
}
else
{
@@ -29,5 +38,47 @@ namespace EnvelopeGenerator.Web.Services
}
}
+
+ public State GetState()
+ {
+ return new State
+ {
+ Database = MSSQL,
+ LogConfig = _logConfig,
+ UserId = 2 // TODO
+ };
+ }
+
+ public void InitializeModels(State state)
+ {
+ envelopeModel = new(state);
+ documentModel = new(state);
+ elementModel = new(state);
+ }
+
+ public Envelope LoadEnvelope(string envelopeReceiverId)
+ {
+ Tuple result = Helpers.DecodeEnvelopeReceiverId(envelopeReceiverId);
+ var envelopeUuid = result.Item1;
+ var receiverSignature = result.Item2;
+
+ Envelope envelope = envelopeModel.GetByUuid(envelopeUuid);
+ List documents = (List)documentModel.List(envelope.Id);
+
+ envelope.Documents = documents;
+
+ return envelope;
+ }
+
+ public List LoadEnvelopes()
+ {
+ return (List)envelopeModel.List();
+ }
+
+ public EnvelopeDocument LoadDocument(int pDocumentId)
+ {
+ return documentModel.GetById(pDocumentId);
+ }
+
}
}
diff --git a/EnvelopeGenerator.Web/Services/LoggingService.cs b/EnvelopeGenerator.Web/Services/LoggingService.cs
index 6f2b627c..3d03f6cc 100644
--- a/EnvelopeGenerator.Web/Services/LoggingService.cs
+++ b/EnvelopeGenerator.Web/Services/LoggingService.cs
@@ -8,7 +8,7 @@ namespace EnvelopeGenerator.Web.Services
public LoggingService(IConfiguration Config)
{
- LogConfig = new LogConfig(LogConfig.PathType.CustomPath, Config["Config:LogPath"], null, "Digital Data", "ECM.JobRunner.Web");
+ LogConfig = new LogConfig(LogConfig.PathType.CustomPath, Config["Config:LogPath"], null, "Digital Data", "ECM.EnvelopeGenerator.Web");
var logger = LogConfig.GetLogger();
logger.Info("Logging initialized!");
diff --git a/EnvelopeGenerator.Web/Shared/MainLayout.razor b/EnvelopeGenerator.Web/Shared/MainLayout.razor
index 011a7c92..e4ab3c90 100644
--- a/EnvelopeGenerator.Web/Shared/MainLayout.razor
+++ b/EnvelopeGenerator.Web/Shared/MainLayout.razor
@@ -1,19 +1,2 @@
@inherits LayoutComponentBase
-
-EnvelopeGenerator.Web
-
-
-
-
-
-
-
-
- @Body
-
-
-
+@Body
\ No newline at end of file
diff --git a/EnvelopeGenerator.Web/appsettings.Development.json b/EnvelopeGenerator.Web/appsettings.Development.json
index 770d3e93..f8802543 100644
--- a/EnvelopeGenerator.Web/appsettings.Development.json
+++ b/EnvelopeGenerator.Web/appsettings.Development.json
@@ -5,5 +5,11 @@
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
+ },
+ "Config": {
+ "ConnectionString": "Server=sDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;",
+ "LogPath": "E:\\EnvelopeGenerator\\Logs",
+ "LogDebug": true,
+ "LogJson": true
}
}
diff --git a/EnvelopeGenerator.Web/wwwroot/app.js b/EnvelopeGenerator.Web/wwwroot/app.js
new file mode 100644
index 00000000..342a12b3
--- /dev/null
+++ b/EnvelopeGenerator.Web/wwwroot/app.js
@@ -0,0 +1,24 @@
+// This function will be called in the ShowEnvelope.razor page
+
+// and will trigger loading of the Editor Interface
+function loadPDFFromUrl(container, url) {
+ console.log("Loading PSPDFKit..");
+
+ fetch(url, { credentials: "include" })
+ .then(res => res.arrayBuffer())
+ .then(arrayBuffer => PSPDFKit.load({
+ container: container,
+ document: arrayBuffer
+ }))
+ .then(instance => {
+ console.log("PSPDFKit loaded", instance)
+ configurePSPDFKit(instance);
+ })
+ .catch(error => {
+ console.error(error.message);
+ });
+}
+
+function configurePSPDFKit(instance) {
+
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.Web/wwwroot/index.d.ts b/EnvelopeGenerator.Web/wwwroot/index.d.ts
new file mode 100644
index 00000000..d3369051
--- /dev/null
+++ b/EnvelopeGenerator.Web/wwwroot/index.d.ts
@@ -0,0 +1,8599 @@
+declare const SignatureSaveMode: {
+ readonly ALWAYS: "ALWAYS";
+ readonly NEVER: "NEVER";
+ readonly USING_UI: "USING_UI";
+};
+type ISignatureSaveMode = (typeof SignatureSaveMode)[keyof typeof SignatureSaveMode];
+
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/**
+ * Immutable data encourages pure functions (data-in, data-out) and lends itself
+ * to much simpler application development and enabling techniques from
+ * functional programming such as lazy evaluation.
+ *
+ * While designed to bring these powerful functional concepts to JavaScript, it
+ * presents an Object-Oriented API familiar to Javascript engineers and closely
+ * mirroring that of Array, Map, and Set. It is easy and efficient to convert to
+ * and from plain Javascript types.
+ *
+ * ## How to read these docs
+ *
+ * In order to better explain what kinds of values the Immutable.js API expects
+ * and produces, this documentation is presented in a statically typed dialect of
+ * JavaScript (like [Flow][] or [TypeScript][]). You *don't need* to use these
+ * type checking tools in order to use Immutable.js, however becoming familiar
+ * with their syntax will help you get a deeper understanding of this API.
+ *
+ * **A few examples and how to read them.**
+ *
+ * All methods describe the kinds of data they accept and the kinds of data
+ * they return. For example a function which accepts two numbers and returns
+ * a number would look like this:
+ *
+ * ```js
+ * sum(first: number, second: number): number
+ * ```
+ *
+ * Sometimes, methods can accept different kinds of data or return different
+ * kinds of data, and this is described with a *type variable*, which is
+ * typically in all-caps. For example, a function which always returns the same
+ * kind of data it was provided would look like this:
+ *
+ * ```js
+ * identity(value: T): T
+ * ```
+ *
+ * Type variables are defined with classes and referred to in methods. For
+ * example, a class that holds onto a value for you might look like this:
+ *
+ * ```js
+ * class Box {
+ * constructor(value: T)
+ * getValue(): T
+ * }
+ * ```
+ *
+ * In order to manipulate Immutable data, methods that we're used to affecting
+ * a Collection instead return a new Collection of the same type. The type
+ * `this` refers to the same kind of class. For example, a List which returns
+ * new Lists when you `push` a value onto it might look like:
+ *
+ * ```js
+ * class List {
+ * push(value: T): this
+ * }
+ * ```
+ *
+ * Many methods in Immutable.js accept values which implement the JavaScript
+ * [Iterable][] protocol, and might appear like `Iterable` for something
+ * which represents sequence of strings. Typically in JavaScript we use plain
+ * Arrays (`[]`) when an Iterable is expected, but also all of the Immutable.js
+ * collections are iterable themselves!
+ *
+ * For example, to get a value deep within a structure of data, we might use
+ * `getIn` which expects an `Iterable` path:
+ *
+ * ```
+ * getIn(path: Iterable): any
+ * ```
+ *
+ * To use this method, we could pass an array: `data.getIn([ "key", 2 ])`.
+ *
+ *
+ * Note: All examples are presented in the modern [ES2015][] version of
+ * JavaScript. Use tools like Babel to support older browsers.
+ *
+ * For example:
+ *
+ * ```js
+ * // ES2015
+ * const mappedFoo = foo.map(x => x * x);
+ * // ES5
+ * var mappedFoo = foo.map(function (x) { return x * x; });
+ * ```
+ *
+ * [ES2015]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla
+ * [TypeScript]: http://www.typescriptlang.org/
+ * [Flow]: https://flowtype.org/
+ * [Iterable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
+ */
+
+
+
+ /**
+ * Lists are ordered indexed dense collections, much like a JavaScript
+ * Array.
+ *
+ * Lists are immutable and fully persistent with O(log32 N) gets and sets,
+ * and O(1) push and pop.
+ *
+ * Lists implement Deque, with efficient addition and removal from both the
+ * end (`push`, `pop`) and beginning (`unshift`, `shift`).
+ *
+ * Unlike a JavaScript Array, there is no distinction between an
+ * "unset" index and an index set to `undefined`. `List#forEach` visits all
+ * indices from 0 to size, regardless of whether they were explicitly defined.
+ */
+ declare module List {
+
+ /**
+ * True if the provided value is a List
+ *
+ *
+ * ```js
+ * const { List } = require('immutable');
+ * List.isList([]); // false
+ * List.isList(List()); // true
+ * ```
+ */
+ function isList(maybeList: any): maybeList is List;
+
+ /**
+ * Creates a new List containing `values`.
+ *
+ *
+ * ```js
+ * const { List } = require('immutable');
+ * List.of(1, 2, 3, 4)
+ * // List [ 1, 2, 3, 4 ]
+ * ```
+ *
+ * Note: Values are not altered or converted in any way.
+ *
+ *
+ * ```js
+ * const { List } = require('immutable');
+ * List.of({x:1}, 2, [3], 4)
+ * // List [ { x: 1 }, 2, [ 3 ], 4 ]
+ * ```
+ */
+ function of(...values: Array): List;
+ }
+
+ /**
+ * Create a new immutable List containing the values of the provided
+ * collection-like.
+ *
+ * Note: `List` is a factory function and not a class, and does not use the
+ * `new` keyword during construction.
+ *
+ *
+ * ```js
+ * const { List, Set } = require('immutable')
+ *
+ * const emptyList = List()
+ * // List []
+ *
+ * const plainArray = [ 1, 2, 3, 4 ]
+ * const listFromPlainArray = List(plainArray)
+ * // List [ 1, 2, 3, 4 ]
+ *
+ * const plainSet = Set([ 1, 2, 3, 4 ])
+ * const listFromPlainSet = List(plainSet)
+ * // List [ 1, 2, 3, 4 ]
+ *
+ * const arrayIterator = plainArray[Symbol.iterator]()
+ * const listFromCollectionArray = List(arrayIterator)
+ * // List [ 1, 2, 3, 4 ]
+ *
+ * listFromPlainArray.equals(listFromCollectionArray) // true
+ * listFromPlainSet.equals(listFromCollectionArray) // true
+ * listFromPlainSet.equals(listFromPlainArray) // true
+ * ```
+ */
+ declare function List(): List;
+ declare function List(): List;
+ declare function List(collection: Iterable): List;
+
+ interface List extends Collection.Indexed {
+
+ /**
+ * The number of items in this List.
+ */
+ readonly size: number;
+
+ // Persistent changes
+
+ /**
+ * Returns a new List which includes `value` at `index`. If `index` already
+ * exists in this List, it will be replaced.
+ *
+ * `index` may be a negative number, which indexes back from the end of the
+ * List. `v.set(-1, "value")` sets the last item in the List.
+ *
+ * If `index` larger than `size`, the returned List's `size` will be large
+ * enough to include the `index`.
+ *
+ *
+ * ```js
+ * const originalList = List([ 0 ]);
+ * // List [ 0 ]
+ * originalList.set(1, 1);
+ * // List [ 0, 1 ]
+ * originalList.set(0, 'overwritten');
+ * // List [ "overwritten" ]
+ * originalList.set(2, 2);
+ * // List [ 0, undefined, 2 ]
+ *
+ * List().set(50000, 'value').size;
+ * // 50001
+ * ```
+ *
+ * Note: `set` can be used in `withMutations`.
+ */
+ set(index: number, value: T): List;
+
+ /**
+ * Returns a new List which excludes this `index` and with a size 1 less
+ * than this List. Values at indices above `index` are shifted down by 1 to
+ * fill the position.
+ *
+ * This is synonymous with `list.splice(index, 1)`.
+ *
+ * `index` may be a negative number, which indexes back from the end of the
+ * List. `v.delete(-1)` deletes the last item in the List.
+ *
+ * Note: `delete` cannot be safely used in IE8
+ *
+ *
+ * ```js
+ * List([ 0, 1, 2, 3, 4 ]).delete(0);
+ * // List [ 1, 2, 3, 4 ]
+ * ```
+ *
+ * Since `delete()` re-indexes values, it produces a complete copy, which
+ * has `O(N)` complexity.
+ *
+ * Note: `delete` *cannot* be used in `withMutations`.
+ *
+ * @alias remove
+ */
+ delete(index: number): List;
+ remove(index: number): List;
+
+ /**
+ * Returns a new List with `value` at `index` with a size 1 more than this
+ * List. Values at indices above `index` are shifted over by 1.
+ *
+ * This is synonymous with `list.splice(index, 0, value)`.
+ *
+ *
+ * ```js
+ * List([ 0, 1, 2, 3, 4 ]).insert(6, 5)
+ * // List [ 0, 1, 2, 3, 4, 5 ]
+ * ```
+ *
+ * Since `insert()` re-indexes values, it produces a complete copy, which
+ * has `O(N)` complexity.
+ *
+ * Note: `insert` *cannot* be used in `withMutations`.
+ */
+ insert(index: number, value: T): List;
+
+ /**
+ * Returns a new List with 0 size and no values in constant time.
+ *
+ *
+ * ```js
+ * List([ 1, 2, 3, 4 ]).clear()
+ * // List []
+ * ```
+ *
+ * Note: `clear` can be used in `withMutations`.
+ */
+ clear(): List;
+
+ /**
+ * Returns a new List with the provided `values` appended, starting at this
+ * List's `size`.
+ *
+ *
+ * ```js
+ * List([ 1, 2, 3, 4 ]).push(5)
+ * // List [ 1, 2, 3, 4, 5 ]
+ * ```
+ *
+ * Note: `push` can be used in `withMutations`.
+ */
+ push(...values: Array): List;
+
+ /**
+ * Returns a new List with a size ones less than this List, excluding
+ * the last index in this List.
+ *
+ * Note: this differs from `Array#pop` because it returns a new
+ * List rather than the removed value. Use `last()` to get the last value
+ * in this List.
+ *
+ * ```js
+ * List([ 1, 2, 3, 4 ]).pop()
+ * // List[ 1, 2, 3 ]
+ * ```
+ *
+ * Note: `pop` can be used in `withMutations`.
+ */
+ pop(): List;
+
+ /**
+ * Returns a new List with the provided `values` prepended, shifting other
+ * values ahead to higher indices.
+ *
+ *
+ * ```js
+ * List([ 2, 3, 4]).unshift(1);
+ * // List [ 1, 2, 3, 4 ]
+ * ```
+ *
+ * Note: `unshift` can be used in `withMutations`.
+ */
+ unshift(...values: Array): List;
+
+ /**
+ * Returns a new List with a size ones less than this List, excluding
+ * the first index in this List, shifting all other values to a lower index.
+ *
+ * Note: this differs from `Array#shift` because it returns a new
+ * List rather than the removed value. Use `first()` to get the first
+ * value in this List.
+ *
+ *
+ * ```js
+ * List([ 0, 1, 2, 3, 4 ]).shift();
+ * // List [ 1, 2, 3, 4 ]
+ * ```
+ *
+ * Note: `shift` can be used in `withMutations`.
+ */
+ shift(): List;
+
+ /**
+ * Returns a new List with an updated value at `index` with the return
+ * value of calling `updater` with the existing value, or `notSetValue` if
+ * `index` was not set. If called with a single argument, `updater` is
+ * called with the List itself.
+ *
+ * `index` may be a negative number, which indexes back from the end of the
+ * List. `v.update(-1)` updates the last item in the List.
+ *
+ *
+ * ```js
+ * const list = List([ 'a', 'b', 'c' ])
+ * const result = list.update(2, val => val.toUpperCase())
+ * // List [ "a", "b", "C" ]
+ * ```
+ *
+ * This can be very useful as a way to "chain" a normal function into a
+ * sequence of methods. RxJS calls this "let" and lodash calls it "thru".
+ *
+ * For example, to sum a List after mapping and filtering:
+ *
+ *
+ * ```js
+ * function sum(collection) {
+ * return collection.reduce((sum, x) => sum + x, 0)
+ * }
+ *
+ * List([ 1, 2, 3 ])
+ * .map(x => x + 1)
+ * .filter(x => x % 2 === 0)
+ * .update(sum)
+ * // 6
+ * ```
+ *
+ * Note: `update(index)` can be used in `withMutations`.
+ *
+ * @see `Map#update`
+ */
+ update(index: number, notSetValue: T, updater: (value: T) => T): this;
+ update(index: number, updater: (value: T) => T): this;
+ update(updater: (value: this) => R): R;
+
+ /**
+ * Returns a new List with size `size`. If `size` is less than this
+ * List's size, the new List will exclude values at the higher indices.
+ * If `size` is greater than this List's size, the new List will have
+ * undefined values for the newly available indices.
+ *
+ * When building a new List and the final size is known up front, `setSize`
+ * used in conjunction with `withMutations` may result in the more
+ * performant construction.
+ */
+ setSize(size: number): List;
+
+
+ // Deep persistent changes
+
+ /**
+ * Returns a new List having set `value` at this `keyPath`. If any keys in
+ * `keyPath` do not exist, a new immutable Map will be created at that key.
+ *
+ * Index numbers are used as keys to determine the path to follow in
+ * the List.
+ *
+ *
+ * ```js
+ * const { List } = require('immutable')
+ * const list = List([ 0, 1, 2, List([ 3, 4 ])])
+ * list.setIn([3, 0], 999);
+ * // List [ 0, 1, 2, List [ 999, 4 ] ]
+ * ```
+ *
+ * Plain JavaScript Object or Arrays may be nested within an Immutable.js
+ * Collection, and setIn() can update those values as well, treating them
+ * immutably by creating new copies of those values with the changes applied.
+ *
+ *
+ * ```js
+ * const { List } = require('immutable')
+ * const list = List([ 0, 1, 2, { plain: 'object' }])
+ * list.setIn([3, 'plain'], 'value');
+ * // List([ 0, 1, 2, { plain: 'value' }])
+ * ```
+ *
+ * Note: `setIn` can be used in `withMutations`.
+ */
+ setIn(keyPath: Iterable, value: any): this;
+
+ /**
+ * Returns a new List having removed the value at this `keyPath`. If any
+ * keys in `keyPath` do not exist, no change will occur.
+ *
+ *
+ * ```js
+ * const { List } = require('immutable')
+ * const list = List([ 0, 1, 2, List([ 3, 4 ])])
+ * list.deleteIn([3, 0]);
+ * // List [ 0, 1, 2, List [ 4 ] ]
+ * ```
+ *
+ * Plain JavaScript Object or Arrays may be nested within an Immutable.js
+ * Collection, and removeIn() can update those values as well, treating them
+ * immutably by creating new copies of those values with the changes applied.
+ *
+ *
+ * ```js
+ * const { List } = require('immutable')
+ * const list = List([ 0, 1, 2, { plain: 'object' }])
+ * list.removeIn([3, 'plain']);
+ * // List([ 0, 1, 2, {}])
+ * ```
+ *
+ * Note: `deleteIn` *cannot* be safely used in `withMutations`.
+ *
+ * @alias removeIn
+ */
+ deleteIn(keyPath: Iterable): this;
+ removeIn(keyPath: Iterable): this;
+
+ /**
+ * Note: `updateIn` can be used in `withMutations`.
+ *
+ * @see `Map#updateIn`
+ */
+ updateIn(keyPath: Iterable, notSetValue: any, updater: (value: any) => any): this;
+ updateIn(keyPath: Iterable, updater: (value: any) => any): this;
+
+ /**
+ * Note: `mergeIn` can be used in `withMutations`.
+ *
+ * @see `Map#mergeIn`
+ */
+ mergeIn(keyPath: Iterable, ...collections: Array): this;
+
+ /**
+ * Note: `mergeDeepIn` can be used in `withMutations`.
+ *
+ * @see `Map#mergeDeepIn`
+ */
+ mergeDeepIn(keyPath: Iterable, ...collections: Array): this;
+
+ // Transient changes
+
+ /**
+ * Note: Not all methods can be safely used on a mutable collection or within
+ * `withMutations`! Check the documentation for each method to see if it
+ * allows being used in `withMutations`.
+ *
+ * @see `Map#withMutations`
+ */
+ withMutations(mutator: (mutable: this) => any): this;
+
+ /**
+ * An alternative API for withMutations()
+ *
+ * Note: Not all methods can be safely used on a mutable collection or within
+ * `withMutations`! Check the documentation for each method to see if it
+ * allows being used in `withMutations`.
+ *
+ * @see `Map#asMutable`
+ */
+ asMutable(): this;
+
+ /**
+ * @see `Map#wasAltered`
+ */
+ wasAltered(): boolean;
+
+ /**
+ * @see `Map#asImmutable`
+ */
+ asImmutable(): this;
+
+ // Sequence algorithms
+
+ /**
+ * Returns a new List with other values or collections concatenated to this one.
+ *
+ * Note: `concat` can be used in `withMutations`.
+ *
+ * @alias merge
+ */
+ concat(...valuesOrCollections: Array | C>): List;
+ merge(...collections: Array>): List;
+
+ /**
+ * Returns a new List with values passed through a
+ * `mapper` function.
+ *
+ *
+ * ```js
+ * List([ 1, 2 ]).map(x => 10 * x)
+ * // List [ 10, 20 ]
+ * ```
+ */
+ map(
+ mapper: (value: T, key: number, iter: this) => M,
+ context?: any
+ ): List;
+
+ /**
+ * Flat-maps the List, returning a new List.
+ *
+ * Similar to `list.map(...).flatten(true)`.
+ */
+ flatMap(
+ mapper: (value: T, key: number, iter: this) => Iterable,
+ context?: any
+ ): List;
+
+ /**
+ * Returns a new List with only the values for which the `predicate`
+ * function returns true.
+ *
+ * Note: `filter()` always returns a new instance, even if it results in
+ * not filtering out any values.
+ */
+ filter(
+ predicate: (value: T, index: number, iter: this) => value is F,
+ context?: any
+ ): List;
+ filter(
+ predicate: (value: T, index: number, iter: this) => any,
+ context?: any
+ ): this;
+
+ /**
+ * Returns a List "zipped" with the provided collection.
+ *
+ * Like `zipWith`, but using the default `zipper`: creating an `Array`.
+ *
+ *
+ * ```js
+ * const a = List([ 1, 2, 3 ]);
+ * const b = List([ 4, 5, 6 ]);
+ * const c = a.zip(b); // List [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
+ * ```
+ */
+ zip(other: Collection): List<[T,U]>;
+ zip(other: Collection, other2: Collection): List<[T,U,V]>;
+ zip(...collections: Array>): List;
+
+ /**
+ * Returns a List "zipped" with the provided collections.
+ *
+ * Unlike `zip`, `zipAll` continues zipping until the longest collection is
+ * exhausted. Missing values from shorter collections are filled with `undefined`.
+ *
+ *
+ * ```js
+ * const a = List([ 1, 2 ]);
+ * const b = List([ 3, 4, 5 ]);
+ * const c = a.zipAll(b); // List [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ]
+ * ```
+ *
+ * Note: Since zipAll will return a collection as large as the largest
+ * input, some results may contain undefined values. TypeScript cannot
+ * account for these without cases (as of v2.5).
+ */
+ zipAll(other: Collection): List<[T,U]>;
+ zipAll(other: Collection, other2: Collection): List<[T,U,V]>;
+ zipAll(...collections: Array>): List;
+
+ /**
+ * Returns a List "zipped" with the provided collections by using a
+ * custom `zipper` function.
+ *
+ *
+ * ```js
+ * const a = List([ 1, 2, 3 ]);
+ * const b = List([ 4, 5, 6 ]);
+ * const c = a.zipWith((a, b) => a + b, b);
+ * // List [ 5, 7, 9 ]
+ * ```
+ */
+ zipWith(
+ zipper: (value: T, otherValue: U) => Z,
+ otherCollection: Collection
+ ): List;
+ zipWith(
+ zipper: (value: T, otherValue: U, thirdValue: V) => Z,
+ otherCollection: Collection,
+ thirdCollection: Collection
+ ): List;
+ zipWith(
+ zipper: (...any: Array) => Z,
+ ...collections: Array>
+ ): List;
+ }
+
+
+ /**
+ * Immutable Map is an unordered Collection.Keyed of (key, value) pairs with
+ * `O(log32 N)` gets and `O(log32 N)` persistent sets.
+ *
+ * Iteration order of a Map is undefined, however is stable. Multiple
+ * iterations of the same Map will iterate in the same order.
+ *
+ * Map's keys can be of any type, and use `Immutable.is` to determine key
+ * equality. This allows the use of any value (including NaN) as a key.
+ *
+ * Because `Immutable.is` returns equality based on value semantics, and
+ * Immutable collections are treated as values, any Immutable collection may
+ * be used as a key.
+ *
+ *
+ * ```js
+ * const { Map, List } = require('immutable');
+ * Map().set(List([ 1 ]), 'listofone').get(List([ 1 ]));
+ * // 'listofone'
+ * ```
+ *
+ * Any JavaScript object may be used as a key, however strict identity is used
+ * to evaluate key equality. Two similar looking objects will represent two
+ * different keys.
+ *
+ * Implemented by a hash-array mapped trie.
+ */
+ declare module Map {
+
+ /**
+ * True if the provided value is a Map
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * Map.isMap({}) // false
+ * Map.isMap(Map()) // true
+ * ```
+ */
+ function isMap(maybeMap: any): maybeMap is Map;
+
+ /**
+ * Creates a new Map from alternating keys and values
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * Map.of(
+ * 'key', 'value',
+ * 'numerical value', 3,
+ * 0, 'numerical key'
+ * )
+ * // Map { 0: "numerical key", "key": "value", "numerical value": 3 }
+ * ```
+ *
+ * @deprecated Use Map([ [ 'k', 'v' ] ]) or Map({ k: 'v' })
+ */
+ function of(...keyValues: Array): Map;
+ }
+
+ /**
+ * Creates a new Immutable Map.
+ *
+ * Created with the same key value pairs as the provided Collection.Keyed or
+ * JavaScript Object or expects a Collection of [K, V] tuple entries.
+ *
+ * Note: `Map` is a factory function and not a class, and does not use the
+ * `new` keyword during construction.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * Map({ key: "value" })
+ * Map([ [ "key", "value" ] ])
+ * ```
+ *
+ * Keep in mind, when using JS objects to construct Immutable Maps, that
+ * JavaScript Object properties are always strings, even if written in a
+ * quote-less shorthand, while Immutable Maps accept keys of any type.
+ *
+ *
+ * ```js
+ * let obj = { 1: "one" }
+ * Object.keys(obj) // [ "1" ]
+ * assert.equal(obj["1"], obj[1]) // "one" === "one"
+ *
+ * let map = Map(obj)
+ * assert.notEqual(map.get("1"), map.get(1)) // "one" !== undefined
+ * ```
+ *
+ * Property access for JavaScript Objects first converts the key to a string,
+ * but since Immutable Map keys can be of any type the argument to `get()` is
+ * not altered.
+ */
+ declare function Map(collection: Iterable<[K, V]>): Map;
+ declare function Map(collection: Iterable>): Map;
+ declare function Map(obj: {[key: string]: V}): Map;
+ declare function Map(): Map;
+ declare function Map(): Map;
+
+ interface Map extends Collection.Keyed {
+
+ /**
+ * The number of entries in this Map.
+ */
+ readonly size: number;
+
+ // Persistent changes
+
+ /**
+ * Returns a new Map also containing the new key, value pair. If an equivalent
+ * key already exists in this Map, it will be replaced.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const originalMap = Map()
+ * const newerMap = originalMap.set('key', 'value')
+ * const newestMap = newerMap.set('key', 'newer value')
+ *
+ * originalMap
+ * // Map {}
+ * newerMap
+ * // Map { "key": "value" }
+ * newestMap
+ * // Map { "key": "newer value" }
+ * ```
+ *
+ * Note: `set` can be used in `withMutations`.
+ */
+ set(key: K, value: V): this;
+
+ /**
+ * Returns a new Map which excludes this `key`.
+ *
+ * Note: `delete` cannot be safely used in IE8, but is provided to mirror
+ * the ES6 collection API.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const originalMap = Map({
+ * key: 'value',
+ * otherKey: 'other value'
+ * })
+ * // Map { "key": "value", "otherKey": "other value" }
+ * originalMap.delete('otherKey')
+ * // Map { "key": "value" }
+ * ```
+ *
+ * Note: `delete` can be used in `withMutations`.
+ *
+ * @alias remove
+ */
+ delete(key: K): this;
+ remove(key: K): this;
+
+ /**
+ * Returns a new Map which excludes the provided `keys`.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const names = Map({ a: "Aaron", b: "Barry", c: "Connor" })
+ * names.deleteAll([ 'a', 'c' ])
+ * // Map { "b": "Barry" }
+ * ```
+ *
+ * Note: `deleteAll` can be used in `withMutations`.
+ *
+ * @alias removeAll
+ */
+ deleteAll(keys: Iterable): this;
+ removeAll(keys: Iterable): this;
+
+ /**
+ * Returns a new Map containing no keys or values.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * Map({ key: 'value' }).clear()
+ * // Map {}
+ * ```
+ *
+ * Note: `clear` can be used in `withMutations`.
+ */
+ clear(): this;
+
+ /**
+ * Returns a new Map having updated the value at this `key` with the return
+ * value of calling `updater` with the existing value.
+ *
+ * Similar to: `map.set(key, updater(map.get(key)))`.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const aMap = Map({ key: 'value' })
+ * const newMap = aMap.update('key', value => value + value)
+ * // Map { "key": "valuevalue" }
+ * ```
+ *
+ * This is most commonly used to call methods on collections within a
+ * structure of data. For example, in order to `.push()` onto a nested `List`,
+ * `update` and `push` can be used together:
+ *
+ *
+ * ```js
+ * const aMap = Map({ nestedList: List([ 1, 2, 3 ]) })
+ * const newMap = aMap.update('nestedList', list => list.push(4))
+ * // Map { "nestedList": List [ 1, 2, 3, 4 ] }
+ * ```
+ *
+ * When a `notSetValue` is provided, it is provided to the `updater`
+ * function when the value at the key does not exist in the Map.
+ *
+ *
+ * ```js
+ * const aMap = Map({ key: 'value' })
+ * const newMap = aMap.update('noKey', 'no value', value => value + value)
+ * // Map { "key": "value", "noKey": "no valueno value" }
+ * ```
+ *
+ * However, if the `updater` function returns the same value it was called
+ * with, then no change will occur. This is still true if `notSetValue`
+ * is provided.
+ *
+ *
+ * ```js
+ * const aMap = Map({ apples: 10 })
+ * const newMap = aMap.update('oranges', 0, val => val)
+ * // Map { "apples": 10 }
+ * assert.strictEqual(newMap, map);
+ * ```
+ *
+ * For code using ES2015 or later, using `notSetValue` is discourged in
+ * favor of function parameter default values. This helps to avoid any
+ * potential confusion with identify functions as described above.
+ *
+ * The previous example behaves differently when written with default values:
+ *
+ *
+ * ```js
+ * const aMap = Map({ apples: 10 })
+ * const newMap = aMap.update('oranges', (val = 0) => val)
+ * // Map { "apples": 10, "oranges": 0 }
+ * ```
+ *
+ * If no key is provided, then the `updater` function return value is
+ * returned as well.
+ *
+ *
+ * ```js
+ * const aMap = Map({ key: 'value' })
+ * const result = aMap.update(aMap => aMap.get('key'))
+ * // "value"
+ * ```
+ *
+ * This can be very useful as a way to "chain" a normal function into a
+ * sequence of methods. RxJS calls this "let" and lodash calls it "thru".
+ *
+ * For example, to sum the values in a Map
+ *
+ *
+ * ```js
+ * function sum(collection) {
+ * return collection.reduce((sum, x) => sum + x, 0)
+ * }
+ *
+ * Map({ x: 1, y: 2, z: 3 })
+ * .map(x => x + 1)
+ * .filter(x => x % 2 === 0)
+ * .update(sum)
+ * // 6
+ * ```
+ *
+ * Note: `update(key)` can be used in `withMutations`.
+ */
+ update(key: K, notSetValue: V, updater: (value: V) => V): this;
+ update(key: K, updater: (value: V) => V): this;
+ update(updater: (value: this) => R): R;
+
+ /**
+ * Returns a new Map resulting from merging the provided Collections
+ * (or JS objects) into this Map. In other words, this takes each entry of
+ * each collection and sets it on this Map.
+ *
+ * Note: Values provided to `merge` are shallowly converted before being
+ * merged. No nested values are altered.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const one = Map({ a: 10, b: 20, c: 30 })
+ * const two = Map({ b: 40, a: 50, d: 60 })
+ * one.merge(two) // Map { "a": 50, "b": 40, "c": 30, "d": 60 }
+ * two.merge(one) // Map { "b": 20, "a": 10, "d": 60, "c": 30 }
+ * ```
+ *
+ * Note: `merge` can be used in `withMutations`.
+ *
+ * @alias concat
+ */
+ merge(...collections: Array>): Map;
+ merge(...collections: Array<{[key: string]: C}>): Map;
+ concat(...collections: Array>): Map;
+ concat(...collections: Array<{[key: string]: C}>): Map;
+
+ /**
+ * Like `merge()`, `mergeWith()` returns a new Map resulting from merging
+ * the provided Collections (or JS objects) into this Map, but uses the
+ * `merger` function for dealing with conflicts.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const one = Map({ a: 10, b: 20, c: 30 })
+ * const two = Map({ b: 40, a: 50, d: 60 })
+ * one.mergeWith((oldVal, newVal) => oldVal / newVal, two)
+ * // { "a": 0.2, "b": 0.5, "c": 30, "d": 60 }
+ * two.mergeWith((oldVal, newVal) => oldVal / newVal, one)
+ * // { "b": 2, "a": 5, "d": 60, "c": 30 }
+ * ```
+ *
+ * Note: `mergeWith` can be used in `withMutations`.
+ */
+ mergeWith(
+ merger: (oldVal: V, newVal: V, key: K) => V,
+ ...collections: Array | {[key: string]: V}>
+ ): this;
+
+ /**
+ * Like `merge()`, but when two Collections conflict, it merges them as well,
+ * recursing deeply through the nested data.
+ *
+ * Note: Values provided to `merge` are shallowly converted before being
+ * merged. No nested values are altered unless they will also be merged at
+ * a deeper level.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const one = Map({ a: Map({ x: 10, y: 10 }), b: Map({ x: 20, y: 50 }) })
+ * const two = Map({ a: Map({ x: 2 }), b: Map({ y: 5 }), c: Map({ z: 3 }) })
+ * one.mergeDeep(two)
+ * // Map {
+ * // "a": Map { "x": 2, "y": 10 },
+ * // "b": Map { "x": 20, "y": 5 },
+ * // "c": Map { "z": 3 }
+ * // }
+ * ```
+ *
+ * Note: `mergeDeep` can be used in `withMutations`.
+ */
+ mergeDeep(...collections: Array | {[key: string]: V}>): this;
+
+ /**
+ * Like `mergeDeep()`, but when two non-Collections conflict, it uses the
+ * `merger` function to determine the resulting value.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const one = Map({ a: Map({ x: 10, y: 10 }), b: Map({ x: 20, y: 50 }) })
+ * const two = Map({ a: Map({ x: 2 }), b: Map({ y: 5 }), c: Map({ z: 3 }) })
+ * one.mergeDeepWith((oldVal, newVal) => oldVal / newVal, two)
+ * // Map {
+ * // "a": Map { "x": 5, "y": 10 },
+ * // "b": Map { "x": 20, "y": 10 },
+ * // "c": Map { "z": 3 }
+ * // }
+ * ```
+
+ * Note: `mergeDeepWith` can be used in `withMutations`.
+ */
+ mergeDeepWith(
+ merger: (oldVal: any, newVal: any, key: any) => any,
+ ...collections: Array | {[key: string]: V}>
+ ): this;
+
+
+ // Deep persistent changes
+
+ /**
+ * Returns a new Map having set `value` at this `keyPath`. If any keys in
+ * `keyPath` do not exist, a new immutable Map will be created at that key.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const originalMap = Map({
+ * subObject: Map({
+ * subKey: 'subvalue',
+ * subSubObject: Map({
+ * subSubKey: 'subSubValue'
+ * })
+ * })
+ * })
+ *
+ * const newMap = originalMap.setIn(['subObject', 'subKey'], 'ha ha!')
+ * // Map {
+ * // "subObject": Map {
+ * // "subKey": "ha ha!",
+ * // "subSubObject": Map { "subSubKey": "subSubValue" }
+ * // }
+ * // }
+ *
+ * const newerMap = originalMap.setIn(
+ * ['subObject', 'subSubObject', 'subSubKey'],
+ * 'ha ha ha!'
+ * )
+ * // Map {
+ * // "subObject": Map {
+ * // "subKey": "subvalue",
+ * // "subSubObject": Map { "subSubKey": "ha ha ha!" }
+ * // }
+ * // }
+ * ```
+ *
+ * Plain JavaScript Object or Arrays may be nested within an Immutable.js
+ * Collection, and setIn() can update those values as well, treating them
+ * immutably by creating new copies of those values with the changes applied.
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const originalMap = Map({
+ * subObject: {
+ * subKey: 'subvalue',
+ * subSubObject: {
+ * subSubKey: 'subSubValue'
+ * }
+ * }
+ * })
+ *
+ * originalMap.setIn(['subObject', 'subKey'], 'ha ha!')
+ * // Map {
+ * // "subObject": {
+ * // subKey: "ha ha!",
+ * // subSubObject: { subSubKey: "subSubValue" }
+ * // }
+ * // }
+ * ```
+ *
+ * If any key in the path exists but cannot be updated (such as a primitive
+ * like number or a custom Object like Date), an error will be thrown.
+ *
+ * Note: `setIn` can be used in `withMutations`.
+ */
+ setIn(keyPath: Iterable, value: any): this;
+
+ /**
+ * Returns a new Map having removed the value at this `keyPath`. If any keys
+ * in `keyPath` do not exist, no change will occur.
+ *
+ * Note: `deleteIn` can be used in `withMutations`.
+ *
+ * @alias removeIn
+ */
+ deleteIn(keyPath: Iterable): this;
+ removeIn(keyPath: Iterable): this;
+
+ /**
+ * Returns a new Map having applied the `updater` to the entry found at the
+ * keyPath.
+ *
+ * This is most commonly used to call methods on collections nested within a
+ * structure of data. For example, in order to `.push()` onto a nested `List`,
+ * `updateIn` and `push` can be used together:
+ *
+ *
+ * ```js
+ * const { Map, List } = require('immutable')
+ * const map = Map({ inMap: Map({ inList: List([ 1, 2, 3 ]) }) })
+ * const newMap = map.updateIn(['inMap', 'inList'], list => list.push(4))
+ * // Map { "inMap": Map { "inList": List [ 1, 2, 3, 4 ] } }
+ * ```
+ *
+ * If any keys in `keyPath` do not exist, new Immutable `Map`s will
+ * be created at those keys. If the `keyPath` does not already contain a
+ * value, the `updater` function will be called with `notSetValue`, if
+ * provided, otherwise `undefined`.
+ *
+ *
+ * ```js
+ * const map = Map({ a: Map({ b: Map({ c: 10 }) }) })
+ * const newMap = map.updateIn(['a', 'b', 'c'], val => val * 2)
+ * // Map { "a": Map { "b": Map { "c": 20 } } }
+ * ```
+ *
+ * If the `updater` function returns the same value it was called with, then
+ * no change will occur. This is still true if `notSetValue` is provided.
+ *
+ *
+ * ```js
+ * const map = Map({ a: Map({ b: Map({ c: 10 }) }) })
+ * const newMap = map.updateIn(['a', 'b', 'x'], 100, val => val)
+ * // Map { "a": Map { "b": Map { "c": 10 } } }
+ * assert.strictEqual(newMap, aMap)
+ * ```
+ *
+ * For code using ES2015 or later, using `notSetValue` is discourged in
+ * favor of function parameter default values. This helps to avoid any
+ * potential confusion with identify functions as described above.
+ *
+ * The previous example behaves differently when written with default values:
+ *
+ *
+ * ```js
+ * const map = Map({ a: Map({ b: Map({ c: 10 }) }) })
+ * const newMap = map.updateIn(['a', 'b', 'x'], (val = 100) => val)
+ * // Map { "a": Map { "b": Map { "c": 10, "x": 100 } } }
+ * ```
+ *
+ * Plain JavaScript Object or Arrays may be nested within an Immutable.js
+ * Collection, and updateIn() can update those values as well, treating them
+ * immutably by creating new copies of those values with the changes applied.
+ *
+ *
+ * ```js
+ * const map = Map({ a: { b: { c: 10 } } })
+ * const newMap = map.updateIn(['a', 'b', 'c'], val => val * 2)
+ * // Map { "a": { b: { c: 20 } } }
+ * ```
+ *
+ * If any key in the path exists but cannot be updated (such as a primitive
+ * like number or a custom Object like Date), an error will be thrown.
+ *
+ * Note: `updateIn` can be used in `withMutations`.
+ */
+ updateIn(keyPath: Iterable, notSetValue: any, updater: (value: any) => any): this;
+ updateIn(keyPath: Iterable, updater: (value: any) => any): this;
+
+ /**
+ * A combination of `updateIn` and `merge`, returning a new Map, but
+ * performing the merge at a point arrived at by following the keyPath.
+ * In other words, these two lines are equivalent:
+ *
+ * ```js
+ * map.updateIn(['a', 'b', 'c'], abc => abc.merge(y))
+ * map.mergeIn(['a', 'b', 'c'], y)
+ * ```
+ *
+ * Note: `mergeIn` can be used in `withMutations`.
+ */
+ mergeIn(keyPath: Iterable, ...collections: Array): this;
+
+ /**
+ * A combination of `updateIn` and `mergeDeep`, returning a new Map, but
+ * performing the deep merge at a point arrived at by following the keyPath.
+ * In other words, these two lines are equivalent:
+ *
+ * ```js
+ * map.updateIn(['a', 'b', 'c'], abc => abc.mergeDeep(y))
+ * map.mergeDeepIn(['a', 'b', 'c'], y)
+ * ```
+ *
+ * Note: `mergeDeepIn` can be used in `withMutations`.
+ */
+ mergeDeepIn(keyPath: Iterable, ...collections: Array): this;
+
+ // Transient changes
+
+ /**
+ * Every time you call one of the above functions, a new immutable Map is
+ * created. If a pure function calls a number of these to produce a final
+ * return value, then a penalty on performance and memory has been paid by
+ * creating all of the intermediate immutable Maps.
+ *
+ * If you need to apply a series of mutations to produce a new immutable
+ * Map, `withMutations()` creates a temporary mutable copy of the Map which
+ * can apply mutations in a highly performant manner. In fact, this is
+ * exactly how complex mutations like `merge` are done.
+ *
+ * As an example, this results in the creation of 2, not 4, new Maps:
+ *
+ *
+ * ```js
+ * const { Map } = require('immutable')
+ * const map1 = Map()
+ * const map2 = map1.withMutations(map => {
+ * map.set('a', 1).set('b', 2).set('c', 3)
+ * })
+ * assert.equal(map1.size, 0)
+ * assert.equal(map2.size, 3)
+ * ```
+ *
+ * Note: Not all methods can be used on a mutable collection or within
+ * `withMutations`! Read the documentation for each method to see if it
+ * is safe to use in `withMutations`.
+ */
+ withMutations(mutator: (mutable: this) => any): this;
+
+ /**
+ * Another way to avoid creation of intermediate Immutable maps is to create
+ * a mutable copy of this collection. Mutable copies *always* return `this`,
+ * and thus shouldn't be used for equality. Your function should never return
+ * a mutable copy of a collection, only use it internally to create a new
+ * collection.
+ *
+ * If possible, use `withMutations` to work with temporary mutable copies as
+ * it provides an easier to use API and considers many common optimizations.
+ *
+ * Note: if the collection is already mutable, `asMutable` returns itself.
+ *
+ * Note: Not all methods can be used on a mutable collection or within
+ * `withMutations`! Read the documentation for each method to see if it
+ * is safe to use in `withMutations`.
+ *
+ * @see `Map#asImmutable`
+ */
+ asMutable(): this;
+
+ /**
+ * Returns true if this is a mutable copy (see `asMutable()`) and mutative
+ * alterations have been applied.
+ *
+ * @see `Map#asMutable`
+ */
+ wasAltered(): boolean;
+
+ /**
+ * The yin to `asMutable`'s yang. Because it applies to mutable collections,
+ * this operation is *mutable* and may return itself (though may not
+ * return itself, i.e. if the result is an empty collection). Once
+ * performed, the original mutable copy must no longer be mutated since it
+ * may be the immutable result.
+ *
+ * If possible, use `withMutations` to work with temporary mutable copies as
+ * it provides an easier to use API and considers many common optimizations.
+ *
+ * @see `Map#asMutable`
+ */
+ asImmutable(): this;
+
+ // Sequence algorithms
+
+ /**
+ * Returns a new Map with values passed through a
+ * `mapper` function.
+ *
+ * Map({ a: 1, b: 2 }).map(x => 10 * x)
+ * // Map { a: 10, b: 20 }
+ */
+ map(
+ mapper: (value: V, key: K, iter: this) => M,
+ context?: any
+ ): Map;
+
+ /**
+ * @see Collection.Keyed.mapKeys
+ */
+ mapKeys(
+ mapper: (key: K, value: V, iter: this) => M,
+ context?: any
+ ): Map;
+
+ /**
+ * @see Collection.Keyed.mapEntries
+ */
+ mapEntries(
+ mapper: (entry: [K, V], index: number, iter: this) => [KM, VM],
+ context?: any
+ ): Map;
+
+ /**
+ * Flat-maps the Map, returning a new Map.
+ *
+ * Similar to `data.map(...).flatten(true)`.
+ */
+ flatMap(
+ mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
+ context?: any
+ ): Map;
+
+ /**
+ * Returns a new Map with only the entries for which the `predicate`
+ * function returns true.
+ *
+ * Note: `filter()` always returns a new instance, even if it results in
+ * not filtering out any values.
+ */
+ filter(
+ predicate: (value: V, key: K, iter: this) => value is F,
+ context?: any
+ ): Map;
+ filter(
+ predicate: (value: V, key: K, iter: this) => any,
+ context?: any
+ ): this;
+
+ /**
+ * @see Collection.Keyed.flip
+ */
+ flip(): Map;
+ }
+
+
+ /**
+ * A type of Map that has the additional guarantee that the iteration order of
+ * entries will be the order in which they were set().
+ *
+ * The iteration behavior of OrderedMap is the same as native ES6 Map and
+ * JavaScript Object.
+ *
+ * Note that `OrderedMap` are more expensive than non-ordered `Map` and may
+ * consume more memory. `OrderedMap#set` is amortized O(log32 N), but not
+ * stable.
+ */
+
+ declare module OrderedMap {
+
+ /**
+ * True if the provided value is an OrderedMap.
+ */
+ function isOrderedMap(maybeOrderedMap: any): maybeOrderedMap is OrderedMap;
+ }
+
+ /**
+ * Creates a new Immutable OrderedMap.
+ *
+ * Created with the same key value pairs as the provided Collection.Keyed or
+ * JavaScript Object or expects a Collection of [K, V] tuple entries.
+ *
+ * The iteration order of key-value pairs provided to this constructor will
+ * be preserved in the OrderedMap.
+ *
+ * let newOrderedMap = OrderedMap({key: "value"})
+ * let newOrderedMap = OrderedMap([["key", "value"]])
+ *
+ * Note: `OrderedMap` is a factory function and not a class, and does not use
+ * the `new` keyword during construction.
+ */
+ declare function OrderedMap(collection: Iterable<[K, V]>): OrderedMap;
+ declare function OrderedMap(collection: Iterable>): OrderedMap;
+ declare function OrderedMap(obj: {[key: string]: V}): OrderedMap;
+ declare function OrderedMap(): OrderedMap;
+ declare function OrderedMap(): OrderedMap;
+
+ interface OrderedMap extends Map {
+
+ /**
+ * The number of entries in this OrderedMap.
+ */
+ readonly size: number;
+
+ /**
+ * Returns a new OrderedMap also containing the new key, value pair. If an
+ * equivalent key already exists in this OrderedMap, it will be replaced
+ * while maintaining the existing order.
+ *
+ *
+ * ```js
+ * const { OrderedMap } = require('immutable')
+ * const originalMap = OrderedMap({a:1, b:1, c:1})
+ * const updatedMap = originalMap.set('b', 2)
+ *
+ * originalMap
+ * // OrderedMap {a: 1, b: 1, c: 1}
+ * updatedMap
+ * // OrderedMap {a: 1, b: 2, c: 1}
+ * ```
+ *
+ * Note: `set` can be used in `withMutations`.
+ */
+ set(key: K, value: V): this;
+
+ /**
+ * Returns a new OrderedMap resulting from merging the provided Collections
+ * (or JS objects) into this OrderedMap. In other words, this takes each
+ * entry of each collection and sets it on this OrderedMap.
+ *
+ * Note: Values provided to `merge` are shallowly converted before being
+ * merged. No nested values are altered.
+ *
+ *
+ * ```js
+ * const { OrderedMap } = require('immutable')
+ * const one = OrderedMap({ a: 10, b: 20, c: 30 })
+ * const two = OrderedMap({ b: 40, a: 50, d: 60 })
+ * one.merge(two) // OrderedMap { "a": 50, "b": 40, "c": 30, "d": 60 }
+ * two.merge(one) // OrderedMap { "b": 20, "a": 10, "d": 60, "c": 30 }
+ * ```
+ *
+ * Note: `merge` can be used in `withMutations`.
+ *
+ * @alias concat
+ */
+ merge(...collections: Array>): OrderedMap;
+ merge(...collections: Array<{[key: string]: C}>): OrderedMap;
+ concat(...collections: Array>): OrderedMap;
+ concat(...collections: Array<{[key: string]: C}>): OrderedMap;
+
+ // Sequence algorithms
+
+ /**
+ * Returns a new OrderedMap with values passed through a
+ * `mapper` function.
+ *
+ * OrderedMap({ a: 1, b: 2 }).map(x => 10 * x)
+ * // OrderedMap { "a": 10, "b": 20 }
+ *
+ * Note: `map()` always returns a new instance, even if it produced the same
+ * value at every step.
+ */
+ map(
+ mapper: (value: V, key: K, iter: this) => M,
+ context?: any
+ ): OrderedMap;
+
+ /**
+ * @see Collection.Keyed.mapKeys
+ */
+ mapKeys(
+ mapper: (key: K, value: V, iter: this) => M,
+ context?: any
+ ): OrderedMap;
+
+ /**
+ * @see Collection.Keyed.mapEntries
+ */
+ mapEntries(
+ mapper: (entry: [K, V], index: number, iter: this) => [KM, VM],
+ context?: any
+ ): OrderedMap;
+
+ /**
+ * Flat-maps the OrderedMap, returning a new OrderedMap.
+ *
+ * Similar to `data.map(...).flatten(true)`.
+ */
+ flatMap(
+ mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
+ context?: any
+ ): OrderedMap;
+
+ /**
+ * Returns a new OrderedMap with only the entries for which the `predicate`
+ * function returns true.
+ *
+ * Note: `filter()` always returns a new instance, even if it results in
+ * not filtering out any values.
+ */
+ filter(
+ predicate: (value: V, key: K, iter: this) => value is F,
+ context?: any
+ ): OrderedMap;
+ filter(
+ predicate: (value: V, key: K, iter: this) => any,
+ context?: any
+ ): this;
+
+ /**
+ * @see Collection.Keyed.flip
+ */
+ flip(): OrderedMap;
+ }
+
+
+ /**
+ * A Collection of unique values with `O(log32 N)` adds and has.
+ *
+ * When iterating a Set, the entries will be (value, value) pairs. Iteration
+ * order of a Set is undefined, however is stable. Multiple iterations of the
+ * same Set will iterate in the same order.
+ *
+ * Set values, like Map keys, may be of any type. Equality is determined using
+ * `Immutable.is`, enabling Sets to uniquely include other Immutable
+ * collections, custom value types, and NaN.
+ */
+ declare module Set {
+
+ /**
+ * True if the provided value is a Set
+ */
+ function isSet(maybeSet: any): maybeSet is Set;
+
+ /**
+ * Creates a new Set containing `values`.
+ */
+ function of(...values: Array): Set;
+
+ /**
+ * `Set.fromKeys()` creates a new immutable Set containing the keys from
+ * this Collection or JavaScript Object.
+ */
+ function fromKeys(iter: Collection): Set;
+ function fromKeys(obj: {[key: string]: any}): Set;
+
+ /**
+ * `Set.intersect()` creates a new immutable Set that is the intersection of
+ * a collection of other sets.
+ *
+ * ```js
+ * const { Set } = require('immutable')
+ * const intersected = Set.intersect([
+ * Set([ 'a', 'b', 'c' ])
+ * Set([ 'c', 'a', 't' ])
+ * ])
+ * // Set [ "a", "c"" ]
+ * ```
+ */
+ function intersect(sets: Iterable>): Set;
+
+ /**
+ * `Set.union()` creates a new immutable Set that is the union of a
+ * collection of other sets.
+ *
+ * ```js
+ * const { Set } = require('immutable')
+ * const unioned = Set.union([
+ * Set([ 'a', 'b', 'c' ])
+ * Set([ 'c', 'a', 't' ])
+ * ])
+ * // Set [ "a", "b", "c", "t"" ]
+ * ```
+ */
+ function union(sets: Iterable>): Set;
+ }
+
+ /**
+ * Create a new immutable Set containing the values of the provided
+ * collection-like.
+ *
+ * Note: `Set` is a factory function and not a class, and does not use the
+ * `new` keyword during construction.
+ */
+ declare function Set(): Set;
+ declare function Set(): Set;
+ declare function Set(collection: Iterable): Set;
+
+ interface Set extends Collection.Set {
+
+ /**
+ * The number of items in this Set.
+ */
+ readonly size: number;
+
+ // Persistent changes
+
+ /**
+ * Returns a new Set which also includes this value.
+ *
+ * Note: `add` can be used in `withMutations`.
+ */
+ add(value: T): this;
+
+ /**
+ * Returns a new Set which excludes this value.
+ *
+ * Note: `delete` can be used in `withMutations`.
+ *
+ * Note: `delete` **cannot** be safely used in IE8, use `remove` if
+ * supporting old browsers.
+ *
+ * @alias remove
+ */
+ delete(value: T): this;
+ remove(value: T): this;
+
+ /**
+ * Returns a new Set containing no values.
+ *
+ * Note: `clear` can be used in `withMutations`.
+ */
+ clear(): this;
+
+ /**
+ * Returns a Set including any value from `collections` that does not already
+ * exist in this Set.
+ *
+ * Note: `union` can be used in `withMutations`.
+ * @alias merge
+ * @alias concat
+ */
+ union(...collections: Array>): Set;
+ merge(...collections: Array>): Set;
+ concat(...collections: Array>): Set;
+
+ /**
+ * Returns a Set which has removed any values not also contained
+ * within `collections`.
+ *
+ * Note: `intersect` can be used in `withMutations`.
+ */
+ intersect(...collections: Array>): this;
+
+ /**
+ * Returns a Set excluding any values contained within `collections`.
+ *
+ *
+ * ```js
+ * const { OrderedSet } = require('immutable')
+ * OrderedSet([ 1, 2, 3 ]).subtract([1, 3])
+ * // OrderedSet [2]
+ * ```
+ *
+ * Note: `subtract` can be used in `withMutations`.
+ */
+ subtract(...collections: Array>): this;
+
+
+ // Transient changes
+
+ /**
+ * Note: Not all methods can be used on a mutable collection or within
+ * `withMutations`! Check the documentation for each method to see if it
+ * mentions being safe to use in `withMutations`.
+ *
+ * @see `Map#withMutations`
+ */
+ withMutations(mutator: (mutable: this) => any): this;
+
+ /**
+ * Note: Not all methods can be used on a mutable collection or within
+ * `withMutations`! Check the documentation for each method to see if it
+ * mentions being safe to use in `withMutations`.
+ *
+ * @see `Map#asMutable`
+ */
+ asMutable(): this;
+
+ /**
+ * @see `Map#wasAltered`
+ */
+ wasAltered(): boolean;
+
+ /**
+ * @see `Map#asImmutable`
+ */
+ asImmutable(): this;
+
+ // Sequence algorithms
+
+ /**
+ * Returns a new Set with values passed through a
+ * `mapper` function.
+ *
+ * Set([1,2]).map(x => 10 * x)
+ * // Set [10,20]
+ */
+ map(
+ mapper: (value: T, key: T, iter: this) => M,
+ context?: any
+ ): Set;
+
+ /**
+ * Flat-maps the Set, returning a new Set.
+ *
+ * Similar to `set.map(...).flatten(true)`.
+ */
+ flatMap(
+ mapper: (value: T, key: T, iter: this) => Iterable,
+ context?: any
+ ): Set;
+
+ /**
+ * Returns a new Set with only the values for which the `predicate`
+ * function returns true.
+ *
+ * Note: `filter()` always returns a new instance, even if it results in
+ * not filtering out any values.
+ */
+ filter(
+ predicate: (value: T, key: T, iter: this) => value is F,
+ context?: any
+ ): Set;
+ filter(
+ predicate: (value: T, key: T, iter: this) => any,
+ context?: any
+ ): this;
+ }
+
+
+ /**
+ * A type of Set that has the additional guarantee that the iteration order of
+ * values will be the order in which they were `add`ed.
+ *
+ * The iteration behavior of OrderedSet is the same as native ES6 Set.
+ *
+ * Note that `OrderedSet` are more expensive than non-ordered `Set` and may
+ * consume more memory. `OrderedSet#add` is amortized O(log32 N), but not
+ * stable.
+ */
+ declare module OrderedSet {
+
+ /**
+ * True if the provided value is an OrderedSet.
+ */
+ function isOrderedSet(maybeOrderedSet: any): boolean;
+
+ /**
+ * Creates a new OrderedSet containing `values`.
+ */
+ function of(...values: Array): OrderedSet;
+
+ /**
+ * `OrderedSet.fromKeys()` creates a new immutable OrderedSet containing
+ * the keys from this Collection or JavaScript Object.
+ */
+ function fromKeys(iter: Collection): OrderedSet;
+ function fromKeys(obj: {[key: string]: any}): OrderedSet;
+ }
+
+ /**
+ * Create a new immutable OrderedSet containing the values of the provided
+ * collection-like.
+ *
+ * Note: `OrderedSet` is a factory function and not a class, and does not use
+ * the `new` keyword during construction.
+ */
+ declare function OrderedSet(): OrderedSet;
+ declare function OrderedSet(): OrderedSet;
+ declare function OrderedSet(collection: Iterable): OrderedSet;
+
+ interface OrderedSet extends Set {
+
+ /**
+ * The number of items in this OrderedSet.
+ */
+ readonly size: number;
+
+ /**
+ * Returns an OrderedSet including any value from `collections` that does
+ * not already exist in this OrderedSet.
+ *
+ * Note: `union` can be used in `withMutations`.
+ * @alias merge
+ * @alias concat
+ */
+ union(...collections: Array>): OrderedSet;
+ merge(...collections: Array>): OrderedSet;
+ concat(...collections: Array>): OrderedSet;
+
+ // Sequence algorithms
+
+ /**
+ * Returns a new Set with values passed through a
+ * `mapper` function.
+ *
+ * OrderedSet([ 1, 2 ]).map(x => 10 * x)
+ * // OrderedSet [10, 20]
+ */
+ map(
+ mapper: (value: T, key: T, iter: this) => M,
+ context?: any
+ ): OrderedSet;
+
+ /**
+ * Flat-maps the OrderedSet, returning a new OrderedSet.
+ *
+ * Similar to `set.map(...).flatten(true)`.
+ */
+ flatMap(
+ mapper: (value: T, key: T, iter: this) => Iterable,
+ context?: any
+ ): OrderedSet;
+
+ /**
+ * Returns a new OrderedSet with only the values for which the `predicate`
+ * function returns true.
+ *
+ * Note: `filter()` always returns a new instance, even if it results in
+ * not filtering out any values.
+ */
+ filter(
+ predicate: (value: T, key: T, iter: this) => value is F,
+ context?: any
+ ): OrderedSet;
+ filter(
+ predicate: (value: T, key: T, iter: this) => any,
+ context?: any
+ ): this;
+
+ /**
+ * Returns an OrderedSet of the same type "zipped" with the provided
+ * collections.
+ *
+ * Like `zipWith`, but using the default `zipper`: creating an `Array`.
+ *
+ * ```js
+ * const a = OrderedSet([ 1, 2, 3 ])
+ * const b = OrderedSet([ 4, 5, 6 ])
+ * const c = a.zip(b)
+ * // OrderedSet [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
+ * ```
+ */
+ zip(other: Collection): OrderedSet<[T,U]>;
+ zip(other1: Collection, other2: Collection): OrderedSet<[T,U,V]>;
+ zip(...collections: Array>): OrderedSet;
+
+ /**
+ * Returns a OrderedSet of the same type "zipped" with the provided
+ * collections.
+ *
+ * Unlike `zip`, `zipAll` continues zipping until the longest collection is
+ * exhausted. Missing values from shorter collections are filled with `undefined`.
+ *
+ * ```js
+ * const a = OrderedSet([ 1, 2 ]);
+ * const b = OrderedSet([ 3, 4, 5 ]);
+ * const c = a.zipAll(b); // OrderedSet [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ]
+ * ```
+ *
+ * Note: Since zipAll will return a collection as large as the largest
+ * input, some results may contain undefined values. TypeScript cannot
+ * account for these without cases (as of v2.5).
+ */
+ zipAll(other: Collection): OrderedSet<[T,U]>;
+ zipAll(other1: Collection, other2: Collection): OrderedSet<[T,U,V]>;
+ zipAll(...collections: Array>): OrderedSet