@finsemble/finsemble-core 6.1.4 → 6.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.js +12 -12
- package/.nycrc.json +7 -7
- package/README.md +24 -24
- package/assets/fonts/LICENSE.txt +202 -202
- package/configs/core/config.json +214 -214
- package/configs/core/securityPolicies.json +24 -24
- package/configs/core/services.json +233 -233
- package/configs/schemas/README.md +1 -1
- package/configs/schemas/fileBasedSchemas/appdConfigFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/applicationConfigFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/componentsFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/coreConfigFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/dashbarFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/manifestFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/securityPoliciesFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/servicesFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/uiComponentsFile.schema.json +5 -5
- package/configs/schemas/fileBasedSchemas/workspacesFile.schema.json +5 -5
- package/configs/schemas/finsemble.schema.json +4006 -4006
- package/dist/FSBL.js +1 -1
- package/dist/clients/Interop/FinsembleDesktopAgent.md +154 -154
- package/dist/clients/Interop/tsconfig.json +7 -7
- package/dist/clients/Startup/README.md +28 -28
- package/dist/clients/dragAndDropAssets/dragAndDropScrim.css +54 -54
- package/dist/clients/dragAndDropAssets/ff-delete-circle.svg +10 -10
- package/dist/clients/dragAndDropAssets/ff-share.svg +13 -13
- package/dist/components/system/notification/ff-close.svg +14 -14
- package/dist/components/system/notification/finsemble_logo_white.svg +15 -15
- package/dist/components/system/notification/notification.html +155 -155
- package/dist/configs/core/config.json +214 -214
- package/dist/configs/core/securityPolicies.json +24 -24
- package/dist/configs/core/services.json +233 -233
- package/dist/configs/schemas/README.md +1 -1
- package/dist/configs/schemas/fileBasedSchemas/appdConfigFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/applicationConfigFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/componentsFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/coreConfigFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/dashbarFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/manifestFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/securityPoliciesFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/servicesFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/uiComponentsFile.schema.json +5 -5
- package/dist/configs/schemas/fileBasedSchemas/workspacesFile.schema.json +5 -5
- package/dist/configs/schemas/finsemble.schema.json +4006 -4006
- package/dist/finsemble-javascript-adapter.js +1 -1
- package/dist/index.js +1 -1
- package/dist/javascript-adapter-example-app.html +37 -37
- package/dist/services/Interop/DevTools.tsx +71 -71
- package/dist/services/Interop/Interop.html +15 -15
- package/dist/services/Interop/InteropService.js +1 -1
- package/dist/services/Interop/InteropService.md +148 -148
- package/dist/services/Interop/InteropServiceUI.css +12 -12
- package/dist/services/Interop/InteropServiceUI.js +1 -1
- package/dist/services/Interop/InteropServiceUI.tsx +39 -39
- package/dist/services/Interop/devtoolsEnhancer.tsx +63 -63
- package/dist/services/Interop/tsconfig.json +7 -7
- package/dist/services/ServiceTemplate.md +39 -39
- package/dist/services/assimilation/assimilation.html +18 -18
- package/dist/services/assimilation/assimilationService.js +1 -1
- package/dist/services/authentication/authentication.html +17 -17
- package/dist/services/authentication/authenticationService.js +1 -1
- package/dist/services/authentication/dialogSignOn.html +199 -199
- package/dist/services/config/config.html +17 -17
- package/dist/services/config/configService.js +1 -1
- package/dist/services/dataStore/dataStore.html +18 -18
- package/dist/services/dataStore/dataStoreService.js +1 -1
- package/dist/services/hotkeys/hotkeys.html +18 -18
- package/dist/services/hotkeys/hotkeysService.js +1 -1
- package/dist/services/linker/linker.html +18 -18
- package/dist/services/linker/linkerService.js +1 -1
- package/dist/services/logger/logger.html +18 -18
- package/dist/services/logger/loggerService.js +1 -1
- package/dist/services/logger/loggerUI.js +1 -1
- package/dist/services/logger/src/app.css +860 -860
- package/dist/services/logger/src/components/Views/Logs/rightPanel/consoleView.css +379 -379
- package/dist/services/logger/src/components/objectInspector/README.md +1 -1
- package/dist/services/notification/notification.html +11 -11
- package/dist/services/notification/notificationService.js +1 -1
- package/dist/services/preferences/preferencesService.js +1 -1
- package/dist/services/router/router.html +18 -18
- package/dist/services/router/routerService.js +1 -1
- package/dist/services/search/search.html +17 -17
- package/dist/services/search/searchService.js +1 -1
- package/dist/services/storage/adapters/instrumentedIndexedDBAdapter.js +1 -1
- package/dist/services/storage/storage.html +17 -17
- package/dist/services/storage/storageService.js +1 -1
- package/dist/services/systemManager/bootTasks/testTasks/_aReadMe.md +119 -119
- package/dist/services/systemManager/systemManager.html +24 -24
- package/dist/services/systemManager/systemManager.js +1 -1
- package/dist/services/window/Docking/GroupRequirements.md +18 -18
- package/dist/services/window/Splintering/SplinterAgentSlave.html +13 -13
- package/dist/services/window/Splintering/SplinterAgentSlave.js +1 -1
- package/dist/services/window/Splintering/Splintering.md +118 -118
- package/dist/services/window/StackedWindowManager/StackRequirements.md +23 -23
- package/dist/services/window/WindowBehaviorRequirements.md +25 -25
- package/dist/services/window/windowService.html +10 -10
- package/dist/services/window/windowService.js +1 -1
- package/dist/services/workspace/dev-docs/importExportFormat.md +51 -51
- package/dist/services/workspace/dev-docs/remotelyPersistedWorkspaces.md +62 -62
- package/dist/services/workspace/workspace.html +18 -18
- package/dist/services/workspace/workspace.schema.json +48 -48
- package/dist/services/workspace/workspaceService.js +1 -1
- package/package.json +1 -1
- package/tsconfig.json +23 -23
- package/types/index.d.ts +40 -55
- package/types/index.tsbuildinfo +1 -1
- package/types.tsconfig.json +15 -15
|
@@ -1,154 +1,154 @@
|
|
|
1
|
-
# FinsembleDesktopAgent
|
|
2
|
-
|
|
3
|
-
This file contains an implementation of the FDC3 "DesktopAgent" type (https://fdc3.finos.org/docs/api/ref/DesktopAgent).
|
|
4
|
-
It implements version 1.2 of FDC3. We'll refer to the code within this file as "the desktop agent".
|
|
5
|
-
|
|
6
|
-
The desktop agent is intended to be the primary API that developers use to implement "data integration" - e.g. sharing
|
|
7
|
-
"context" between apps and raising "intents" between apps. It is available through two global objects:
|
|
8
|
-
|
|
9
|
-
`window.fdc3` - This global is automatically injected by Finsemble's preload. Developers in capital markets will use
|
|
10
|
-
this interface.
|
|
11
|
-
|
|
12
|
-
`FSBL.Interop` - Provides the identical interface but with a non-fdc3 branding. Developers outside of capital markets
|
|
13
|
-
will be more likely to accept this interface.
|
|
14
|
-
|
|
15
|
-
The desktop agent communicates with Finsemble's "Interop Service". The Interop Service acts as a "resolver", routing
|
|
16
|
-
messages to clients (e.g. apps / windows), maintaining a global store of contexts, and providing connectivity to modules
|
|
17
|
-
(and eventually, plugins) that integrate with interop.
|
|
18
|
-
|
|
19
|
-
## Design Philosophy
|
|
20
|
-
|
|
21
|
-
This client is intentionally "thin". As much logic as possible has been pushed into the Interop Service by sending
|
|
22
|
-
messages over router calls. This thin design allows the client to be easily ported to and maintained in Finsemble's
|
|
23
|
-
native adapters (e.g. .Net & Java).
|
|
24
|
-
|
|
25
|
-
## Implementation Details
|
|
26
|
-
|
|
27
|
-
### Mechanics
|
|
28
|
-
|
|
29
|
-
The desktop agent communicates with the Interop Service in three ways:
|
|
30
|
-
|
|
31
|
-
1. The desktop agent sends messages for which there is no reply necessary. e.g. broadcast(), joinChannels(),
|
|
32
|
-
raiseIntent()
|
|
33
|
-
|
|
34
|
-
2. The interop service sends unsolicited messages to the desktop agent for which no reply is necessary. e.g. context
|
|
35
|
-
changes and intents
|
|
36
|
-
|
|
37
|
-
3. The desktop agent queries the interop service and expects a reply. e.g. getCurrentContext(), findIntents()
|
|
38
|
-
|
|
39
|
-
These communications are handled via two RouterClient channels. The Interop Service listens on a responder to "well
|
|
40
|
-
known" channel: type "SERVER_CHANNEL". Each desktop agent (typically one desktop agent per Finsemble window) also
|
|
41
|
-
listens on its own responder. Since both client and server are running responders (query/response) all messages are
|
|
42
|
-
queries, though only in case #3 above does the code wait for a response. Responses are always sent though they are empty
|
|
43
|
-
for messages that don't require responses.
|
|
44
|
-
|
|
45
|
-
### Message Protocol
|
|
46
|
-
|
|
47
|
-
The client and server communicate with a message protocol composed of Flux Standard Actions (FSA). These messages are
|
|
48
|
-
defined in `types.ts`. The union of all possible messages is the type `InteropMessage`. These messages are private, part
|
|
49
|
-
of our internal implementation, and are subject to change with each release. External developers should not manually
|
|
50
|
-
access these messages.
|
|
51
|
-
|
|
52
|
-
The messages are strongly typed using Typescript and reference types that are defined by the FDC3 standard. Finsemble's
|
|
53
|
-
core package now contains a copy of the FDC3 standard typedefs in `src/typedefs/FDC3` which serves as the single source
|
|
54
|
-
of truth. There have been some modifications to these typedefs based on areas of the spec that were found to be lacking.
|
|
55
|
-
After 1.2 is released we should revisit these changes vis a vis the updated spec, and release a PR back to FDC3 with any
|
|
56
|
-
changes that we believe are still relevant.
|
|
57
|
-
|
|
58
|
-
As new versions of FDC3 are released, the typedefs should be updated, along with our implementation.
|
|
59
|
-
|
|
60
|
-
Each FSA contains a "meta" section of type `InteropMeta`. This contains information that is independent of the business
|
|
61
|
-
logic of each message. Business logic runs against the "payload" data. The unique uuid of the desktop agent is always
|
|
62
|
-
part of the meta information along with either an "href" or "path" element that can positively identify web and native
|
|
63
|
-
clients respectively. The Interop Service uses meta information in order to direct the message to the correct set of
|
|
64
|
-
business logic (e.g. looking up the client by uuid) and may use this information for security or rules engine
|
|
65
|
-
processing.
|
|
66
|
-
|
|
67
|
-
### Initialization
|
|
68
|
-
|
|
69
|
-
The most complex part of the desktop agent is its startup sequence. The desktop agent must create a local RouterClient
|
|
70
|
-
responder on a unique channel name in order to receive messages from the Interop Service such as broadcasts and raised
|
|
71
|
-
intents. The desktop agent registers itself with the Interop Service by passing a message that contains the unique
|
|
72
|
-
RouterClient channel that the desktop agent has opened.
|
|
73
|
-
|
|
74
|
-
While the FDC3 1.2 specification now supports the "fdc3Ready" event, extenuating circumstances led us to take a more
|
|
75
|
-
robust approach to initialization. We do not auto-initialize the desktop agent (like we do with other Finsemble
|
|
76
|
-
clients). Instead, the desktop agent is initialized _only when an API call is actually invoked_.
|
|
77
|
-
|
|
78
|
-
This strategy prevents every single Finsemble window from registering with the InteropService. Only windows that have
|
|
79
|
-
made FDC3 calls will initialize and therefore be registered. This also implicitly allows us to tie feature functionality
|
|
80
|
-
to usage of the API. For instance, the linker can now display automatically by virtue of an implicit FDC3 registration.
|
|
81
|
-
|
|
82
|
-
To implement this strategy we took the approach of automatically providing the fdc3 interface _immediately_ on the
|
|
83
|
-
browser window. The first fdc3 call will trigger intialization. That call, and any subsequent calls, will be "queued"
|
|
84
|
-
until registration is complete and then sequentially sent to the service.
|
|
85
|
-
|
|
86
|
-
This mechanism also conveniently handles waiting for the underlying FSBL event and protects developers from the common
|
|
87
|
-
problem of failing to wait for ready events.
|
|
88
|
-
|
|
89
|
-
A `shouldAutoconnect` function is included but is dormant. This can be used in the future should we find use cases that
|
|
90
|
-
require the desktop agent to connect prior to any API invocations.
|
|
91
|
-
|
|
92
|
-
### Channels
|
|
93
|
-
|
|
94
|
-
The FDC3 specification implies an object oriented approach, with channels being created using a factory
|
|
95
|
-
(https://fdc3.finos.org/docs/api/ref/DesktopAgent#getorcreatechannel). This interface has been implemented but the
|
|
96
|
-
implementation is through "inversion of control". The "channel" is actually a thin proxy that uses methods internal to
|
|
97
|
-
the desktop agent. This allows re-use of code, simplifying the implementation.
|
|
98
|
-
|
|
99
|
-
`channelGetCurrentContext()`, `channelBroadcast()`, and `channelAddContextListener()` are private implementations of
|
|
100
|
-
getCurrentContext(), broadcast() and addContextListener(). These implementations simply optionally add a channel to the
|
|
101
|
-
message that is sent to the Interop Service. The code is otherwise identical.
|
|
102
|
-
|
|
103
|
-
As a result, the desktop agent maintains a single list of context handlers that contain both "channel" listeners and
|
|
104
|
-
"global" listeners. The overall implementation is greatly simplified through this approach, which should be maintainable
|
|
105
|
-
assuming future versions of FDC3 do not stray from the current philosophy of broadcast() being merely a special case of
|
|
106
|
-
channel.broadcast().
|
|
107
|
-
|
|
108
|
-
Note that these functions are commented with `/* @internal */`. They act as "friend" functions in object oriented
|
|
109
|
-
parlance. A "friend" function is one that is private except to friendly classes. In this case, ChannelProxy is a friend
|
|
110
|
-
of DesktopAgent – authorized to make use of these special functions. Unfortunately, neither typescript nor es6 support
|
|
111
|
-
the friend concept. The `/* @internal */` syntax is therefore used to hide these functions from code completion and from
|
|
112
|
-
documentation generation despite technically being public.
|
|
113
|
-
|
|
114
|
-
### Other
|
|
115
|
-
|
|
116
|
-
#### Strict Typescript
|
|
117
|
-
|
|
118
|
-
This code was written with strict typescript:
|
|
119
|
-
|
|
120
|
-
```
|
|
121
|
-
"noImplicitAny": true,
|
|
122
|
-
"strict": true
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
This leads to much more robust code. Unfortunately, finsemble-core does not yet compile as a whole using the strict
|
|
126
|
-
rules and therefore these rules have been commented out. (See `src/clients/Interop/tsconfig.json`). Until such time that
|
|
127
|
-
finsemble-core's Typescript implementation is fixed, these rules should be temporarily enabled and any TS errors should
|
|
128
|
-
be fixed before merging any changes.
|
|
129
|
-
|
|
130
|
-
Note: We spent a fair amount of time trying to get Typescript to enable the strict compiler options for just certain
|
|
131
|
-
directories but eventually gave up. Don't be fooled. It works intermittently, making you think you've solved it only to
|
|
132
|
-
find that under another circumstance (like a rebuild) that the strict compiler options "leak" upwards to the rest of the
|
|
133
|
-
project.
|
|
134
|
-
|
|
135
|
-
#### Joining / Leaving Multiple Channels & Linker
|
|
136
|
-
|
|
137
|
-
While the FDC3 specification only supports joining a single channel, our implementation allows joining multiple
|
|
138
|
-
channels. However, we expect most channel joining to be implicit–the result of the user interacting with the Linker.
|
|
139
|
-
When a user enables a channel on the Linker, the client is automatically joined to that channel (by the Interop
|
|
140
|
-
Service). The Linker does support joining (and thus leaving) multiple channels.
|
|
141
|
-
|
|
142
|
-
If the app developer calls leaveCurrentChannel() then the client will be disconnected from all linker channels.
|
|
143
|
-
Documentation should discourage developers from using getSystemChannels(), joinChannel(), getCurrentChannel(), and
|
|
144
|
-
leaveCurrentChannel() except in those rare cases where they are forced to implement their own linker.
|
|
145
|
-
|
|
146
|
-
#### Non Service Channels
|
|
147
|
-
|
|
148
|
-
The `getCurrentChannel()` API call is the main exception to the rule that all API calls interact with the Interop
|
|
149
|
-
Service. This call is so trivial that it is implemented with a local variable. This call will not reflect implicitly
|
|
150
|
-
joined channels such as occur through the Linker.
|
|
151
|
-
|
|
152
|
-
`getOrCreateChannel()` runs locally. All it does is create a ChannelProxy object. There is no tangible action associated
|
|
153
|
-
with "creating" a channel (there is no "channel" entity in the Interop Service). We treat a channel as essentially just
|
|
154
|
-
a namespace.
|
|
1
|
+
# FinsembleDesktopAgent
|
|
2
|
+
|
|
3
|
+
This file contains an implementation of the FDC3 "DesktopAgent" type (https://fdc3.finos.org/docs/api/ref/DesktopAgent).
|
|
4
|
+
It implements version 1.2 of FDC3. We'll refer to the code within this file as "the desktop agent".
|
|
5
|
+
|
|
6
|
+
The desktop agent is intended to be the primary API that developers use to implement "data integration" - e.g. sharing
|
|
7
|
+
"context" between apps and raising "intents" between apps. It is available through two global objects:
|
|
8
|
+
|
|
9
|
+
`window.fdc3` - This global is automatically injected by Finsemble's preload. Developers in capital markets will use
|
|
10
|
+
this interface.
|
|
11
|
+
|
|
12
|
+
`FSBL.Interop` - Provides the identical interface but with a non-fdc3 branding. Developers outside of capital markets
|
|
13
|
+
will be more likely to accept this interface.
|
|
14
|
+
|
|
15
|
+
The desktop agent communicates with Finsemble's "Interop Service". The Interop Service acts as a "resolver", routing
|
|
16
|
+
messages to clients (e.g. apps / windows), maintaining a global store of contexts, and providing connectivity to modules
|
|
17
|
+
(and eventually, plugins) that integrate with interop.
|
|
18
|
+
|
|
19
|
+
## Design Philosophy
|
|
20
|
+
|
|
21
|
+
This client is intentionally "thin". As much logic as possible has been pushed into the Interop Service by sending
|
|
22
|
+
messages over router calls. This thin design allows the client to be easily ported to and maintained in Finsemble's
|
|
23
|
+
native adapters (e.g. .Net & Java).
|
|
24
|
+
|
|
25
|
+
## Implementation Details
|
|
26
|
+
|
|
27
|
+
### Mechanics
|
|
28
|
+
|
|
29
|
+
The desktop agent communicates with the Interop Service in three ways:
|
|
30
|
+
|
|
31
|
+
1. The desktop agent sends messages for which there is no reply necessary. e.g. broadcast(), joinChannels(),
|
|
32
|
+
raiseIntent()
|
|
33
|
+
|
|
34
|
+
2. The interop service sends unsolicited messages to the desktop agent for which no reply is necessary. e.g. context
|
|
35
|
+
changes and intents
|
|
36
|
+
|
|
37
|
+
3. The desktop agent queries the interop service and expects a reply. e.g. getCurrentContext(), findIntents()
|
|
38
|
+
|
|
39
|
+
These communications are handled via two RouterClient channels. The Interop Service listens on a responder to "well
|
|
40
|
+
known" channel: type "SERVER_CHANNEL". Each desktop agent (typically one desktop agent per Finsemble window) also
|
|
41
|
+
listens on its own responder. Since both client and server are running responders (query/response) all messages are
|
|
42
|
+
queries, though only in case #3 above does the code wait for a response. Responses are always sent though they are empty
|
|
43
|
+
for messages that don't require responses.
|
|
44
|
+
|
|
45
|
+
### Message Protocol
|
|
46
|
+
|
|
47
|
+
The client and server communicate with a message protocol composed of Flux Standard Actions (FSA). These messages are
|
|
48
|
+
defined in `types.ts`. The union of all possible messages is the type `InteropMessage`. These messages are private, part
|
|
49
|
+
of our internal implementation, and are subject to change with each release. External developers should not manually
|
|
50
|
+
access these messages.
|
|
51
|
+
|
|
52
|
+
The messages are strongly typed using Typescript and reference types that are defined by the FDC3 standard. Finsemble's
|
|
53
|
+
core package now contains a copy of the FDC3 standard typedefs in `src/typedefs/FDC3` which serves as the single source
|
|
54
|
+
of truth. There have been some modifications to these typedefs based on areas of the spec that were found to be lacking.
|
|
55
|
+
After 1.2 is released we should revisit these changes vis a vis the updated spec, and release a PR back to FDC3 with any
|
|
56
|
+
changes that we believe are still relevant.
|
|
57
|
+
|
|
58
|
+
As new versions of FDC3 are released, the typedefs should be updated, along with our implementation.
|
|
59
|
+
|
|
60
|
+
Each FSA contains a "meta" section of type `InteropMeta`. This contains information that is independent of the business
|
|
61
|
+
logic of each message. Business logic runs against the "payload" data. The unique uuid of the desktop agent is always
|
|
62
|
+
part of the meta information along with either an "href" or "path" element that can positively identify web and native
|
|
63
|
+
clients respectively. The Interop Service uses meta information in order to direct the message to the correct set of
|
|
64
|
+
business logic (e.g. looking up the client by uuid) and may use this information for security or rules engine
|
|
65
|
+
processing.
|
|
66
|
+
|
|
67
|
+
### Initialization
|
|
68
|
+
|
|
69
|
+
The most complex part of the desktop agent is its startup sequence. The desktop agent must create a local RouterClient
|
|
70
|
+
responder on a unique channel name in order to receive messages from the Interop Service such as broadcasts and raised
|
|
71
|
+
intents. The desktop agent registers itself with the Interop Service by passing a message that contains the unique
|
|
72
|
+
RouterClient channel that the desktop agent has opened.
|
|
73
|
+
|
|
74
|
+
While the FDC3 1.2 specification now supports the "fdc3Ready" event, extenuating circumstances led us to take a more
|
|
75
|
+
robust approach to initialization. We do not auto-initialize the desktop agent (like we do with other Finsemble
|
|
76
|
+
clients). Instead, the desktop agent is initialized _only when an API call is actually invoked_.
|
|
77
|
+
|
|
78
|
+
This strategy prevents every single Finsemble window from registering with the InteropService. Only windows that have
|
|
79
|
+
made FDC3 calls will initialize and therefore be registered. This also implicitly allows us to tie feature functionality
|
|
80
|
+
to usage of the API. For instance, the linker can now display automatically by virtue of an implicit FDC3 registration.
|
|
81
|
+
|
|
82
|
+
To implement this strategy we took the approach of automatically providing the fdc3 interface _immediately_ on the
|
|
83
|
+
browser window. The first fdc3 call will trigger intialization. That call, and any subsequent calls, will be "queued"
|
|
84
|
+
until registration is complete and then sequentially sent to the service.
|
|
85
|
+
|
|
86
|
+
This mechanism also conveniently handles waiting for the underlying FSBL event and protects developers from the common
|
|
87
|
+
problem of failing to wait for ready events.
|
|
88
|
+
|
|
89
|
+
A `shouldAutoconnect` function is included but is dormant. This can be used in the future should we find use cases that
|
|
90
|
+
require the desktop agent to connect prior to any API invocations.
|
|
91
|
+
|
|
92
|
+
### Channels
|
|
93
|
+
|
|
94
|
+
The FDC3 specification implies an object oriented approach, with channels being created using a factory
|
|
95
|
+
(https://fdc3.finos.org/docs/api/ref/DesktopAgent#getorcreatechannel). This interface has been implemented but the
|
|
96
|
+
implementation is through "inversion of control". The "channel" is actually a thin proxy that uses methods internal to
|
|
97
|
+
the desktop agent. This allows re-use of code, simplifying the implementation.
|
|
98
|
+
|
|
99
|
+
`channelGetCurrentContext()`, `channelBroadcast()`, and `channelAddContextListener()` are private implementations of
|
|
100
|
+
getCurrentContext(), broadcast() and addContextListener(). These implementations simply optionally add a channel to the
|
|
101
|
+
message that is sent to the Interop Service. The code is otherwise identical.
|
|
102
|
+
|
|
103
|
+
As a result, the desktop agent maintains a single list of context handlers that contain both "channel" listeners and
|
|
104
|
+
"global" listeners. The overall implementation is greatly simplified through this approach, which should be maintainable
|
|
105
|
+
assuming future versions of FDC3 do not stray from the current philosophy of broadcast() being merely a special case of
|
|
106
|
+
channel.broadcast().
|
|
107
|
+
|
|
108
|
+
Note that these functions are commented with `/* @internal */`. They act as "friend" functions in object oriented
|
|
109
|
+
parlance. A "friend" function is one that is private except to friendly classes. In this case, ChannelProxy is a friend
|
|
110
|
+
of DesktopAgent – authorized to make use of these special functions. Unfortunately, neither typescript nor es6 support
|
|
111
|
+
the friend concept. The `/* @internal */` syntax is therefore used to hide these functions from code completion and from
|
|
112
|
+
documentation generation despite technically being public.
|
|
113
|
+
|
|
114
|
+
### Other
|
|
115
|
+
|
|
116
|
+
#### Strict Typescript
|
|
117
|
+
|
|
118
|
+
This code was written with strict typescript:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
"noImplicitAny": true,
|
|
122
|
+
"strict": true
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This leads to much more robust code. Unfortunately, finsemble-core does not yet compile as a whole using the strict
|
|
126
|
+
rules and therefore these rules have been commented out. (See `src/clients/Interop/tsconfig.json`). Until such time that
|
|
127
|
+
finsemble-core's Typescript implementation is fixed, these rules should be temporarily enabled and any TS errors should
|
|
128
|
+
be fixed before merging any changes.
|
|
129
|
+
|
|
130
|
+
Note: We spent a fair amount of time trying to get Typescript to enable the strict compiler options for just certain
|
|
131
|
+
directories but eventually gave up. Don't be fooled. It works intermittently, making you think you've solved it only to
|
|
132
|
+
find that under another circumstance (like a rebuild) that the strict compiler options "leak" upwards to the rest of the
|
|
133
|
+
project.
|
|
134
|
+
|
|
135
|
+
#### Joining / Leaving Multiple Channels & Linker
|
|
136
|
+
|
|
137
|
+
While the FDC3 specification only supports joining a single channel, our implementation allows joining multiple
|
|
138
|
+
channels. However, we expect most channel joining to be implicit–the result of the user interacting with the Linker.
|
|
139
|
+
When a user enables a channel on the Linker, the client is automatically joined to that channel (by the Interop
|
|
140
|
+
Service). The Linker does support joining (and thus leaving) multiple channels.
|
|
141
|
+
|
|
142
|
+
If the app developer calls leaveCurrentChannel() then the client will be disconnected from all linker channels.
|
|
143
|
+
Documentation should discourage developers from using getSystemChannels(), joinChannel(), getCurrentChannel(), and
|
|
144
|
+
leaveCurrentChannel() except in those rare cases where they are forced to implement their own linker.
|
|
145
|
+
|
|
146
|
+
#### Non Service Channels
|
|
147
|
+
|
|
148
|
+
The `getCurrentChannel()` API call is the main exception to the rule that all API calls interact with the Interop
|
|
149
|
+
Service. This call is so trivial that it is implemented with a local variable. This call will not reflect implicitly
|
|
150
|
+
joined channels such as occur through the Linker.
|
|
151
|
+
|
|
152
|
+
`getOrCreateChannel()` runs locally. All it does is create a ChannelProxy object. There is no tangible action associated
|
|
153
|
+
with "creating" a channel (there is no "channel" entity in the Interop Service). We treat a channel as essentially just
|
|
154
|
+
a namespace.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../../tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
//"noImplicitAny": true,
|
|
5
|
-
//"strict": true
|
|
6
|
-
}
|
|
7
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
//"noImplicitAny": true,
|
|
5
|
+
//"strict": true
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
## Entry points
|
|
2
|
-
|
|
3
|
-
There are two <script> level entry points for finsemble:
|
|
4
|
-
|
|
5
|
-
- `finsemble-desktop-api-preload.ts` is the entry point when running in "desktop mode" (using FEA). This script is compiled to FSBL.js which is preloaded by the launcher (@todo, don't rename in the future but only after dealing with preload caching issues as referenced in launcher)
|
|
6
|
-
|
|
7
|
-
- `finsemble-javascript-adapter.ts` is the entry point when running in "freestanding mode" (in a browser, webview, or any other web based javascript container). A developer would include this file as a <script> tag and then manually call `FSBL.startApp()` with the appropriate parameters.
|
|
8
|
-
|
|
9
|
-
These entry points make use of FSBLDesktop and FSBLFreestanding, both of which inject the FSBL global object. FEAFreestanding is a simpler and smaller footprint that is certified to run in a browser. _Note that it is not certified to run under Node though an effort has been made to be compatible._
|
|
10
|
-
|
|
11
|
-
FSBLService provides a third entry point. This is used in Finsemble's internal services and the startup manager.
|
|
12
|
-
|
|
13
|
-
Eventually finsemble-desktop-api-preload and finsemble-javascript-adapter can merge into a single entry point as might each of the FSBL entry point modules. Currently though, importing FEADesktop runs too many import level actions that depend upon the existence of Finsemble's services and the fin object. So, we are left with some un-DRY code.
|
|
14
|
-
|
|
15
|
-
## Startup
|
|
16
|
-
|
|
17
|
-
There are a few jobs that the FSBL entry points accomplish:
|
|
18
|
-
|
|
19
|
-
- Initialize "Startup" data. This data is obtained from the startApp() function in freestanding mode (passed by the developer) or from the fin object's customData in desktop mode (passed from the launcher). The Startup data is used throughout the system for "boot" purposes.
|
|
20
|
-
|
|
21
|
-
- Start the router. The system cannot be brought online until the router is ready.
|
|
22
|
-
|
|
23
|
-
- Initialize client APIs. This is only relevant in FSBLDesktop and FSBLService. Freestanding apps do not have access to the full Finsemble client API set. Over time we will either eliminate APIs or eliminate the need for initialization. Once that is accomplished, the FSBL entry points can be more easily merged together.
|
|
24
|
-
|
|
25
|
-
- Start DPE Listeners. This is the code that listens on DPE events and dynamically updates Finsemble, such as changing toolbar colors on the fly.
|
|
26
|
-
|
|
27
|
-
## RouterConfig
|
|
28
|
-
|
|
1
|
+
## Entry points
|
|
2
|
+
|
|
3
|
+
There are two <script> level entry points for finsemble:
|
|
4
|
+
|
|
5
|
+
- `finsemble-desktop-api-preload.ts` is the entry point when running in "desktop mode" (using FEA). This script is compiled to FSBL.js which is preloaded by the launcher (@todo, don't rename in the future but only after dealing with preload caching issues as referenced in launcher)
|
|
6
|
+
|
|
7
|
+
- `finsemble-javascript-adapter.ts` is the entry point when running in "freestanding mode" (in a browser, webview, or any other web based javascript container). A developer would include this file as a <script> tag and then manually call `FSBL.startApp()` with the appropriate parameters.
|
|
8
|
+
|
|
9
|
+
These entry points make use of FSBLDesktop and FSBLFreestanding, both of which inject the FSBL global object. FEAFreestanding is a simpler and smaller footprint that is certified to run in a browser. _Note that it is not certified to run under Node though an effort has been made to be compatible._
|
|
10
|
+
|
|
11
|
+
FSBLService provides a third entry point. This is used in Finsemble's internal services and the startup manager.
|
|
12
|
+
|
|
13
|
+
Eventually finsemble-desktop-api-preload and finsemble-javascript-adapter can merge into a single entry point as might each of the FSBL entry point modules. Currently though, importing FEADesktop runs too many import level actions that depend upon the existence of Finsemble's services and the fin object. So, we are left with some un-DRY code.
|
|
14
|
+
|
|
15
|
+
## Startup
|
|
16
|
+
|
|
17
|
+
There are a few jobs that the FSBL entry points accomplish:
|
|
18
|
+
|
|
19
|
+
- Initialize "Startup" data. This data is obtained from the startApp() function in freestanding mode (passed by the developer) or from the fin object's customData in desktop mode (passed from the launcher). The Startup data is used throughout the system for "boot" purposes.
|
|
20
|
+
|
|
21
|
+
- Start the router. The system cannot be brought online until the router is ready.
|
|
22
|
+
|
|
23
|
+
- Initialize client APIs. This is only relevant in FSBLDesktop and FSBLService. Freestanding apps do not have access to the full Finsemble client API set. Over time we will either eliminate APIs or eliminate the need for initialization. Once that is accomplished, the FSBL entry points can be more easily merged together.
|
|
24
|
+
|
|
25
|
+
- Start DPE Listeners. This is the code that listens on DPE events and dynamically updates Finsemble, such as changing toolbar colors on the fly.
|
|
26
|
+
|
|
27
|
+
## RouterConfig
|
|
28
|
+
|
|
29
29
|
This contains convenience routines for processing router config, particularly for extracting it out of the system manifest.
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The contents of this file are dynamically injected as a <style> tag
|
|
3
|
-
* within the scrim container element.
|
|
4
|
-
*/
|
|
5
|
-
:root {
|
|
6
|
-
--accent-primary-1: #36788b;
|
|
7
|
-
--accent-negative: #f26666;
|
|
8
|
-
--scrim-positive-background-color: var(--accent-primary-1);
|
|
9
|
-
--scrim-negative-background-color: var(--accent-negative);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.fsbl-share-scrim {
|
|
13
|
-
position: fixed;
|
|
14
|
-
display: flex;
|
|
15
|
-
height: 100%;
|
|
16
|
-
width: 100%;
|
|
17
|
-
z-index: 1000000;
|
|
18
|
-
top: 0;
|
|
19
|
-
left: 0;
|
|
20
|
-
justify-content: center;
|
|
21
|
-
align-content: center;
|
|
22
|
-
flex-direction: column;
|
|
23
|
-
align-items: center;
|
|
24
|
-
transition: all 0.3s ease;
|
|
25
|
-
opacity: 0.85;
|
|
26
|
-
background-color: var(--scrim-positive-background-color);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.fsbl-share-scrim .error-message {
|
|
30
|
-
display: flex;
|
|
31
|
-
height: 100%;
|
|
32
|
-
align-content: center;
|
|
33
|
-
justify-content: center;
|
|
34
|
-
align-items: center;
|
|
35
|
-
padding: 1em;
|
|
36
|
-
background-color: var(--scrim-negative-background-color);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.fsbl-share-scrim img {
|
|
40
|
-
display: flex;
|
|
41
|
-
height: 10%;
|
|
42
|
-
width: 10%;
|
|
43
|
-
z-index: 1000000;
|
|
44
|
-
top: 0;
|
|
45
|
-
left: 0;
|
|
46
|
-
justify-content: center;
|
|
47
|
-
align-content: center;
|
|
48
|
-
flex-direction: column;
|
|
49
|
-
align-items: center;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.fsbl-share-scrim.no {
|
|
53
|
-
background-color: var(--scrim-negative-background-color);
|
|
54
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* The contents of this file are dynamically injected as a <style> tag
|
|
3
|
+
* within the scrim container element.
|
|
4
|
+
*/
|
|
5
|
+
:root {
|
|
6
|
+
--accent-primary-1: #36788b;
|
|
7
|
+
--accent-negative: #f26666;
|
|
8
|
+
--scrim-positive-background-color: var(--accent-primary-1);
|
|
9
|
+
--scrim-negative-background-color: var(--accent-negative);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.fsbl-share-scrim {
|
|
13
|
+
position: fixed;
|
|
14
|
+
display: flex;
|
|
15
|
+
height: 100%;
|
|
16
|
+
width: 100%;
|
|
17
|
+
z-index: 1000000;
|
|
18
|
+
top: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
align-content: center;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
align-items: center;
|
|
24
|
+
transition: all 0.3s ease;
|
|
25
|
+
opacity: 0.85;
|
|
26
|
+
background-color: var(--scrim-positive-background-color);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.fsbl-share-scrim .error-message {
|
|
30
|
+
display: flex;
|
|
31
|
+
height: 100%;
|
|
32
|
+
align-content: center;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
align-items: center;
|
|
35
|
+
padding: 1em;
|
|
36
|
+
background-color: var(--scrim-negative-background-color);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.fsbl-share-scrim img {
|
|
40
|
+
display: flex;
|
|
41
|
+
height: 10%;
|
|
42
|
+
width: 10%;
|
|
43
|
+
z-index: 1000000;
|
|
44
|
+
top: 0;
|
|
45
|
+
left: 0;
|
|
46
|
+
justify-content: center;
|
|
47
|
+
align-content: center;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
align-items: center;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.fsbl-share-scrim.no {
|
|
53
|
+
background-color: var(--scrim-negative-background-color);
|
|
54
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
-
<title>ff-delete-circle</title>
|
|
4
|
-
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
5
|
-
<g id="ff-delete-circle" fill="#FFFFFF" fill-rule="nonzero">
|
|
6
|
-
<path d="M8.8,15.8 C8.6,15.8 8.4,15.7 8.3,15.6 C8,15.3 8,14.8 8.3,14.5 L14.4,8.3 C14.7,8 15.2,8 15.5,8.3 C15.8,8.6 15.8,9.1 15.5,9.4 L9.4,15.6 C9.2,15.7 9,15.8 8.8,15.8" id="Path"></path>
|
|
7
|
-
<path d="M14.9,15.8 C14.7,15.8 14.5,15.7 14.4,15.6 L8.3,9.4 C8,9.1 8,8.6 8.3,8.3 C8.6,8 9.1,8 9.4,8.3 L15.5,14.5 C15.8,14.8 15.8,15.3 15.5,15.6 C15.3,15.7 15.1,15.8 14.9,15.8" id="Path"></path>
|
|
8
|
-
<path d="M11.6,1.6 C6.1,1.6 1.6,6.2 1.6,11.7 C1.6,17.3 6.1,21.8 11.6,21.8 C17.1,21.8 21.6,17.2 21.6,11.7 C21.6,6.1 17.1,1.6 11.6,1.6 Z M11.6,23.4 C5.2,23.4 0,18.1 0,11.7 C0,5.3 5.2,0 11.6,0 C18,0 23.2,5.2 23.2,11.7 C23.2,18.2 17.9,23.4 11.6,23.4 L11.6,23.4 Z" id="Shape"></path>
|
|
9
|
-
</g>
|
|
10
|
-
</g>
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
+
<title>ff-delete-circle</title>
|
|
4
|
+
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
5
|
+
<g id="ff-delete-circle" fill="#FFFFFF" fill-rule="nonzero">
|
|
6
|
+
<path d="M8.8,15.8 C8.6,15.8 8.4,15.7 8.3,15.6 C8,15.3 8,14.8 8.3,14.5 L14.4,8.3 C14.7,8 15.2,8 15.5,8.3 C15.8,8.6 15.8,9.1 15.5,9.4 L9.4,15.6 C9.2,15.7 9,15.8 8.8,15.8" id="Path"></path>
|
|
7
|
+
<path d="M14.9,15.8 C14.7,15.8 14.5,15.7 14.4,15.6 L8.3,9.4 C8,9.1 8,8.6 8.3,8.3 C8.6,8 9.1,8 9.4,8.3 L15.5,14.5 C15.8,14.8 15.8,15.3 15.5,15.6 C15.3,15.7 15.1,15.8 14.9,15.8" id="Path"></path>
|
|
8
|
+
<path d="M11.6,1.6 C6.1,1.6 1.6,6.2 1.6,11.7 C1.6,17.3 6.1,21.8 11.6,21.8 C17.1,21.8 21.6,17.2 21.6,11.7 C21.6,6.1 17.1,1.6 11.6,1.6 Z M11.6,23.4 C5.2,23.4 0,18.1 0,11.7 C0,5.3 5.2,0 11.6,0 C18,0 23.2,5.2 23.2,11.7 C23.2,18.2 17.9,23.4 11.6,23.4 L11.6,23.4 Z" id="Shape"></path>
|
|
9
|
+
</g>
|
|
10
|
+
</g>
|
|
11
11
|
</svg>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg width="23px" height="23px" viewBox="0 0 23 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
-
<title>Share White</title>
|
|
4
|
-
<g id="Share-White" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
5
|
-
<g id="Page-1" transform="translate(0.000000, 1.000000)" fill="#FFFFFF">
|
|
6
|
-
<g id="Group-3" transform="translate(8.000000, 0.479100)">
|
|
7
|
-
<path d="M14.3271717,6.06480859 C14.3587843,6.01822157 14.3953884,5.97662602 14.4170181,5.92504754 C14.4985454,5.72372507 14.4985454,5.49910909 14.4170181,5.29945044 C14.3953884,5.24620814 14.3587843,5.20461259 14.3271717,5.15802557 C14.3005506,5.11975766 14.2855762,5.07483447 14.2522997,5.0398942 L14.2356615,5.02491981 C14.2356615,5.02325598 14.2356615,5.02325598 14.2339977,5.02325598 L9.73502284,0.259733439 C9.41889665,-0.07136715 8.89312889,-0.0896691926 8.55870065,0.226456998 C8.22593624,0.542583188 8.21096184,1.06835096 8.52708803,1.40277919 L11.7182987,4.78033796 L2.99155206,4.78033796 C1.34104058,4.78033796 0,6.43417709 0,8.46903146 L0,10.6902339 C0,11.1511126 0.371032318,11.5221449 0.831911028,11.5221449 C1.29112591,11.5221449 1.66382206,11.1511126 1.66382206,10.6902339 L1.66382206,8.46903146 C1.66382206,7.3709089 2.27111711,6.44416002 2.99155206,6.44416002 L11.7182987,6.44416002 L8.52708803,9.82005497 C8.21096184,10.1544832 8.22593624,10.6785871 8.55870065,10.9963772 C8.72009139,11.147785 8.92640533,11.2243208 9.13105544,11.2243208 C9.35234377,11.2243208 9.57196828,11.1361382 9.73502284,10.9614369 L14.2339977,6.201242 C14.2356615,6.19957818 14.2356615,6.19957818 14.2356615,6.19957818 L14.2522997,6.18293996 C14.2855762,6.14799969 14.3005506,6.1030765 14.3271717,6.06480859" id="Fill-1"></path>
|
|
8
|
-
</g>
|
|
9
|
-
<g id="Group-6" transform="translate(0.000000, 2.479100)">
|
|
10
|
-
<path d="M21.9707702,18.5166757 L0.831911028,18.5166757 C0.37269614,18.5166757 0,18.1439795 0,17.6847646 L0,0.831911028 C0,0.371032318 0.37269614,0 0.831911028,0 L5.40742168,0 C5.86663657,0 6.23933271,0.371032318 6.23933271,0.831911028 C6.23933271,1.29112591 5.86663657,1.66382206 5.40742168,1.66382206 L1.66382206,1.66382206 L1.66382206,16.8528536 L21.1388592,16.8528536 L21.1388592,10.7499543 C21.1388592,10.2907394 21.5115554,9.91804327 21.9707702,9.91804327 C22.4299851,9.91804327 22.8026813,10.2907394 22.8026813,10.7499543 L22.8026813,17.6847646 C22.8026813,18.1439795 22.4299851,18.5166757 21.9707702,18.5166757" id="Fill-4"></path>
|
|
11
|
-
</g>
|
|
12
|
-
</g>
|
|
13
|
-
</g>
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="23px" height="23px" viewBox="0 0 23 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
+
<title>Share White</title>
|
|
4
|
+
<g id="Share-White" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
5
|
+
<g id="Page-1" transform="translate(0.000000, 1.000000)" fill="#FFFFFF">
|
|
6
|
+
<g id="Group-3" transform="translate(8.000000, 0.479100)">
|
|
7
|
+
<path d="M14.3271717,6.06480859 C14.3587843,6.01822157 14.3953884,5.97662602 14.4170181,5.92504754 C14.4985454,5.72372507 14.4985454,5.49910909 14.4170181,5.29945044 C14.3953884,5.24620814 14.3587843,5.20461259 14.3271717,5.15802557 C14.3005506,5.11975766 14.2855762,5.07483447 14.2522997,5.0398942 L14.2356615,5.02491981 C14.2356615,5.02325598 14.2356615,5.02325598 14.2339977,5.02325598 L9.73502284,0.259733439 C9.41889665,-0.07136715 8.89312889,-0.0896691926 8.55870065,0.226456998 C8.22593624,0.542583188 8.21096184,1.06835096 8.52708803,1.40277919 L11.7182987,4.78033796 L2.99155206,4.78033796 C1.34104058,4.78033796 0,6.43417709 0,8.46903146 L0,10.6902339 C0,11.1511126 0.371032318,11.5221449 0.831911028,11.5221449 C1.29112591,11.5221449 1.66382206,11.1511126 1.66382206,10.6902339 L1.66382206,8.46903146 C1.66382206,7.3709089 2.27111711,6.44416002 2.99155206,6.44416002 L11.7182987,6.44416002 L8.52708803,9.82005497 C8.21096184,10.1544832 8.22593624,10.6785871 8.55870065,10.9963772 C8.72009139,11.147785 8.92640533,11.2243208 9.13105544,11.2243208 C9.35234377,11.2243208 9.57196828,11.1361382 9.73502284,10.9614369 L14.2339977,6.201242 C14.2356615,6.19957818 14.2356615,6.19957818 14.2356615,6.19957818 L14.2522997,6.18293996 C14.2855762,6.14799969 14.3005506,6.1030765 14.3271717,6.06480859" id="Fill-1"></path>
|
|
8
|
+
</g>
|
|
9
|
+
<g id="Group-6" transform="translate(0.000000, 2.479100)">
|
|
10
|
+
<path d="M21.9707702,18.5166757 L0.831911028,18.5166757 C0.37269614,18.5166757 0,18.1439795 0,17.6847646 L0,0.831911028 C0,0.371032318 0.37269614,0 0.831911028,0 L5.40742168,0 C5.86663657,0 6.23933271,0.371032318 6.23933271,0.831911028 C6.23933271,1.29112591 5.86663657,1.66382206 5.40742168,1.66382206 L1.66382206,1.66382206 L1.66382206,16.8528536 L21.1388592,16.8528536 L21.1388592,10.7499543 C21.1388592,10.2907394 21.5115554,9.91804327 21.9707702,9.91804327 C22.4299851,9.91804327 22.8026813,10.2907394 22.8026813,10.7499543 L22.8026813,17.6847646 C22.8026813,18.1439795 22.4299851,18.5166757 21.9707702,18.5166757" id="Fill-4"></path>
|
|
11
|
+
</g>
|
|
12
|
+
</g>
|
|
13
|
+
</g>
|
|
14
14
|
</svg>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
2
|
-
<defs>
|
|
3
|
-
<style>
|
|
4
|
-
.cls-1 {
|
|
5
|
-
fill: #fff;
|
|
6
|
-
}
|
|
7
|
-
</style>
|
|
8
|
-
</defs>
|
|
9
|
-
<title>ff-close</title>
|
|
10
|
-
<g>
|
|
11
|
-
<path class="cls-1" d="M22.66,23.52a.67.67,0,0,1-.49-.21L1.09,2.23a.71.71,0,0,1,0-1,.69.69,0,0,1,1,0L23.16,22.32a.69.69,0,0,1,0,1,.7.7,0,0,1-.5.21"/>
|
|
12
|
-
<path class="cls-1" d="M1.59,23.52a.71.71,0,0,1-.5-1.2L22.17,1.24a.7.7,0,0,1,1,1L2.08,23.31a.67.67,0,0,1-.49.21"/>
|
|
13
|
-
</g>
|
|
14
|
-
</svg>
|
|
1
|
+
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.cls-1 {
|
|
5
|
+
fill: #fff;
|
|
6
|
+
}
|
|
7
|
+
</style>
|
|
8
|
+
</defs>
|
|
9
|
+
<title>ff-close</title>
|
|
10
|
+
<g>
|
|
11
|
+
<path class="cls-1" d="M22.66,23.52a.67.67,0,0,1-.49-.21L1.09,2.23a.71.71,0,0,1,0-1,.69.69,0,0,1,1,0L23.16,22.32a.69.69,0,0,1,0,1,.7.7,0,0,1-.5.21"/>
|
|
12
|
+
<path class="cls-1" d="M1.59,23.52a.71.71,0,0,1-.5-1.2L22.17,1.24a.7.7,0,0,1,1,1L2.08,23.31a.67.67,0,0,1-.49.21"/>
|
|
13
|
+
</g>
|
|
14
|
+
</svg>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg width="29px" height="31px" viewBox="0 0 29 31" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
-
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
|
|
4
|
-
<title>finsemble_logo_white</title>
|
|
5
|
-
<desc>Created with Sketch.</desc>
|
|
6
|
-
<defs></defs>
|
|
7
|
-
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
8
|
-
<g id="finsemble_logo_white">
|
|
9
|
-
<polygon id="Fill-1" fill="#FFFFFF" points="0 25.1068927 14.3963632 30.5185854 14.3963632 21.4116927 0 16"></polygon>
|
|
10
|
-
<polygon id="Fill-2" fill="#FFFFFF" points="0 25.146361 14.4484105 30.5774098 14.4484105 21.8032227 0 16.3720227"></polygon>
|
|
11
|
-
<polygon id="Fill-3" fill="#039BFF" points="0 16.3899171 14.3963632 21.8016098 28.7925737 16.3899171 15.2762842 11.3089415 15.2511 11.3186195 15.2511 19.6671463 14.3383632 20.0102634 14.3383632 11"></polygon>
|
|
12
|
-
<polygon id="Fill-9" fill="#FFFFFF" points="0.106078947 14.7532196 14.5 20.0800781 14.5 10.8647461 0.103942105 5.38107292"></polygon>
|
|
13
|
-
<polygon id="Fill-6" fill="#039BFF" points="0 5.41169268 14.3380579 10.8953659 28.7925737 5.41169268 14.3963632 0"></polygon>
|
|
14
|
-
</g>
|
|
15
|
-
</g>
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="29px" height="31px" viewBox="0 0 29 31" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
+
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
|
|
4
|
+
<title>finsemble_logo_white</title>
|
|
5
|
+
<desc>Created with Sketch.</desc>
|
|
6
|
+
<defs></defs>
|
|
7
|
+
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
8
|
+
<g id="finsemble_logo_white">
|
|
9
|
+
<polygon id="Fill-1" fill="#FFFFFF" points="0 25.1068927 14.3963632 30.5185854 14.3963632 21.4116927 0 16"></polygon>
|
|
10
|
+
<polygon id="Fill-2" fill="#FFFFFF" points="0 25.146361 14.4484105 30.5774098 14.4484105 21.8032227 0 16.3720227"></polygon>
|
|
11
|
+
<polygon id="Fill-3" fill="#039BFF" points="0 16.3899171 14.3963632 21.8016098 28.7925737 16.3899171 15.2762842 11.3089415 15.2511 11.3186195 15.2511 19.6671463 14.3383632 20.0102634 14.3383632 11"></polygon>
|
|
12
|
+
<polygon id="Fill-9" fill="#FFFFFF" points="0.106078947 14.7532196 14.5 20.0800781 14.5 10.8647461 0.103942105 5.38107292"></polygon>
|
|
13
|
+
<polygon id="Fill-6" fill="#039BFF" points="0 5.41169268 14.3380579 10.8953659 28.7925737 5.41169268 14.3963632 0"></polygon>
|
|
14
|
+
</g>
|
|
15
|
+
</g>
|
|
16
16
|
</svg>
|