Upgraded to Polymer 0.5
This commit is contained in:
parent
4dcdca1bd5
commit
23d080af86
13 changed files with 9909 additions and 10894 deletions
|
@ -1,10 +1,21 @@
|
|||
# To build the frontend, you need node, bower and vulcanize
|
||||
# npm install -g bower vulcanize
|
||||
|
||||
# Install dependencies
|
||||
cd homeassistant/components/http/www_static/polymer
|
||||
bower install
|
||||
cd ..
|
||||
cp polymer/bower_components/platform/platform.js polymer_platform.js
|
||||
cp polymer/bower_components/webcomponentsjs/webcomponents.min.js .
|
||||
|
||||
# Let Polymer refer to the minified JS version before we compile
|
||||
sed -i.bak 's/polymer\.js/polymer\.min\.js/' polymer/bower_components/polymer/polymer.html
|
||||
vulcanize -o frontend.html --inline polymer/splash-login.html
|
||||
|
||||
# Revert back the change to the Polymer component
|
||||
rm polymer/bower_components/polymer/polymer.html
|
||||
mv polymer/bower_components/polymer/polymer.html.bak polymer/bower_components/polymer/polymer.html
|
||||
|
||||
# Generate the MD5 hash of the new frontend
|
||||
cd ..
|
||||
echo '""" DO NOT MODIFY. Auto-generated by build_frontend script """' > frontend.py
|
||||
echo 'VERSION = "'`md5 -q www_static/frontend.html`'"' >> frontend.py
|
||||
|
|
|
@ -362,7 +362,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||
"<body fullbleed>"
|
||||
"<h3 id='init' align='center'>Initializing Home Assistant</h3>"
|
||||
"<script"
|
||||
" src='/static/polymer_platform.js'></script>"
|
||||
" src='/static/webcomponents.min.js'></script>"
|
||||
"<link rel='import' href='/static/{}' />"
|
||||
"<splash-login auth='{}'></splash-login>"
|
||||
"</body></html>").format(app_url, data.get('api_password', '')))
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
""" DO NOT MODIFY. Auto-generated by build_frontend script """
|
||||
VERSION = "655f75099496ad5e46673b838a21df2a"
|
||||
VERSION = "1fee8e3caed50ae728e12ebab5316a2d"
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -15,23 +15,26 @@
|
|||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"polymer": "Polymer/polymer#~0.4.2",
|
||||
"font-roboto": "Polymer/font-roboto#~0.4.2",
|
||||
"core-header-panel": "Polymer/core-header-panel#~0.4.2",
|
||||
"core-toolbar": "Polymer/core-toolbar#~0.4.2",
|
||||
"paper-toast": "Polymer/paper-toast#~0.4.2",
|
||||
"paper-dialog": "Polymer/paper-dialog#~0.4.2",
|
||||
"paper-button": "Polymer/paper-button#~0.4.2",
|
||||
"core-tooltip": "Polymer/core-tooltip#~0.4.2",
|
||||
"moment": "~2.8.3",
|
||||
"paper-input": "Polymer/paper-input#~0.4.2",
|
||||
"core-menu": "Polymer/core-menu#~0.4.2",
|
||||
"core-item": "Polymer/core-item#~0.4.2",
|
||||
"core-icons": "polymer/core-icons#~0.4.2",
|
||||
"paper-toggle-button": "polymer/paper-toggle-button#~0.4.2",
|
||||
"paper-tabs": "polymer/paper-tabs#~0.4.2",
|
||||
"paper-icon-button": "polymer/paper-icon-button#~0.4.2",
|
||||
"paper-menu-button": "polymer/paper-menu-button#~0.4.2",
|
||||
"paper-item": "polymer/paper-item#~0.4.2"
|
||||
"webcomponentsjs": "Polymer/webcomponentsjs#~0.5",
|
||||
"font-roboto": "Polymer/font-roboto#~0.5",
|
||||
"core-header-panel": "Polymer/core-header-panel#~0.5",
|
||||
"core-toolbar": "Polymer/core-toolbar#~0.5",
|
||||
"core-tooltip": "Polymer/core-tooltip#~0.5",
|
||||
"core-menu": "Polymer/core-menu#~0.5",
|
||||
"core-item": "Polymer/core-item#~0.5",
|
||||
"core-input": "Polymer/core-input#~0.5",
|
||||
"core-icons": "polymer/core-icons#~0.5",
|
||||
"paper-toast": "Polymer/paper-toast#~0.5",
|
||||
"paper-dialog": "Polymer/paper-dialog#~0.5",
|
||||
"paper-spinner": "Polymer/paper-spinner#~0.5",
|
||||
"paper-button": "Polymer/paper-button#~0.5",
|
||||
"paper-input": "Polymer/paper-input#~0.5",
|
||||
"paper-toggle-button": "polymer/paper-toggle-button#~0.5",
|
||||
"paper-tabs": "polymer/paper-tabs#~0.5",
|
||||
"paper-icon-button": "polymer/paper-icon-button#~0.5",
|
||||
"paper-menu-button": "polymer/paper-menu-button#~0.5",
|
||||
"paper-dropdown": "polymer/paper-dropdown#~0.5",
|
||||
"paper-item": "polymer/paper-item#~0.5",
|
||||
"moment": "~2.8.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
<link rel="import" href="bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-dialog-transition.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-action-dialog.html">
|
||||
<link rel="import" href="bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input-decorator.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-autogrow-textarea.html">
|
||||
|
||||
<link rel="import" href="events-list.html">
|
||||
|
||||
<polymer-element name="event-fire-dialog" attributes="api">
|
||||
<template>
|
||||
|
||||
<paper-action-dialog id="dialog" heading="Fire Event" transition="core-transition-bottom" backdrop>
|
||||
<style>
|
||||
:host {
|
||||
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
|
||||
}
|
||||
|
||||
paper-input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
paper-input:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
@ -22,14 +33,21 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<paper-dialog id="dialog" heading="Fire Event" transition="paper-dialog-transition-bottom" backdrop="true">
|
||||
<div layout horizontal>
|
||||
<div>
|
||||
<paper-input id="inputType" label="Event Type" floatingLabel="true" autofocus required></paper-input>
|
||||
<paper-input id="inputData" label="Event Data (JSON, optional)" floatingLabel="true" multiline></paper-input>
|
||||
<paper-input-decorator
|
||||
label="Event Data (JSON, optional)"
|
||||
floatingLabel="true">
|
||||
<!--
|
||||
<paper-autogrow-textarea id="inputDataWrapper">
|
||||
<textarea id="inputData"></textarea>
|
||||
</paper-autogrow-textarea>
|
||||
-->
|
||||
<textarea id="inputData" rows="5"></textarea>
|
||||
</paper-input-decorator>
|
||||
</div>
|
||||
<div class='eventContainer'>
|
||||
<b>Available events:</b>
|
||||
|
@ -60,7 +78,8 @@
|
|||
},
|
||||
|
||||
setEventData: function(eventData) {
|
||||
this.$.inputData.value = eventData;
|
||||
this.$.inputData.value = eventData;
|
||||
// this.$.inputDataWrapper.update();
|
||||
},
|
||||
|
||||
eventSelected: function(eventType) {
|
||||
|
@ -68,10 +87,15 @@
|
|||
},
|
||||
|
||||
clickFireEvent: function() {
|
||||
this.api.fire_event(
|
||||
this.$.inputType.value,
|
||||
JSON.parse(this.$.inputData.value)
|
||||
)
|
||||
var data;
|
||||
|
||||
if(this.$.inputData.value != "") {
|
||||
data = JSON.parse(this.$.inputData.value);
|
||||
} else {
|
||||
data = {};
|
||||
}
|
||||
|
||||
this.api.fire_event(this.$.inputType.value, data);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -181,7 +181,7 @@
|
|||
|
||||
fetchEvents: function(onSuccess, onError) {
|
||||
var successEventsUpdated = function(events) {
|
||||
this.events = this.events;
|
||||
this.events = events;
|
||||
|
||||
this.fire('events-updated')
|
||||
|
||||
|
@ -234,10 +234,12 @@
|
|||
},
|
||||
|
||||
call_service: function(domain, service, parameters) {
|
||||
parameters = parameters || {};
|
||||
|
||||
var successToast = function() {
|
||||
if(service == "turn_on" && parameters.entity_id) {
|
||||
this.showToast("Turned on " + parameters.entity_id + '.');
|
||||
} else if(service == "turn_off") {
|
||||
} else if(service == "turn_off" && parameters.entity_id) {
|
||||
this.showToast("Turned off " + parameters.entity_id + '.');
|
||||
} else {
|
||||
this.showToast("Service "+domain+"/"+service+" called.");
|
||||
|
@ -270,6 +272,8 @@
|
|||
},
|
||||
|
||||
fire_event: function(eventType, eventData) {
|
||||
eventData = eventData || {};
|
||||
|
||||
var successToast = function() {
|
||||
this.showToast("Event "+eventType+" fired.");
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<link rel="import" href="bower_components/core-header-panel/core-header-panel.html">
|
||||
<link rel="import" href="bower_components/core-toolbar/core-toolbar.html">
|
||||
<link rel="import" href="bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="bower_components/paper-menu-button/paper-menu-button.html">
|
||||
<link rel="import" href="bower_components/paper-tabs/paper-tabs.html">
|
||||
<link rel="import" href="bower_components/paper-tabs/paper-tab.html">
|
||||
<link rel="import" href="bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="bower_components/paper-menu-button/paper-menu-button.html">
|
||||
<link rel="import" href="bower_components/paper-dropdown/paper-dropdown.html">
|
||||
<link rel="import" href="bower_components/core-menu/core-menu.html">
|
||||
<link rel="import" href="bower_components/paper-item/paper-item.html">
|
||||
|
||||
<link rel="import" href="states-cards.html">
|
||||
|
||||
|
@ -12,10 +14,6 @@
|
|||
<template>
|
||||
<style type="text/css">
|
||||
|
||||
:host {
|
||||
font-family: 'RobotoDraft', sans-serif;
|
||||
}
|
||||
|
||||
core-header-panel {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
@ -33,6 +31,16 @@
|
|||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
margin: 0;
|
||||
padding: 8px 0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<core-header-panel fullbleed>
|
||||
|
@ -44,16 +52,22 @@
|
|||
<paper-icon-button icon="refresh" on-click="{{handleRefreshClick}}"></paper-icon-button>
|
||||
<paper-icon-button icon="settings-remote"
|
||||
on-click="{{handleServiceClick}}"></paper-icon-button>
|
||||
<paper-menu-button icon="more-vert" halign="right">
|
||||
<paper-item label="Set State">
|
||||
<a on-click={{handleAddStateClick}}></a>
|
||||
</paper-item>
|
||||
<paper-item label="Trigger Event">
|
||||
<a on-click={{handleEventClick}}></a>
|
||||
</paper-item>
|
||||
<paper-item label="Log Out">
|
||||
<a on-click={{handleLogOutClick}}></a>
|
||||
</paper-item>
|
||||
|
||||
<paper-menu-button>
|
||||
<paper-icon-button icon="more-vert" noink></paper-icon-button>
|
||||
<paper-dropdown class="dropdown" halign="right" duration="200">
|
||||
<core-menu class="menu">
|
||||
<paper-item label="Set State">
|
||||
<a on-click={{handleAddStateClick}}></a>
|
||||
</paper-item>
|
||||
<paper-item label="Trigger Event">
|
||||
<a on-click={{handleEventClick}}></a>
|
||||
</paper-item>
|
||||
<paper-item label="Log Out">
|
||||
<a on-click={{handleLogOutClick}}></a>
|
||||
</paper-item>
|
||||
</core-menu>
|
||||
</paper-dropdown>
|
||||
</paper-menu-button>
|
||||
|
||||
<div class="bottom fit" horizontal layout>
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
<link rel="import" href="bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-action-dialog.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-dialog-transition.html">
|
||||
<link rel="import" href="bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input-decorator.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-autogrow-textarea.html">
|
||||
|
||||
<link rel="import" href="services-list.html">
|
||||
|
||||
<polymer-element name="service-call-dialog" attributes="api">
|
||||
<template>
|
||||
|
||||
<paper-action-dialog id="dialog" heading="Call Service" transition="core-transition-bottom" backdrop="true">
|
||||
<style>
|
||||
:host {
|
||||
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
|
||||
}
|
||||
|
||||
paper-input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
paper-input:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
@ -22,15 +34,22 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<paper-dialog id="dialog" heading="Call Service" transition="paper-dialog-transition-bottom" backdrop="true">
|
||||
<div layout horizontal>
|
||||
<div>
|
||||
<paper-input id="inputDomain" label="Domain" floatingLabel="true" autofocus required></paper-input>
|
||||
<paper-input id="inputService" label="Service" floatingLabel="true" required></paper-input>
|
||||
<paper-input id="inputData" label="Service Data (JSON, optional)" floatingLabel="true" multiline></paper-input>
|
||||
<paper-input-decorator
|
||||
label="Service Data (JSON, optional)"
|
||||
floatingLabel="true">
|
||||
<!--
|
||||
<paper-autogrow-textarea id="inputDataWrapper">
|
||||
<textarea id="inputData"></textarea>
|
||||
</paper-autogrow-textarea>
|
||||
-->
|
||||
<textarea id="inputData" rows="5"></textarea>
|
||||
</paper-input-decorator>
|
||||
</div>
|
||||
<div class='serviceContainer'>
|
||||
<b>Available services:</b>
|
||||
|
@ -39,7 +58,7 @@
|
|||
</div>
|
||||
<paper-button dismissive>Cancel</paper-button>
|
||||
<paper-button affirmative on-click={{clickCallService}}>Call Service</paper-button>
|
||||
</paper-dialog>
|
||||
</paper-action-dialog>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
|
@ -52,6 +71,7 @@
|
|||
show: function(domain, service, serviceData) {
|
||||
this.setService(domain, service);
|
||||
this.$.inputData.value = serviceData;
|
||||
// this.$.inputDataWrapper.update();
|
||||
this.$.dialog.toggle();
|
||||
},
|
||||
|
||||
|
@ -65,11 +85,16 @@
|
|||
},
|
||||
|
||||
clickCallService: function() {
|
||||
var data;
|
||||
|
||||
if(this.$.inputData.value != "") {
|
||||
data = JSON.parse(this.$.inputData.value);
|
||||
}
|
||||
|
||||
this.api.call_service(
|
||||
this.$.inputDomain.value,
|
||||
this.$.inputService.value,
|
||||
JSON.parse(this.$.inputData.value)
|
||||
)
|
||||
data);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<link rel="import" href="bower_components/font-roboto/roboto.html">
|
||||
<link rel="import" href="bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input-decorator.html">
|
||||
<link rel="import" href="bower_components/core-input/core-input.html">
|
||||
<link rel="import" href="bower_components/paper-spinner/paper-spinner.html">
|
||||
|
||||
<link rel="import" href="home-assistant-main.html">
|
||||
<link rel="import" href="home-assistant-api.html">
|
||||
|
@ -10,17 +12,29 @@
|
|||
<style type="text/css">
|
||||
|
||||
:host {
|
||||
font-family: 'RobotoDraft', sans-serif;
|
||||
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
paper-input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.login paper-button {
|
||||
margin-left: 242px;
|
||||
}
|
||||
|
||||
.login .interact {
|
||||
height: 110px;
|
||||
height: 125px;
|
||||
}
|
||||
|
||||
#validateBox {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#validateMessage {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -35,14 +49,17 @@
|
|||
|
||||
<div class='interact' layout vertical>
|
||||
<div id='loginform'>
|
||||
<paper-input
|
||||
id="passwordInput" label="Password" type="password"
|
||||
value="{{auth}}" on-keyup="{{passwordKeyup}}" autofocus>
|
||||
</paper-input>
|
||||
<paper-input-decorator label="Password" id="passwordDecorator">
|
||||
<input is="core-input" type="password" id="passwordInput"
|
||||
value="{{auth}}" on-keyup="{{passwordKeyup}}" autofocus>
|
||||
</paper-input-decorator>
|
||||
<paper-button on-click={{validatePassword}}>Log In</paper-button>
|
||||
</div>
|
||||
|
||||
<div id="validateMessage" hidden>Validating password...</div>
|
||||
<div id="validateBox" hidden>
|
||||
<paper-spinner active="true"></paper-spinner><br />
|
||||
<div id="validateMessage">Validating password...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -82,13 +99,15 @@
|
|||
passwordKeyup: function(ev) {
|
||||
if(ev.keyCode == 13) {
|
||||
this.validatePassword();
|
||||
} else {
|
||||
this.$.passwordDecorator.isInvalid = false;
|
||||
}
|
||||
},
|
||||
|
||||
validatePassword: function() {
|
||||
this.$.passwordInput.commit();
|
||||
a = this.$.passwordInput;
|
||||
this.$.loginform.setAttribute('hidden', null);
|
||||
this.$.validateMessage.removeAttribute('hidden');
|
||||
this.$.validateBox.removeAttribute('hidden');
|
||||
|
||||
var passwordValid = function(result) {
|
||||
this.$.validateMessage.innerHTML = "Loading data...";
|
||||
|
@ -101,14 +120,14 @@
|
|||
|
||||
var passwordInvalid = function(result) {
|
||||
if(result && result.message) {
|
||||
this.$.passwordInput.error = result.message;
|
||||
this.$.passwordDecorator.error = result.message;
|
||||
} else {
|
||||
this.$.passwordInput.error = "Unexpected result from API";
|
||||
this.$.passwordDecorator.error = "Unexpected result from API";
|
||||
}
|
||||
this.auth = null;
|
||||
this.$.passwordInput.setAttribute('required', true);
|
||||
this.$.passwordDecorator.isInvalid = true;
|
||||
this.$.loginform.removeAttribute('hidden');
|
||||
this.$.validateMessage.setAttribute('hidden', null);
|
||||
this.$.validateBox.setAttribute('hidden', null);
|
||||
this.$.passwordInput.focus();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
<link rel="import" href="bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-dialog-transition.html">
|
||||
<link rel="import" href="bower_components/paper-dialog/paper-action-dialog.html">
|
||||
<link rel="import" href="bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-input-decorator.html">
|
||||
<link rel="import" href="bower_components/paper-input/paper-autogrow-textarea.html">
|
||||
|
||||
<link rel="import" href="entity-list.html">
|
||||
|
||||
<polymer-element name="state-set-dialog" attributes="api">
|
||||
<template>
|
||||
<paper-action-dialog id="dialog" heading="Set State" transition="core-transition-center" backdrop="true">
|
||||
<style>
|
||||
:host {
|
||||
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
|
||||
}
|
||||
|
||||
paper-input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
paper-input:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
@ -22,15 +32,22 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<paper-dialog id="dialog" heading="Set State" transition="paper-dialog-transition-center" backdrop="true">
|
||||
<div layout horizontal>
|
||||
<div>
|
||||
<paper-input id="inputEntityID" label="Entity ID" floatingLabel="true" autofocus required></paper-input>
|
||||
<paper-input id="inputState" label="State" floatingLabel="true" required></paper-input>
|
||||
<paper-input id="inputData" label="State attributes (JSON, optional)" floatingLabel="true" multiline></paper-input>
|
||||
<paper-input-decorator
|
||||
label="State attributes (JSON, optional)"
|
||||
floatingLabel="true">
|
||||
<!--
|
||||
<paper-autogrow-textarea id="inputDataWrapper">
|
||||
<textarea id="inputData"></textarea>
|
||||
</paper-autogrow-textarea>
|
||||
-->
|
||||
<textarea id="inputData" rows="5"></textarea>
|
||||
</paper-input-decorator>
|
||||
</div>
|
||||
<div class='stateContainer'>
|
||||
<b>Current entities:</b>
|
||||
|
@ -39,7 +56,7 @@
|
|||
</div>
|
||||
<paper-button dismissive>Cancel</paper-button>
|
||||
<paper-button affirmative on-click={{clickSetState}}>Set State</paper-button>
|
||||
</paper-dialog>
|
||||
</paper-action-dialog>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
|
|
File diff suppressed because one or more lines are too long
14
homeassistant/components/http/www_static/webcomponents.min.js
vendored
Normal file
14
homeassistant/components/http/www_static/webcomponents.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue