aboutsummaryrefslogtreecommitdiff
path: root/javascript/app/components
diff options
context:
space:
mode:
authorYuchen Pei <hi@ypei.me>2022-09-19 11:22:21 +1000
committerYuchen Pei <hi@ypei.me>2022-09-19 11:22:21 +1000
commitef1b927861f9a949aed20341144ffb5bfd42f038 (patch)
tree48bd4688928546bedc6504aad76bf6e0327fcef9 /javascript/app/components
parent117850d8f659517cb818a857dc04c8f5157795c4 (diff)
Removing the web client
Diffstat (limited to 'javascript/app/components')
-rw-r--r--javascript/app/components/.gitkeep0
-rw-r--r--javascript/app/components/bottom-panel.js52
-rw-r--r--javascript/app/components/expression-info.js3
-rw-r--r--javascript/app/components/file-tree.js118
-rw-r--r--javascript/app/components/haskell-module.js520
-rw-r--r--javascript/app/components/identifier-info.js73
-rw-r--r--javascript/app/components/identifier-name.js61
-rw-r--r--javascript/app/components/infinite-list.js50
-rw-r--r--javascript/app/components/info-window.js144
-rw-r--r--javascript/app/components/input-with-autocomplete.js136
-rw-r--r--javascript/app/components/instance-info.js21
-rw-r--r--javascript/app/components/paginated-list.js48
-rw-r--r--javascript/app/components/resizable-panel.js76
-rw-r--r--javascript/app/components/text-file.js67
-rw-r--r--javascript/app/components/type-component.js29
-rw-r--r--javascript/app/components/type-signature-text.js4
-rw-r--r--javascript/app/components/type-signature.js23
17 files changed, 0 insertions, 1425 deletions
diff --git a/javascript/app/components/.gitkeep b/javascript/app/components/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/javascript/app/components/.gitkeep
+++ /dev/null
diff --git a/javascript/app/components/bottom-panel.js b/javascript/app/components/bottom-panel.js
deleted file mode 100644
index 6415d0e..0000000
--- a/javascript/app/components/bottom-panel.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import Ember from 'ember';
-
-function show(component) {
- const height = Math.floor(component.$containerElement.height() /2);
- component.$().css({
- "display":"block",
- "top" : height+"px"
- });
- component.$topPanelElement.css({
- "height":height+"px"
- });
-}
-
-function hide(component) {
- const height = Math.floor(component.$containerElement.height()/2);
- component.$().css({
- "display":"none",
- "height":height+"px"
- });
- component.$topPanelElement.css({
- "height":"100%"
- });
-}
-
-export default Ember.Component.extend({
- classNames:["bottom-panel"],
- didInsertElement : function () {
- this._super(...arguments);
- this.$topPanelElement = Ember.$(this.get('topPanelElementId'));
- this.$containerElement = Ember.$(this.get('containerElementId'));
- Ember.run.next(this,() => {
- Ember.$(this.element).resizable({
- handles:"n",
- maxHeight:700,
- minHeight:200,
- resize: (event,ui) => {
- Ember.run.next(this,() => {
- this.$topPanelElement.css({"height": this.$containerElement.height() - ui.size.height});
- });
- }
- });
- });
- },
- visibilityObserver : Ember.observer('visible',function () {
- this.get('visible') ? show(this) : hide(this);
- }),
- actions : {
- close () {
- this.set('visible',false);
- }
- }
-});
diff --git a/javascript/app/components/expression-info.js b/javascript/app/components/expression-info.js
deleted file mode 100644
index d403c49..0000000
--- a/javascript/app/components/expression-info.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Ember from 'ember';
-export default Ember.Component.extend({
-});
diff --git a/javascript/app/components/file-tree.js b/javascript/app/components/file-tree.js
deleted file mode 100644
index f78ba1d..0000000
--- a/javascript/app/components/file-tree.js
+++ /dev/null
@@ -1,118 +0,0 @@
-import Ember from 'ember';
-
-const directoryTreeToJsTree = function (packageId,directoryTree) {
- return directoryTree.contents.map((node) => {
- const jsTreeNode = {};
- jsTreeNode.text = node.name;
- jsTreeNode.data = node;
- if(node.path) {
- jsTreeNode.id = node.path;
- jsTreeNode.a_attr = {href:"/package/" + packageId + "/show/" + node.path};
- }
- if(node.tag === "Dir") {
- jsTreeNode.children = directoryTreeToJsTree(packageId,node);
- jsTreeNode.state = {"opened" : containsHaskellModule(node)};
- } else {
- if(node.isHaskellModule) {
- jsTreeNode.icon = "/assets/haskell.ico";
- jsTreeNode.isHaskellModule = true;
- } else {
- jsTreeNode.icon = "jstree-file";
- jsTreeNode.isHaskellModule = false;
- }
- }
- return jsTreeNode;
- });
-};
-
-const containsHaskellModule = function(node) {
- return node.contents.some((n) => {
- if(n.tag === "File") {
- return n.isHaskellModule;
- } else {
- return containsHaskellModule(n);
- }
- });
-}
-
-const fileExtension = function (filename) {
- const idx = filename.lastIndexOf('.');
- return (idx < 1) ? "" : filename.substr(idx + 1);
-}
-
-export default Ember.Component.extend({
- query: null,
- sortType: "alphabetical",
- sortTypeObserver : Ember.observer('sortType',function() {
- Ember.run.next(this,() => {
- this.jstree.refresh();
- });
- }),
- didInsertElement : function () {
- this._super(...arguments);
- const element = this.element.getElementsByClassName('file-tree')[0];
- const component = this;
-
- const jstreeElement = Ember.$(element).jstree({
- 'core' : {
- 'data' : directoryTreeToJsTree(this.get('packageId'),this.get('directoryTree'))
- },
- "plugins" : [
- "search",
- "sort"
- ],
- "search": {
- "case_insensitive": true,
- "show_only_matches" : true,
- "show_only_matches_children": true
- },
- 'sort' : function (a,b) {
- const node1 = this.get_node(a).data;
- const node2 = this.get_node(b).data;
- if(component.get("sortType") === "alphabetical") {
- return node1.name.localeCompare(node2.name);
- } else {
- const extendedName1 = (node1.tag === "Dir" ? "0" : "1") + fileExtension(node1.name) + node1.name;
- const extendedName2 = (node2.tag === "Dir" ? "0" : "1") + fileExtension(node2.name) + node2.name;
- return extendedName1.localeCompare(extendedName2);
- }
- }
- });
-
- jstreeElement.on("select_node.jstree",(event,data) => {
- const file = data.node.data;
- if(file.tag != "Dir") {
- this.sendAction('openFile',file.path);
- }
- });
-
- const jstree = jstreeElement.jstree(true);
-
- if(this.get('currentFile')) {
- jstree.select_node(this.get('currentFile'));
- const node = jstree.get_node(this.get('currentFile'),true)[0];
- if(node) {
- node.scrollIntoView();
- }
- }
- this.jstree = jstree;
- },
- currentFileObserver : Ember.observer('currentFile',function() {
- Ember.run.next(() => {
- this.jstree.deselect_all();
- this.jstree.select_node(this.get('currentFile'));
- });
- }),
- queryObserver : Ember.observer('query',function() {
- if(this.get('query')) {
- this.jstree.search(this.get('query'));
- } else {
- this.jstree.clear_search();
- }
- }),
- actions : {
- hide() {
- this.get('hide')();
- }
- }
-});
diff --git a/javascript/app/components/haskell-module.js b/javascript/app/components/haskell-module.js
deleted file mode 100644
index 187e6c5..0000000
--- a/javascript/app/components/haskell-module.js
+++ /dev/null
@@ -1,520 +0,0 @@
-import Ember from 'ember';
-import {goToDefinition} from '../utils/go-to-definition';
-import {initializeLineSelection} from '../utils/line-selection';
-import {addLinksToLanguageExtensionsDocs} from '../utils/language-extensions';
-
-function compareLocations (p1,p2) {
- if(p1.line === p2.line) {
- if(p1.column === p2.column) {
- return 0;
- } else if(p1.column > p2.column) {
- return 1;
- } else {
- return -1;
- }
- } else if(p1.line > p2.line) {
- return 1;
- } else {
- return -1;
- }
-}
-
-function buildSrcSpan(sourceCodeLines,start,end) {
- if(sourceCodeLines[start.line] && sourceCodeLines[end.line]) {
- if(start.line === end.line) {
- return sourceCodeLines[start.line].slice(start.column-1,end.column-1);
- } else {
- const firstLine = sourceCodeLines[start.line];
- let middleLines = [];
- for(let i = start.line + 1; i < end.line;i ++) {
- middleLines.push(sourceCodeLines[i]);
- }
- const lastLine = sourceCodeLines[end.line];
- const minOffset = Math.min(start.column,
- (middleLines.concat([lastLine]))
- .map((line) => line.search(/\S/))
- .reduce((min,value) => Math.min(min,value)));
- return firstLine.slice(start.column-1,firstLine.length) + "\n"
- + middleLines.map((line) => line.slice(minOffset,line.length)).join("\n")
- + (middleLines.length ? "\n" : "") + lastLine.slice(minOffset,end.column-1);
- }
- } else {
- return null;
- }
-}
-
-function modifyClass(element,on) {
- if(on) {
- element.classList.add('highlighted-identifier');
- } else {
- element.classList.remove('highlighted-identifier');
- }
-}
-
-function highlightIdentifiers(parentElement,identifierElement,on) {
- if(identifierElement.id) {
- const identifiers = Array.prototype.slice.call(parentElement.querySelectorAll("span[id='"+identifierElement.id+"']"));
- identifiers.forEach((identifier) => {
- modifyClass(identifier,on);
- });
- } else {
- modifyClass(identifierElement,on);//Literal
- }
-}
-
-//divident is a string
-//divident may have any number of digits
-function modulo(divident, divisor) {
- return Array.from(divident).map(c => parseInt(c))
- .reduce((acc, value) => {
- return (acc * 10 + value) % divisor;
- },0);
-}
-
-function isDefinedInCurrentModule(moduleName,modulePath,identifierInfo) {
- return (identifierInfo.sort === "External") &&
- (identifierInfo.locationInfo.modulePath === modulePath
- || identifierInfo.locationInfo.moduleName === moduleName)
-}
-
-function identifierStyle(identifierElement,
- identifiers,
- occurrences,
- path,
- colorTheme,
- moduleName) {
- const idOcc = occurrences[identifierElement.dataset.occurrence];
-
- let color = colorTheme.defaultColor;
- let fontWeight;
-
- if(idOcc) {
- if(idOcc.sort.tag === 'TypeId') {
- color = colorTheme.typeColor;
- } else if(idOcc.description === "HsLit" ||
- idOcc.description === "HsOverLit"||
- idOcc.description === "LitPat" ||
- idOcc.description === "NPat" ||
- idOcc.description === "NPlusKPat" ||
- idOcc.description === "OverLit") {
- color = colorTheme.literalColor;
- } else {
- const idInfo = identifiers[identifierElement.dataset.identifier];
- if(idInfo) {
- if(isDefinedInCurrentModule(moduleName,path,idInfo)) {
- color = colorTheme.topLevelIdFromCurrentModule;
- } else if(idInfo.sort === "Internal" && idInfo.locationInfo.tag === "ExactLocation") {
- const colorNumber = modulo(identifierElement.id,colorTheme.localIdentifierColor.length);
- color = colorTheme.localIdentifierColor[colorNumber];
- fontWeight = "bold";
- }
- }
- }
- }
-
- return "color:"+color+";"
- +(fontWeight ? "font-weight:" + fontWeight : "")+";"
- +(idOcc.isBinder ? "text-decoration:underline;" : "");
-}
-
-function initializeIdentifiers (sourceCodeContainerElement,component) {
- const identifierElements = Array.prototype.slice.call(sourceCodeContainerElement.querySelectorAll("span.identifier"));
- if(identifierElements.length > 0) {
- const timeout = 250;//milliseconds
- let timer = null;
-
- identifierElements.forEach((identifierElement) => {
-
- const cssText = identifierStyle(identifierElement,
- component.get('identifiers'),
- component.get('occurrences'),
- component.get('path'),
- component.get('colorTheme'),
- component.get('name'));
-
- identifierElement.style.cssText = cssText;
-
- //go to definition
- identifierElement.onmouseup = (event) => {
- if(timer) {
- clearTimeout(timer);
- }
-
- if(!window.getSelection().isCollapsed) {
- return;
- }
-
- const identifierInfo = component.get('identifiers')[identifierElement.dataset.identifier];
- const idOccurrenceInfo = component.get('occurrences')[identifierElement.dataset.occurrence];
-
- const currentLineNumber = parseInt(identifierElement.parentNode.dataset.line);
-
- if(idOccurrenceInfo.sort.tag === "ModuleId") {
- goToDefinition(component.get('store'),
- idOccurrenceInfo.sort.contents,
- event.which,
- currentLineNumber);
- }
- else {
- if(identifierInfo && (event.which === 1 || event.which === 2)) {
- if(!idOccurrenceInfo.isBinder) {
- goToDefinition(component.get('store'),
- identifierInfo.locationInfo,
- event.which,
- currentLineNumber);
- } else {
- if(identifierInfo.sort === "External") {
- component.get('findReferences')(component.get('packageId'),
- identifierInfo.externalId,
- identifierInfo.demangledOccName,
- identifierInfo.locationInfo);
-
- }
- }
- }
- }
- }
- identifierElement.onmouseover = () => {
- highlightIdentifiers(sourceCodeContainerElement,identifierElement,true);
- if(timer) {
- clearTimeout(timer);
- }
- timer = setTimeout(() => {
- Ember.run.next(component,() => {
- const identifierInfo = component.get('identifiers')[identifierElement.dataset.identifier];
- const identifierOccurrence = component.get('occurrences')[identifierElement.dataset.occurrence];
- console.log(identifierOccurrence);
- console.log(identifierInfo);
-
- component.set('selectedIdentifier',identifierElement);
- component.set('currentLineNumber',parseInt(identifierElement.parentNode.dataset.line) || 1);
- component.set('identifierInfo',identifierInfo);
- component.set('identifierOccurrence',identifierOccurrence);
- component.set('hasSelectedExpression',false);
- component.set('isHoveredOverIdentifier',true);
-
- });
- },timeout);
- };
-
- identifierElement.onmouseout = () => {
- highlightIdentifiers(sourceCodeContainerElement,identifierElement,false);
-
- if(timer) {
- clearTimeout(timer);
- }
-
- timer = setTimeout (() => {
- Ember.run.next(component,() => {
- component.set('isHoveredOverIdentifier',false);
- });
- },timeout);
- };
- });
- component.timer = timer;
- }
-}
-
-
-
-function contains (node, other) {
- return node === other || !!(node.compareDocumentPosition(other) & 16);
-}
-
-function initializeExpressionInfo(sourceCodeContainerElement,component) {
- const lineElements = Array.prototype.slice.call(sourceCodeContainerElement.querySelectorAll("td.line-content"));
- if(lineElements.length > 0) {
-
- //Line numbers start with 1
- let sourceCodeLines = [""];
-
- lineElements.forEach((el) => {
- sourceCodeLines.push(el.textContent);
- });
-
- const allowedNodeNames = ["#text","SPAN","TD"];
- let isLoading = false;
- let shouldWait = false;
- const timeout = 400;//milliseconds
-
- const onmouseup = function() {
- Ember.run.next(() => {
- if(isLoading || shouldWait) {
- return;
- }
- shouldWait = true;
- setTimeout(() => {shouldWait = false;},timeout);
-
- component.set('hasSelectedExpression',false);
-
- const selection = window.getSelection();
-
- //Selection of multiple lines inside a table doesn't work in Firefox
- //https://bugzilla.mozilla.org/show_bug.cgi?id=365900
-
- if(!(selection.anchorNode && selection.focusNode)
- || !contains(sourceCodeContainerElement,selection.anchorNode)
- || !contains(sourceCodeContainerElement,selection.focusNode)
- || (allowedNodeNames.indexOf(selection.anchorNode.nodeName) === -1)
- || (allowedNodeNames.indexOf(selection.focusNode.nodeName) === -1)
- || selection.isCollapsed) {
- return;
- }
-
- // Detects whether the selection is backwards
- const detectionRange = document.createRange();
- detectionRange.setStart(selection.anchorNode, selection.anchorOffset);
- detectionRange.setEnd(selection.focusNode, selection.focusOffset);
- const isBackward = detectionRange.collapsed;
-
- let startNode,startNodeOffset,endNode,endNodeOffset;
-
- if(isBackward) {
- startNode = selection.focusNode;
- startNodeOffset = selection.focusOffset;
- endNode = selection.anchorNode;
- endNodeOffset = selection.anchorOffset;
- } else {
- startNode = selection.anchorNode;
- startNodeOffset = selection.anchorOffset;
- endNode = selection.focusNode;
- endNodeOffset = selection.focusOffset;
- }
-
- let lineStart,columnStart,lineEnd,columnEnd;
- let infoWindowTargetElement;
-
-
- //HTML inside source code container :
- //<tr><td><span data-start="1" date-end="3">abc</span><span>...</span></td></tr>
- //<tr>...</tr>
- if(startNode.nodeName === "#text") {
- const parent = startNode.parentNode;//<span>
- columnStart = parseInt(parent.dataset.start) + startNodeOffset;
- lineStart = parseInt(parent.parentNode.dataset.line);
-
- if(startNodeOffset === startNode.textContent.length && parent.nextSibling === null) {
- const tr = startNode.parentNode.parentNode.parentNode;// span -> td -> tr
-
- //Skipping empty lines
- let nextLine = tr.nextSibling;
- while(nextLine.children[1].textContent === "") {
- nextLine = nextLine.nextSibling;
- }
- infoWindowTargetElement = nextLine.children[1].children[0];
-
- } else {
- if(!(startNodeOffset === 0) && (parent.nextSibling)) {
- infoWindowTargetElement = parent.nextSibling;
- } else {
- infoWindowTargetElement = parent;
- }
- }
- } else if(startNode.nodeName === "SPAN") {
- columnStart = 1;
- lineStart = parseInt(startNode.parentNode.dataset.line);
-
- const tr = startNode.parentNode.parentNode; // td -> tr
- let nextLine = tr.nextSibling;
- while(nextLine.children[1].textContent === "") {
- nextLine = nextLine.nextSibling;
- }
- infoWindowTargetElement = nextLine.children[1].children[0];
-
- } else if(startNode.nodeName === "TD") {
- if(startNodeOffset > 0) {
- const child = startNode.children[startNodeOffset-1];
- columnStart = parseInt(child.dataset.start);
- } else {
- columnStart = 1;
- }
- lineStart = parseInt(startNode.id.slice(2));
- infoWindowTargetElement = startNode.children[0];
- }
-
- if(endNode.nodeName === "#text") {
- columnEnd = parseInt(endNode.parentNode.dataset.start) + endNodeOffset;
- lineEnd = parseInt(endNode.parentNode.parentNode.dataset.line);
- } else if(endNode.nodeName === "SPAN") {
- columnEnd = 1;
- lineEnd = parseInt(endNode.parentNode.dataset.line);
- } else if(endNode.nodeName === "TD"){
- if(endNodeOffset > 0) {
- const child = endNode.children[endNodeOffset-1];
- columnEnd = parseInt(child.dataset.start);
- } else {
- columnEnd = 1;
- }
- lineEnd = parseInt(endNode.id.slice(2));
- }
-
- const loadExprPromise = component.get('store').loadExpressions(
- component.get('packageId'),
- component.get('path'),
- lineStart,
- columnStart,
- lineEnd,
- columnEnd);
- isLoading = true;
-
- loadExprPromise.then((expressions) => {
- Ember.run.next(() => {
- if(expressions && expressions.length > 0) {
- expressions.sort(function(expr1,expr2) {
- if( compareLocations(expr1.srcSpan.start,expr2.srcSpan.start) <= 0
- && compareLocations(expr1.srcSpan.end,expr2.srcSpan.end) >= 0 ) {
- return -1;
- } else {
- return 1;
- }
- });
-
- const expressionsWithSourceCode = expressions.reduce((result,expression) => {
- const object = Ember.copy(expression);
- const srcSpan = buildSrcSpan(sourceCodeLines,
- expression.srcSpan.start,
- expression.srcSpan.end);
- if(srcSpan) {
- object.sourceCode = srcSpan;
- return result.concat(object);
- } else {
- return result;
- }
- },[]);
-
- if(expressionsWithSourceCode.length > 0) {
- component.set('selectedIdentifier',infoWindowTargetElement);
- component.set('expressions',expressionsWithSourceCode);
- component.set('currentLineNumber',parseInt(infoWindowTargetElement.parentNode.dataset.line) || 1);
- component.set('hasSelectedExpression',true);
-
- }
- }
- isLoading = false;
- });
- });
- });
- };
-
- sourceCodeContainerElement.addEventListener('mouseup',onmouseup);
- component._onmouseup = onmouseup;
- }
-}
-
-export default Ember.Component.extend({
- store : Ember.inject.service('store'),
- selectedIdentifier : null,
- isHoveredOverIdentifier : false,
- hasSelectedExpression : false,
- showDeclarations : true,
- showDeclarationsLabel : Ember.computed('showDeclarations',function () {
- return this.get('showDeclarations') ? "Hide" : "Show";
- }),
- queryObserver : Ember.observer("query",function() {
- Ember.run.debounce(this, () => {
- const regExp = new RegExp(this.get('query'),"i");
- const filteredDeclarations = this.get('declarations').filter((d) => d.name.search(regExp) != -1);
- Ember.run.next(() => {
- this.set('filteredDeclarations',filteredDeclarations);
- });
- }, 300);
- }),
- identifierLocationInfo : Ember.computed('identifierInfo','identifierOccurrence',function() {
- const idOcc = this.get('identifierOccurrence');
- const idInfo = this.get('identifierInfo');
- if(idOcc) {
- if(idOcc.sort.tag === "ModuleId") {
- return idOcc.sort.contents;
- } else {
- if(idInfo) {
- return idInfo.locationInfo;
- } else {
- return null;
- }
- }
- }
- }),
- themeObserver : Ember.observer('colorTheme',function() {
- Ember.run.next(this,() => {
- this.cleanup();
- this.didInsertElement();
- });
- }),
- fileObserver : Ember.observer('path',function() {
- Ember.run.next(this,() => {
- this.cleanup();
- this.didInsertElement();
- });
- }),
- cleanup() {
- if(this.timer) {
- clearTimeout(this.timer);
- }
- if(this._onhashchange) {
- window.removeEventListener('hashchange',this._onhashchange);
- }
- if(this._onkeydown) {
- document.removeEventListener('keydown',this._onkeydown);
- }
- if(this._onkeyup) {
- document.removeEventListener('keyup',this._onkeyup);
- }
- if(this._onmouseup) {
- this.sourceCodeContainerElement.removeEventListener('mouseup',this._onmouseup);
- }
- this.set('selectedIdentifier',null);
- this.set('isHoveredOverIdentifier',false);
- this.set('hasSelectedExpression',false);
- this.set('showDeclarations',true);
- },
- didReceiveAttrs() {
- this.set('filteredDeclarations',this.get('declarations'));
- },
- didInsertElement() {
- this._super(...arguments);
- const sourceCodeContainerElement = this.element.querySelector('.source-code-container');
- sourceCodeContainerElement.innerHTML = this.get('html');
- this.sourceCodeContainerElement = sourceCodeContainerElement;
-
- // Add links to Haskell language extensions docs
- const lines = this.sourceCodeContainerElement.querySelectorAll("tr > td:nth-child(2)");
- const lineCount = lines.length;
- let i = 0;
- while(i < lineCount) {
- const line = lines.item(i);
- const lineText = line.textContent;
- if(lineText) {
- // A file-header pragma must precede the module keyword in the file.
- if(lineText.indexOf("module ") === 0) {
- break;
- } else {
- line.innerHTML = addLinksToLanguageExtensionsDocs(lineText);
- }
- }
- i = i + 1;
- }
-
- this.element.parentNode.scrollTop = 0;
- const declarations = this.element.querySelector('.declarations-content');
- this.set('query','');
- if(declarations) {
- declarations.scrollTop = 0;
- }
- Ember.run.next(this,() => {
- initializeIdentifiers(sourceCodeContainerElement,this);
- initializeLineSelection(sourceCodeContainerElement,this);
- initializeExpressionInfo(sourceCodeContainerElement,this);
- });
- },
- willDestroyElement() {
- this.cleanup();
- },
- actions : {
- goToLine(lineNumber) {
- window.location.hash = "L"+lineNumber;
- },
- toggleShowDeclarations() {
- this.toggleProperty('showDeclarations');
- }
- }
-});
diff --git a/javascript/app/components/identifier-info.js b/javascript/app/components/identifier-info.js
deleted file mode 100644
index 79c35c6..0000000
--- a/javascript/app/components/identifier-info.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import Ember from 'ember';
-import {goToDefinition} from '../utils/go-to-definition';
-
-export default Ember.Component.extend({
- store : Ember.inject.service('store'),
- downloadedDocumentation : null,
- didInsertElement () {
- const onmouseup = (event) => {
- if(event.target.dataset.location) {
- let location;
- try {
- location = JSON.parse(event.target.dataset.location);
- } catch (e) {
- console.log(e);
- }
- if(location) {
- goToDefinition(this.get('store'),location,event.which,this.get('currentLineNumber'));
- }
- }
- };
- this.element.addEventListener('mouseup',onmouseup);
- this._onmouseup = onmouseup;
- },
- willDestroyElement : function () {
- if(this._onmouseup) {
- this.element.removeEventListener('mouseup',this._onmouseup);
- }
- },
- //Naughty record selectors :
- //https://github.com/ghc/ghc/blob/ced2cb5e8fbf4493488d1c336da7b00d174923ce/compiler/typecheck/TcTyDecls.hs#L940-L961
- isNaughtyRecSel : Ember.computed('identifierInfo',function () {
- const idInfo = this.get('identifierInfo');
- return idInfo ? (idInfo.details === "RecSelIdNaughty") : false;
- }),
- isExternalIdentifier : Ember.computed('identifierInfo',function () {
- const idInfo = this.get('identifierInfo');
- return idInfo ? (idInfo.sort === "External") : false;
- }),
- identifierObserver : Ember.observer('identifierInfo',function () {
- this.set("downloadedDocumentation","");
- const idInfo = this.get('identifierInfo');
- if(idInfo) {
- const locationInfo = idInfo.locationInfo;
- if(locationInfo.tag === "ApproximateLocation") {
- const packageId = locationInfo.packageId.name + "-" + locationInfo.packageId.version;
- const currentIdentifier = idInfo;
-
- this.get('store').loadDefinitionSite(packageId,
- locationInfo.moduleName,
- locationInfo.componentId,
- locationInfo.entity,
- locationInfo.name)
- .then((definitionSite) => {
- Ember.run.next(this,() => {
- if(currentIdentifier === this.get('identifierInfo')) {
- this.set('downloadedDocumentation',definitionSite.documentation);
- }})
- }).catch(() => {
- this.get('store').loadHoogleDocs(packageId,
- locationInfo.moduleName,
- locationInfo.entity,
- locationInfo.name)
- .then((hoogleDocs) => {
- Ember.run.next(this,() => {
- if(currentIdentifier === this.get('identifierInfo')) {
- this.set('downloadedDocumentation',hoogleDocs);
- }});
- });
- });
- }
- }
- })
-});
diff --git a/javascript/app/components/identifier-name.js b/javascript/app/components/identifier-name.js
deleted file mode 100644
index 4b01b03..0000000
--- a/javascript/app/components/identifier-name.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import Ember from 'ember';
-import {goToDefinition} from '../utils/go-to-definition';
-
-export default Ember.Component.extend({
- store : Ember.inject.service('store'),
- name : Ember.computed('identifierElement',function() {
- const element = this.get('identifierElement');
- if(element) {
- return element.innerText;
- }
- }),
- style : Ember.computed('identifierElement',function() {
- const element = this.get('identifierElement');
- if(element) {
- return new Ember.String.htmlSafe("color:"+element.style.color);
- }
- }),
- locationInfo : Ember.computed('identifierInfo','identifierOccurrence',function() {
- if(this.get('identifierOccurrence.sort.tag') === "ModuleId") {
- return this.get('identifierOccurrence.sort.contents');
- } else {
- return this.get('identifierInfo.locationInfo');
- }
- }),
- location : Ember.computed('locationInfo',function() {
- const loc = this.get('locationInfo');
- if(loc) {
- if(loc.tag === "ExactLocation") {
- return loc.modulePath;
- } else if(loc.tag === "ApproximateLocation") {
- if(loc.entity === "Mod") {
- return loc.packageId.name + "-" + loc.packageId.version;
- } else {
- return loc.packageId.name + "-" + loc.packageId.version + " " + loc.moduleName;
- }
- } else {
- return loc.contents;
- }
- } else {
- return "";
- }
- }),
- isExternalIdentifier : Ember.computed('identifierInfo',function () {
- return (this.get('identifierInfo.sort') === "External");
- }),
- actions : {
- goToDefinition (event) {
- goToDefinition(this.get('store'),
- this.get('locationInfo'),
- event.which,
- this.get('currentLineNumber'));
- return false;
- },
- findReferences (identifierInfo,currentPackageId) {
- this.get('findReferences')(currentPackageId,
- identifierInfo.externalId,
- identifierInfo.demangledOccName,
- identifierInfo.locationInfo);
- }
- }
-});
diff --git a/javascript/app/components/infinite-list.js b/javascript/app/components/infinite-list.js
deleted file mode 100644
index 02e1943..0000000
--- a/javascript/app/components/infinite-list.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import Component from '@ember/component';
-import { run } from '@ember/runloop';
-import { observer } from '@ember/object';
-
-let pageNumber;
-let updating = false;
-
-function initialize(component) {
- component.set('renderedElements',component.get('elements').slice(0,component.get('perPage')));
- pageNumber = 1;
-}
-
-export default Component.extend({
- renderedElements : [],
- init() {
- this._super(...arguments);
- initialize(this);
- },
- elementsObserver : observer('elements',function() {
- initialize(this);
- const containerElement = document.getElementById(this.get('containerElementId'));
- if(containerElement) {
- containerElement.scrollTop = 0;
- }
- }),
- didInsertElement() {
- const containerElement = document.getElementById(this.get('containerElementId'));
- if(containerElement) {
- const component = this;
- containerElement.onscroll = function() {
- const perPage = component.get('perPage');
- const elements = component.get('elements');
-
- if(!updating &&
- (pageNumber * perPage < elements.length) &&
- (containerElement.scrollTop + containerElement.offsetHeight
- > component.element.offsetHeight - 100)) {
-
- updating = true;
- run.next(component,() => {
- const newElements = elements.slice(pageNumber * perPage,(pageNumber + 1) * perPage);
- component.get('renderedElements').pushObjects(newElements);
- pageNumber ++;
- updating = false;
- });
- }
- }
- }
- }
-});
diff --git a/javascript/app/components/info-window.js b/javascript/app/components/info-window.js
deleted file mode 100644
index da669f1..0000000
--- a/javascript/app/components/info-window.js
+++ /dev/null
@@ -1,144 +0,0 @@
-import Ember from 'ember';
-
-let resizing = false;
-let dragging = false;
-
-function updatePosition(component) {
- const targetElement = component.get('targetElement');
- if(targetElement) {
- const infoWindowHeight = component.element.offsetHeight;
- const targetElementHeight = targetElement.offsetHeight;
-
- const parent = targetElement.parentNode;//<td> element
- const containerElement = document.querySelector("#" + component.get('containerElementId'));
-
- //getBoundingClientRect() returns the smallest rectangle which contains
- //the entire element, with read-only left, top, right, bottom, x, y, width,
- //and height properties describing the overall border-box in pixels. Properties
- //other than width and height are relative to the top-left of the *viewport*.
- const targetTopViewport = targetElement.getBoundingClientRect().top;
-
- let containerTopViewport;
- if (containerElement) {
- containerTopViewport = containerElement.getBoundingClientRect().top;
- } else {
- containerTopViewport = 0;
- }
-
- let infoWindowTop;
- if(targetTopViewport < infoWindowHeight + containerTopViewport) {
- //offsetTop is the number of pixels from the top of the closest relatively
- //positioned parent element.
- infoWindowTop = targetElement.offsetTop + parent.offsetTop
- + targetElementHeight + 10 + "px";
- } else {
- infoWindowTop = targetElement.offsetTop + parent.offsetTop
- - infoWindowHeight + "px";
- }
-
- const infoWindowLeft = targetElement.offsetLeft + parent.offsetLeft + "px";
-
- component.$().css({
- top:infoWindowTop,
- left:infoWindowLeft
- });
- } else {
- component.set('isPinned',false);
- }
-}
-
-export default Ember.Component.extend({
- classNames : ["info-window-container"],
- attributeBindings: ['hidden'],
- isPinned : false,
- isFocused: false,
- didInsertElement () {
- const component = this;
-
- const $headerElement = Ember.$(component.element.querySelector(".info-window-header"));
- const $contentElement = Ember.$(component.element.querySelector(".info-window-content"));
- const $infoWindowElement = Ember.$(component.element.querySelector(".info-window"));
- const $infoWindowContainerElement = Ember.$(component.element);
-
- this.$headerElement = $headerElement;
- this.$contentElement = $contentElement;
-
- this.$().resizable({
- handles: "n,w",
- minHeight: 80,
- minWidth: 400,
- start: function() {
- resizing = true;
- },
- stop: function() {
- resizing = false;
- },
- resize : function() {
- const containerHeight = $infoWindowContainerElement.height();
- $infoWindowElement.css({
- "height": containerHeight + 2 + "px"
- });
- $contentElement.css({
- "max-height":(containerHeight - $headerElement.outerHeight(true)) + "px"
- });
- }
- });
- this.$().draggable({
- containment:"#" + this.get('containerElementId'),
- handle: $headerElement,
- start: function() {
- dragging = true;
- },
- stop: function() {
- dragging = false;
- }
- });
- },
- mouseEnter () {
- if(!this.get('hasSelectedExpression')) {
- this.set('isFocused',true);
- }
- },
- mouseLeave (event) {
- //Workaround for a bug in Chrome
- const element = document.elementFromPoint(event.clientX,event.clientY);
- if(element && element.classList.contains('link')) {
- return;
- }
- if(!resizing
- && !dragging
- && !this.get('isPinned')
- && !this.get('hasSelectedExpression')) {
- this.set('isFocused',false);
- }
- },
- hidden : Ember.computed('isHoveredOverIdentifier',
- 'isFocused',
- 'hasSelectedExpression',
- 'isPinned', function() {
- if (this.$contentElement) {
- this.$contentElement.scrollTop(0);
- }
- if (this.get('isPinned')
- || this.get('isFocused')
- || this.get('isHoveredOverIdentifier')
- || this.get('hasSelectedExpression')) {
- return false;
- } else {
- return true;
- }
- }),
- didUpdate() {
- updatePosition(this);
- },
- actions : {
- close() {
- this.set('isPinned',false);
- this.set('isFocused',false);
- this.set('hasSelectedExpression',false);
- },
- pin() {
- this.toggleProperty('isPinned');
- }
- }
-});
diff --git a/javascript/app/components/input-with-autocomplete.js b/javascript/app/components/input-with-autocomplete.js
deleted file mode 100644
index 5960c46..0000000
--- a/javascript/app/components/input-with-autocomplete.js
+++ /dev/null
@@ -1,136 +0,0 @@
-import Ember from 'ember';
-export default Ember.Component.extend({
- store : Ember.inject.service('store'),
- highlightedItemIndex: -1,
- items : [],
- query: null,
- didInsertElement() {
- const $input = Ember.$(this.element).find(".search-input");
- const $autocompleteContainer = Ember.$(this.element).find(".autocomplete-container");
- this.$input = $input;
- this.$autocompleteContainer = $autocompleteContainer;
- const width = $input.width() + 300;
- $autocompleteContainer.css({
- "width" : width+"px",
- "top" : $input.outerHeight()
- });
- $input.keyup((e) => {
- if(e.which === 13) {
- this.onEnter();
- } else if(e.which === 27) {
- this.onEsc();
- } else if(e.which === 40) {
- this.onDown();
- } else if(e.which === 38) {
- this.onUp();
- }
- });
- $input.focusin(() => {
- this.showAutocompleteList();
- });
- $input.focusout(() => {
- //Timeout is needed to make sure that click event fires
- Ember.run.later((() => {
- this.hideAutocompleteList();
- }), 100);
- });
- },
- willDestroyElement() {
- this._super(...arguments);
- this.$input.off('keyup');
- this.$input.off('focusin');
- this.$input.off('focusout');
- },
- onEnter() {
- if(this.get('highlightedItemIndex') !== -1) {
- const item = this.get('items')[this.get('highlightedItemIndex')];
- if(item) {
- this.hideAutocompleteList();
- this.get('selectItem')(item);
- }
- } else {
- this.hideAutocompleteList();
- this.get('onSubmit')(this.get('query'));
- }
- },
- onEsc() {
- this.hideAutocompleteList();
- },
- onDown() {
- this.showAutocompleteList();
- const index = this.get('highlightedItemIndex');
- const items = this.get('items');
- const itemsCount = items.length;
- if(itemsCount > 0) {
- if(index !== -1) {
- if(index === itemsCount - 1) {
- this.set('highlightedItemIndex',0);
- } else {
- this.set('highlightedItemIndex',index+1);
- }
- } else {
- this.set('highlightedItemIndex',0);
- }
- }
- },
- onUp() {
- this.showAutocompleteList();
- const index = this.get('highlightedItemIndex');
- const items = this.get('items');
- const itemsCount = items.length;
- if(itemsCount > 0) {
- if(index !== -1) {
- if(index === 0) {
- this.set('highlightedItemIndex',itemsCount - 1);
- } else {
- this.set('highlightedItemIndex',index - 1);
- }
- } else {
- this.set('highlightedItemIndex',itemsCount - 1);
- }
- }
- },
- hideAutocompleteList() {
- this.set('highlightedItemIndex',-1);
- this.$autocompleteContainer.css({
- "display":"none",
- });
- },
- showAutocompleteList() {
- if(this.get('query') !== "") {
- this.$autocompleteContainer.css({
- "display":"block"
- });
- }
- },
- searchUrlObserver : Ember.observer('createSearchUrlFunction',function() {
- this.notifyPropertyChange('query');
- }),
- queryObserver : Ember.observer("query",function() {
- if(this.get('query')) {
- const perPage = this.get('maxItems') ? this.get('maxItems') : 10;
- const url = this.get('createSearchUrlFunction')(this.get('query')) + "?per_page=" + perPage;
- Ember.run.debounce(this, () => {
- this.get('store').loadFromUrlPaginated(url).then((result) => {
- Ember.run.next(() => {
- this.set('items',result.items);
- });
- });
- }, 400);
- this.showAutocompleteList();
- } else {
- this.hideAutocompleteList();
- this.set('items',[]);
- }
- }),
- actions : {
- onSubmit() {
- this.hideAutocompleteList();
- this.get('onSubmit')(this.get('query'));
- },
- goToDefinition (item) {
- this.hideAutocompleteList();
- this.get('selectItem')(item);
- }
- }
-});
diff --git a/javascript/app/components/instance-info.js b/javascript/app/components/instance-info.js
deleted file mode 100644
index 339d415..0000000
--- a/javascript/app/components/instance-info.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import Ember from 'ember';
-import {goToDefinition} from '../utils/go-to-definition';
-
-export default Ember.Component.extend({
- store : Ember.inject.service('store'),
- style : Ember.computed('nestedLevel',function() {
- return new Ember.String.htmlSafe("margin-left :" + this.get('nestedLevel') * 10 + "px");
- }),
- nextNestedLevel : Ember.computed('nestedLevel',function () {
- return this.get('nestedLevel') + 1;
- }),
- actions : {
- goToDefinition (event) {
- goToDefinition(this.get('store'),
- this.get('instance.location'),
- event.which,
- this.get('currentLineNumber'));
- return false;
- }
- }
-});
diff --git a/javascript/app/components/paginated-list.js b/javascript/app/components/paginated-list.js
deleted file mode 100644
index d4b6609..0000000
--- a/javascript/app/components/paginated-list.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import Ember from 'ember';
-function loadItems(store,component,url) {
- store.loadFromUrlPaginated(url).then((result) => {
- Ember.run.next(() => {
- component.set('total',result.total);
- component.set('items',result.items);
- component.set('first',result.linkHeader.first);
- component.set('next',result.linkHeader.next);
- component.set('prev',result.linkHeader.prev);
- component.set('last',result.linkHeader.last);
-
- const pageMatch = url.match(/(&|\?)page=(\d+)/);
- const perPageMatch = url.match(/(&|\?)per_page=(\d+)/);
-
- const page = pageMatch ? pageMatch[2] : 1;
- const perPage = perPageMatch ? perPageMatch[2] : 20;
-
- if(result.linkHeader.next || result.linkHeader.prev) {
- component.set('firstItemOnPage',(page - 1) * perPage + 1);
- if(!result.linkHeader.last) {
- component.set('lastItemOnPage',result.total);
- } else {
- component.set('lastItemOnPage',page * perPage);
- }
- }
- });
- });
-}
-
-export default Ember.Component.extend({
- store : Ember.inject.service('store'),
- init() {
- this._super(...arguments);
- if(this.get('url')) {
- loadItems(this.get('store'),this,this.get('url'));
- }
- },
- urlObserver : Ember.observer('url',function () {
- loadItems(this.get('store'),this,this.get('url'));
- this.element.querySelector(".paginated-list-content").scrollTop = 0;
- }),
- actions : {
- update(url) {
- this.element.querySelector(".paginated-list-content").scrollTop = 0;
- loadItems(this.get('store'),this,url);
- }
- }
-});
diff --git a/javascript/app/components/resizable-panel.js b/javascript/app/components/resizable-panel.js
deleted file mode 100644
index fe51ade..0000000
--- a/javascript/app/components/resizable-panel.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import Ember from 'ember';
-
-function hide (component,byUser) {
- component.$alsoResizeElement.css({left: 0});
- component.$().css({width:0});
- component.set('hidden',true);
- component.$(".show-left-panel-button").show();
- if(byUser) {
- component.set('hiddenByUser',true);
- }
-}
-
-function show (component,byUser) {
- component.$alsoResizeElement.css({left: 300});
- component.$().css({width:300});
- component.set('hidden',false);
- component.$(".show-left-panel-button").hide();
- if(byUser) {
- component.set('hiddenByUser',false);
- }
-}
-
-export default Ember.Component.extend({
- hidden:false,
- hiddenByUser:false,
- didInsertElement : function () {
- this._super(...arguments);
- Ember.run.next(this,() => {
- const onresize = () => {
- if(!this.get('hiddenByUser')) {
- const width = window.innerWidth;
- if(!this.get('hidden') && width < 700) {
- hide(this,false);
- } else if(this.get('hidden') && width > 700) {
- show(this,false);
- }
- }
- };
- this._onresize = onresize;
- window.addEventListener('resize', onresize);
- const $alsoResizeElement = Ember.$(this.get('alsoResizeElementId'));
- Ember.$(this.element).resizable({
- maxWidth: 800,
- minWidth: 200,
- handles: 'e',
- resize: (event,ui) => {
- Ember.run.next(this,() => {
- $alsoResizeElement.css({left: ui.size.width});
- });
- }
- });
- this.$alsoResizeElement = $alsoResizeElement;
- if(window.innerWidth < 700) {
- this.set('hidden',true);
- hide(this,false);
- }
- });
- },
- hideButtonLabel : Ember.computed('hidden',function() {
- return this.get('hidden') ? "&gt;" : "&lt;";
- }),
- willDestroyElement() {
- if(this._onresize) {
- window.removeEventListener('resize',this._onresize);
- }
- },
- actions : {
- hide() {
- if(this.get('hidden')) {
- show(this,true);
- } else {
- hide(this,true);
- }
- }
- }
-});
diff --git a/javascript/app/components/text-file.js b/javascript/app/components/text-file.js
deleted file mode 100644
index 2239571..0000000
--- a/javascript/app/components/text-file.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* global showdown */
-import Ember from 'ember';
-import {initializeLineSelection} from '../utils/line-selection';
-
-function escapeHtml(text) {
- return text.replace(/[\"&<>]/g, function (a) {
- return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
- });
-}
-
-function addLineNumbers (text) {
- const start = "<table class='source-code'><tbody>";
- const end = "</tbody></table>";
- let lineNumber = 0;
- const lines = text.split("\n").map((line) => {
- lineNumber ++;
- const lineNumberHtml = "<td id='LN"+lineNumber+"' class='line-number'>"+lineNumber+"</td>";
- const lineContentHtml = "<td id='LC"+lineNumber+"' class='line-content'>"+escapeHtml(line)+"</td>";
- return "<tr>"+ lineNumberHtml + lineContentHtml + "</tr>";
- }).join("");
- return start + lines + end;
-}
-
-const markdownExtensions = ["markdown", "mdown", "mkdn", "mkd", "md"];
-
-export default Ember.Component.extend({
- isMarkdown : Ember.computed('path',function() {
- const maybeExtension = this.get('path').split('.').pop();
- return markdownExtensions.any((extension) => (maybeExtension === extension));
- }),
- html : Ember.computed('path','isMarkdown',function() {
- if(this.get('isMarkdown')) {
- return this.markdownConverter.makeHtml(this.get('text'));
- } else {
- return addLineNumbers(this.get('text'));
- }
- }),
- init() {
- this._super(...arguments);
- this.markdownConverter = new showdown.Converter();
- },
- didInsertElement() {
- const sourceCodeContainerElement = this.element.querySelector('.source-code-container');
- initializeLineSelection(sourceCodeContainerElement,this);
- this.element.parentNode.scrollTop = 0;
- },
- willDestroyElement : function () {
- this.cleanup();
- },
- cleanup() {
- if(this._onhashchange) {
- window.removeEventListener('hashchange',this._onhashchange);
- }
- if(this._onkeydown) {
- document.removeEventListener('keydown',this._onkeydown);
- }
- if(this._onkeyup) {
- document.removeEventListener('keyup',this._onkeyup);
- }
- },
- pathObserver : Ember.observer('path',function() {
- Ember.run.next(this,() => {
- this.cleanup();
- this.didInsertElement();
- });
- })
-});
diff --git a/javascript/app/components/type-component.js b/javascript/app/components/type-component.js
deleted file mode 100644
index c19facc..0000000
--- a/javascript/app/components/type-component.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import Ember from 'ember';
-import {goToDefinition} from '../utils/go-to-definition';
-
-export default Ember.Component.extend({
- store : Ember.inject.service('store'),
- tagName : 'span',
- classNames: ["type-component"],
- contextMenu() {//right mouse button click to show kind of a type constructor or type variable
- if(this.get('identifiers') && this.get('internalId')) {
- this.set('expanded',true);
- }
- return false;
- },
- linkClass : Ember.computed('identifierInfo',function() {
- return this.get('identifierInfo') ? "link" : "";
- }),
- identifierInfo : Ember.computed('internalId',function() {
- return this.get('internalId') ? this.get('identifiers')[this.get('internalId')] : null;
- }),
- actions : {
- onmouseup (event) {
- if(this.get('identifierInfo') && (event.which !== 3 )) {
- const locationInfo = this.get('identifierInfo').locationInfo;
- goToDefinition(this.get('store'),locationInfo,event.which,this.get('currentLineNumber'));
- return false;
- }
- }
- }
-});
diff --git a/javascript/app/components/type-signature-text.js b/javascript/app/components/type-signature-text.js
deleted file mode 100644
index ce33607..0000000
--- a/javascript/app/components/type-signature-text.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import Ember from 'ember';
-export default Ember.Component.extend({
- tagName : "span"
-});
diff --git a/javascript/app/components/type-signature.js b/javascript/app/components/type-signature.js
deleted file mode 100644
index 8e7545f..0000000
--- a/javascript/app/components/type-signature.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import Ember from 'ember';
-export default Ember.Component.extend({
- tagName : "span",
- expandTypeSynonyms: false,
- expandTypeSynonymsLabel : Ember.computed('expandTypeSynonyms',function() {
- return this.get('expandTypeSynonyms') ? "Show type synonyms" : "Expand type synonyms";
- }),
- components : Ember.computed('type','expandTypeSynonyms',function() {
- if(this.get('expandTypeSynonyms') && this.get('type.componentsExpanded')) {
- return this.get('type.componentsExpanded');
- } else {
- return this.get('type.components');
- }
- }),
- typeObserver : Ember.observer('type',function() {
- this.set('expandTypeSynonyms',false);
- }),
- actions : {
- toggleExpandTypeSynonyms () {
- this.toggleProperty('expandTypeSynonyms');
- }
- }
-});