Skip to content

Commit

Permalink
Major updates to workshop content and automation
Browse files Browse the repository at this point in the history
  • Loading branch information
asdaraujo committed Oct 27, 2021
1 parent f99d907 commit e8de299
Show file tree
Hide file tree
Showing 137 changed files with 818 additions and 1,519 deletions.
4 changes: 2 additions & 2 deletions .build
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
20211019201223
Previous commit: 461eb0b Refactored test modules
20211026133942
Previous commit: 4abf0c0 Updated SSB lab to conform with CSA 1.4
8 changes: 5 additions & 3 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
= CDF Workshop
= CDF Workshops

== Introduction

In this hands-on workshop, you will build a full OT to IT workflow for an **IoT Predictive Maintenance** use case. Below is the architecture diagram, showing all the components you will setup over the lab exercises. While the diagram divides the components according to their location (factory, regional or datacenter level) in this workshop all such components will reside in one single host.

image::images/iot-architecture.png[width=800]

=== Labs
=== Workshops

IMPORTANT: If this is your first time going through this content, please read the rest of this README introduction before jumping to the Labs.

If you already familiar with the instructions in the README, time to start working and see some interesting stuff! Pick your lab and let's get started!

* link:streaming.adoc[From Edge to Streams Processing]
* link:workshop_edge.adoc[Ingesting data from the edge]
* link:workshop_nifi.adoc[NiFi and Streams Processing]
* link:workshop_dataviz.adoc[Creating Dashboards with Cloudera Data Viz]
* link:streams_replication.adoc[Streams Replication]
* link:sql_stream_builder.adoc[Querying streams with SQL]
* link:spark_analytics.adoc[Spark and Fast Analytics with Kudu]
Expand Down
Binary file removed images/create_table.png
Binary file not shown.
Binary file added images/dataviz/add-dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/add-expression.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/add-measures.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/add-visuals.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/clone-field.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/connection-explorer-table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/create-dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/dashboard-add-dimensions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Binary file added images/dataviz/dataset-fields.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/dataviz-home-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/dim-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/edit-dataset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/edit-filter-expresion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/edit-measure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/explore-visuals-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/layout-button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/mes-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added images/dataviz/new-connection-basic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/new-dasboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dataviz/new-data-connection.png
Binary file added images/dataviz/new-dataset.png
Binary file added images/dataviz/opening-dataviz.png
Binary file added images/dataviz/real-time-dashboard.png
Binary file added images/dataviz/refreshed-fields.png
Binary file added images/dataviz/updated-dataset.png
Binary file added images/dataviz/updated-field-category.png
Binary file added images/dataviz/visual-axes-settings.png
Binary file added images/dataviz/visual-legend-style.png
Binary file added images/dataviz/visual-style.png
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added images/edge/bogus-readings.png
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added images/edge/list-queue.png
Binary file added images/edge/message-queue-details.png
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added images/nifi/create_table.png
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added images/nifi/table_select.png
File renamed without changes
File renamed without changes
Binary file removed images/table_select.png
Diff not rendered.
Binary file removed images/viz_add_expression.png
Diff not rendered.
Binary file removed images/viz_clone_field.png
Diff not rendered.
Binary file removed images/viz_connection_explorer.png
Diff not rendered.
Binary file removed images/viz_connection_explorer_table.png
Diff not rendered.
Binary file removed images/viz_create_dashboard.png
Diff not rendered.
Binary file removed images/viz_dashboard_add_dimensions.png
Diff not rendered.
Binary file removed images/viz_dashboard_add_measures.png
Diff not rendered.
Binary file removed images/viz_new_connection_basic.png
Diff not rendered.
Binary file removed images/viz_new_dashboard.png
Diff not rendered.
Binary file removed images/viz_new_dataset.png
Diff not rendered.
Binary file removed images/viz_save_dataset.png
Diff not rendered.
2 changes: 1 addition & 1 deletion sensor.avsc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
{
"name": "sensor_ts",
"doc": "Timestamp of the collected readings.",
"doc": "Timestamp, in microseconds, of the collected readings.",
"type": "long"
},
{
Expand Down
2 changes: 1 addition & 1 deletion setup/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ git clone https://github.com/cloudera-labs/edge2ai-workshop.git
+
[source,shell]
----
cp edge2ai-workshop/setup/scripts/stack.cdp716p.sh edge2ai-workshop/setup/scripts/stack.sh
cp edge2ai-workshop/setup/terraform/resources/stack.cdp716p.sh edge2ai-workshop/setup/terraform/resources/stack.sh
----
+
The `stack.sh` file is the default stack definition file used by all the namespaces that lack _namespace-specific_ stacks. You can create namespace-specific stack by naming the file `stack.<namespace>.sh` instead.
Expand Down
1 change: 0 additions & 1 deletion setup/scripts

This file was deleted.

21 changes: 18 additions & 3 deletions setup/terraform/check-services.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,22 @@ function get_model_status() {
CDSW_ALTUS_API="cdsw.$ip.nip.io/api/altus-ds-1"
status=""
for scheme in http https; do
token=$("${CURL[@]}" -X POST --cookie-jar .curl.cj.$$ --cookie .curl.cj.$$ -H "Content-Type: application/json" --data '{"_local":false,"login":"admin","password":"'"${THE_PWD}"'"}' "$scheme://$CDSW_API/authenticate" 2>/dev/null | jq -r '.auth_token' 2> /dev/null)
token=$("${CURL[@]}" -X POST --cookie-jar .curl.cj-model.$$ --cookie .curl.cj-model.$$ -H "Content-Type: application/json" --data '{"_local":false,"login":"admin","password":"'"${THE_PWD}"'"}' "$scheme://$CDSW_API/authenticate" 2>/dev/null | jq -r '.auth_token // empty' 2> /dev/null)
[[ ! -n $token ]] && continue
status=$("${CURL[@]}" -X POST --cookie-jar .curl.cj.$$ --cookie .curl.cj.$$ -H "Content-Type: application/json" -H "Authorization: Bearer $token" --data '{"projectOwnerName":"admin","latestModelDeployment":true,"latestModelBuild":true}' "$scheme://$CDSW_ALTUS_API/models/list-models" 2>/dev/null | jq -r '.[].latestModelDeployment | select(.model.name == "IoT Prediction Model").status' 2>/dev/null)
status=$("${CURL[@]}" -X POST --cookie-jar .curl.cj-model.$$ --cookie .curl.cj-model.$$ -H "Content-Type: application/json" -H "Authorization: Bearer $token" --data '{"projectOwnerName":"admin","latestModelDeployment":true,"latestModelBuild":true}' "$scheme://$CDSW_ALTUS_API/models/list-models" 2>/dev/null | jq -r '.[].latestModelDeployment | select(.model.name == "IoT Prediction Model").status' 2>/dev/null)
[[ -n $status ]] && break
done
echo -n $status
}

function get_viz_status() {
local ip=$1
CDSW_API="cdsw.$ip.nip.io/api/v1"
status=""
for scheme in http https; do
token=$("${CURL[@]}" -X POST --cookie-jar .curl.cj-viz.$$ --cookie .curl.cj-viz.$$ -H "Content-Type: application/json" --data '{"_local":false,"login":"admin","password":"'"${THE_PWD}"'"}' "$scheme://$CDSW_API/authenticate" 2>/dev/null | jq -r '.auth_token // empty' 2> /dev/null)
[[ ! -n $token ]] && continue
status=$("${CURL[@]}" -X GET --cookie-jar .curl.cj-viz.$$ --cookie .curl.cj-viz.$$ -H "Content-Type: application/json" -H "Authorization: Bearer $token" "$scheme://$CDSW_API/projects/admin/vizapps-workshop/applications" 2>/dev/null | jq -r '.[0].status // empty' 2>/dev/null)
[[ -n $status ]] && break
done
echo -n $status
Expand Down Expand Up @@ -50,8 +63,10 @@ if [ -s $TF_JSON_FILE ]; then
(("${CURL[@]}" http://$host:8888/ ; "${CURL[@]}" https://$host:8889/) 2>/dev/null | grep "<title>Hue" > /dev/null 2>&1 && echo Ok) > .curl.hue.$$ &
(("${CURL[@]}" http://cdsw.$ip.nip.io/ || "${CURL[@]}" https://cdsw.$ip.nip.io/) 2>/dev/null | egrep "(Cloudera Machine Learning|Cloudera Data Science Workbench)" > /dev/null 2>&1 && echo Ok) > .curl.cml.$$ &
(get_model_status $ip) > .curl.model.$$ &
("${CURL[@]}" http://viz.cdsw.$ip.nip.io/arc/adminapi/users 2>/dev/null | grep 'user' > /dev/null 2>&1 && echo running) > .curl.viz.$$ &
# ("${CURL[@]}" http://viz.cdsw.$ip.nip.io/arc/adminapi/users 2>/dev/null | grep 'user' > /dev/null 2>&1 && echo running) > .curl.viz.$$ &
(get_viz_status $ip) > .curl.viz.$$ &
wait
# printf "%-30s %-20s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %s\n" "$instance" "$ip" "$(cat .curl.web.$$)" "$(cat .curl.cm.$$)" "$(cat .curl.cem.$$)" "$(cat .curl.nifi.$$)" "$(cat .curl.nifireg.$$)" "$(cat .curl.schreg.$$)" "$(cat .curl.smm.$$)" "$(cat .curl.hue.$$)" "$(cat .curl.cml.$$)" "$(cat .curl.model.$$)"
printf "%-30s %-20s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-14s %s\n" "$instance" "$ip" "$(cat .curl.web.$$)" "$(cat .curl.cm.$$)" "$(cat .curl.cem.$$)" "$(cat .curl.nifi.$$)" "$(cat .curl.nifireg.$$)" "$(cat .curl.schreg.$$)" "$(cat .curl.smm.$$)" "$(cat .curl.hue.$$)" "$(cat .curl.cml.$$)" "$(cat .curl.model.$$)" "$(cat .curl.viz.$$)"
done | sort -t\[ -k1,1r -k2,2n
fi
14 changes: 6 additions & 8 deletions setup/terraform/resources/cdsw_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ def add_vizapps_user(username, password, first_name, last_name):
print('# Create user')
while True:
try:
print(CDSW_API)
r = s.post(CDSW_API + '/users',
json={
'email': EMAIL,
Expand Down Expand Up @@ -134,7 +133,7 @@ def add_vizapps_user(username, password, first_name, last_name):
models = [m for m in r.json() if m['name'] == model_name]
if models and models[0]['latestModelDeployment']['status'] == 'deployed':
model_id = models[0]['id']
project_id = get_project(name=PROJECT_NAME)['id']
project = get_project(name=PROJECT_NAME)
print('Model is already deployed!! Skipping.')
else:
print('# Add engine')
Expand All @@ -153,8 +152,8 @@ def add_vizapps_user(username, password, first_name, last_name):
'project_visibility': 'private',
'name': PROJECT_NAME,
'gitUrl': 'https://github.com/cloudera-labs/edge2ai-workshop'})
project_id = r.json()['id']
print('Project ID: %s'% (project_id,))
project = r.json()
print('Project ID: %s' % (project['id'],))

print('# Upload setup script')
setup_script = """!pip3 install --upgrade pip scikit-learn
Expand All @@ -166,7 +165,7 @@ def add_vizapps_user(username, password, first_name, last_name):
r = s.put(CDSW_API + '/projects/admin/edge2ai-workshop/files/setup_workshop.py', files={'name': setup_script})

print('# Upload model')
model_pkl = open(MODEL_PKL_FILE, 'r')
model_pkl = open(MODEL_PKL_FILE, 'rb')
r = s.put(CDSW_API + '/projects/admin/edge2ai-workshop/files/iot_model.pkl', files={'name': model_pkl})

print('# Create job to run the setup script')
Expand Down Expand Up @@ -216,7 +215,7 @@ def add_vizapps_user(username, password, first_name, last_name):

print('# Deploy model')
r = s.post(CDSW_ALTUS_API + '/models/create-model', json={
'projectId': project_id,
'projectId': project['id'],
'name': model_name,
'description': model_name,
'visibility': 'private',
Expand Down Expand Up @@ -272,7 +271,6 @@ def add_vizapps_user(username, password, first_name, last_name):
print(viz_project_url + '/engine-images')
r = s.patch(viz_project_url + '/engine-images',
json={'engineImageId': engine_image_id})
print(r)
r = s.get(viz_project_url + '/engine-images')
project_engine_image_id = r.json()['id']
print('Project image default engine Image ID set to: %s'% (project_engine_image_id))
Expand Down Expand Up @@ -302,7 +300,7 @@ def add_vizapps_user(username, password, first_name, last_name):
print('# Wait for model to start')
while True:
r = s.post(CDSW_ALTUS_API + '/models/list-models', json={
'project': str(project_id),
'project': str(project['id']),
'latestModelDeployment': True,
'latestModelBuild': True,
})
Expand Down
46 changes: 38 additions & 8 deletions setup/terraform/resources/labs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,29 @@ def __init__(cls, name, bases, dct):


class AbstractWorkshop(metaclass=AbstractWorkshopMeta):
def __init__(self, run_id=None):
def __init__(self, run_id=None, context=None):
class _Context(object):
pass

self.context = _Context()
self.context = context or _Context()
self.run_id = run_id if run_id is not None else get_run_id()

@classmethod
@abstractmethod
def workshop_id(cls):
"""Return a short string to identify the CA type."""
"""Return a short string to identify the workshop."""
pass

@classmethod
@abstractmethod
def prereqs(cls):
"""
Return a list of prereqs for this workshop. The list can contain either:
- Strings identifying the name of other workshops that need to be setup before this one does. In
this case all the labs of the specified workshop will be setup.
- Tuples (String, Integer), where the String specifies the name of the workshop and Integer the number
of the last lab of that workshop to be executed/setup.
"""
pass

def before_setup(self):
Expand All @@ -135,7 +147,20 @@ def after_setup(self):
def teardown(self):
pass

def _execute_prereqs(self):
global WORKSHOPS
for prereq in self.prereqs():
if isinstance(prereq, str):
workshop = prereq
lab = 99
else:
workshop, lab = prereq

LOG.info('Executing prereqs setup: Workshop {}, Lab < {}'.format(workshop, lab))
WORKSHOPS[workshop](self.run_id, self.context).setup(lab)

def setup(self, target_lab=99):
self._execute_prereqs()
self.before_setup()
lab_setup_functions = [(n, f, _get_step_number(n)) for n, f in
getmembers(self.__class__) if _get_step_number(n) is not None]
Expand All @@ -147,7 +172,10 @@ def setup(self, target_lab=99):
else:
LOG.debug("[{0}] is numbered higher than target [lab{1}], skipping".format(func_name, target_lab))
self.after_setup()
return self.context

def get_artifacts_dir(self):
return os.path.join(os.path.dirname(__file__), 'artifacts', self.workshop_id())

def _load_workshops():
base_dir = get_base_dir()
Expand All @@ -158,22 +186,24 @@ def _load_workshops():


def global_setup(target_workshop='base', target_lab=99, run_id=None):
LOG.info('Executing global setup for Lab {} in Workshop {}'.format(target_workshop, target_lab))
_load_workshops()
if target_workshop in WORKSHOPS:
LOG.info('Executing setup for Lab {} in Workshop {}'.format(target_workshop, target_lab))
WORKSHOPS[target_workshop](run_id).setup(target_lab)
else:
raise RuntimeError("Workshop [{}] not found. Known workshops are: {}".format(target_workshop, WORKSHOPS))
LOG.info('Global setup completed successfully!')


def global_teardown(target_workshop='base', run_id=None):
LOG.info('Executing global teardown for Workshop {}'.format(target_workshop))
def global_teardown(target_workshop=None, run_id=None):
_load_workshops()
if target_workshop in WORKSHOPS:
if target_workshop is not None:
LOG.info('Executing teardown for Workshop {}'.format(target_workshop))
WORKSHOPS[target_workshop](run_id).teardown()
else:
raise RuntimeError("Workshop [{}] not found. Known workshops are: {}".format(target_workshop, WORKSHOPS))
for target_workshop in WORKSHOPS:
LOG.info('Executing teardown for Workshop {}'.format(target_workshop))
WORKSHOPS[target_workshop](run_id).teardown()
LOG.info('Global teardown completed successfully!')


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"reportimage": [],
"dashboards": [],
"segments": [],
"appgroups": [],
"visuals": [],
"appgroupmembership": [],
"events": [],
"colorpalette": [],
"dateranges": [],
"datasets": [
{
"model": "datasets.dataset",
"pk": 26,
"fields": {
"dataconnection": 22,
"dataset_name": "sensor data1",
"dataset_type": "singletable",
"dataset_detail": "default.sensors",
"dataset_description": "",
"dataset_info": "[{\"tablename\": \"default.sensors\", \"columns\": [{\"name\": \"sensor_id\", \"type\": \"INT\", \"isdim\": true, \"alias\": \"sensor_id\"}, {\"name\": \"\", \"type\": \"TIMESTAMP\", \"isdim\": true, \"alias\": \"sensor_timestamp\", \"basecol\": \"sensor_ts\", \"expr\": \"microseconds_add(to_timestamp(cast([sensor_ts]/1000000 as bigint)), [sensor_ts] % 1000000)\"}, {\"name\": \"sensor_ts\", \"type\": \"BIGINT\", \"isdim\": false, \"alias\": \"sensor_ts\"}, {\"name\": \"sensor_0\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_0\"}, {\"name\": \"sensor_1\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_1\"}, {\"name\": \"sensor_2\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_2\"}, {\"name\": \"sensor_3\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_3\"}, {\"name\": \"sensor_4\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_4\"}, {\"name\": \"sensor_5\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_5\"}, {\"name\": \"sensor_6\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_6\"}, {\"name\": \"sensor_7\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_7\"}, {\"name\": \"sensor_8\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_8\"}, {\"name\": \"sensor_9\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_9\"}, {\"name\": \"sensor_10\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_10\"}, {\"name\": \"sensor_11\", \"type\": \"DOUBLE\", \"isdim\": false, \"alias\": \"sensor_11\"}, {\"name\": \"is_healthy\", \"type\": \"INT\", \"isdim\": false, \"alias\": \"is_healthy\"}]}]",
"uuid": "73d9de65-3fdf-4ff3-a1a2-cc08c2a7701b",
"imported_uuid": null,
"cache_sequence": 0,
"dataset_settings": "{}",
"search_enabled": false
}
}
],
"customcss": [],
"staticasset": [],
"version": {
"Arcviz Version": "6.2.3",
"Raw Timestamp of last commit": "1611943183",
"Timestamp of last commit": "Fri Jan 29 18:59:43 2021 +0100",
"SHA of last commit": "4e609f54bd9deb0e1e61658008174cafa75f7e3c",
"Description": "6.2.3-b18"
}
}
Loading

0 comments on commit e8de299

Please sign in to comment.