Subversion Repositories eFlore/Archives.cel-v1

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1 → Rev 2

/trunk/.classpath
New file
0,0 → 1,9
<?xml version="1.0" encoding="utf-8" ?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/opt/gwt/gwt-user.jar"/>
<classpathentry kind="var" path="JUNIT_HOME/junit.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
/trunk/src/org/tela_botanica/client/TopPanel.java
New file
0,0 → 1,39
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.tela_botanica.client;
 
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
 
/**
* Composite permet de wrapper des Widget pour creer un nouveau Widget cf methode initWidget()
*/
 
public class TopPanel extends Composite {
 
public TopPanel() {
HorizontalPanel outer = new HorizontalPanel();
 
outer.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
 
outer.add(new HTML("<b>Carnet en ligne</b>"));
 
initWidget(outer);
}
 
}
/trunk/src/org/tela_botanica/client/AutoCompleteAsyncTextBoxListener.java
New file
0,0 → 1,16
package org.tela_botanica.client;
 
 
/**
* Event listener interface for table events.
*/
public interface AutoCompleteAsyncTextBoxListener {
 
/**
* Fired when a AutoCompleteBox is validated (enter)
*
* @param sender the widget sending the event
* @param text : text selected
*/
void onValidate(SourcesAutoCompleteAsyncTextBoxEvents sender, String text);
}
/trunk/src/org/tela_botanica/client/Cel.java
New file
0,0 → 1,74
package org.tela_botanica.client;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.RootPanel;
 
import org.tela_botanica.client.TopPanel;
import org.tela_botanica.client.CenterPanel;
import org.tela_botanica.client.Shortcuts;
 
 
 
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class Cel implements EntryPoint {
 
private TopPanel topPanel = new TopPanel();
private CenterPanel centerPanel = new CenterPanel();
private Shortcuts shortcuts = new Shortcuts();
 
/**
* This is the entry point method.
*/
public void onModuleLoad() {
 
// Information haut de page (nom application, connexion ... etc).
// A regler
topPanel.setWidth("100%");
 
// DockPanel permet d'arranger plusieurs panneaux au coins cardinaux, le panneau central remplissant
// l'espace laissé.
DockPanel outer = new DockPanel();
outer.add(topPanel, DockPanel.NORTH);
outer.add(centerPanel, DockPanel.CENTER);
outer.add(shortcuts, DockPanel.WEST);
centerPanel.setWidth("100%");
// Shortcuts :
// Pour l'instant : relevés.
outer.setWidth("100%");
 
outer.setSpacing(4);
outer.setCellWidth(centerPanel, "100%");
// Window.enableScrolling(false);
Window.setMargin("0px");
 
// Finally, add the outer panel to the RootPanel, so that it will be
// displayed.
RootPanel.get().add(outer);
 
 
}
public void onWindowResized(int width, int height) {
// Adjust the shortcut panel and detail area to take up the available room
// in the window.
int shortcutHeight = height - shortcuts.getAbsoluteTop() - 8;
if (shortcutHeight < 1)
shortcutHeight = 1;
shortcuts.setHeight("" + shortcutHeight);
 
}
}
/trunk/src/org/tela_botanica/client/TaxonList.java
New file
0,0 → 1,155
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.tela_botanica.client;
 
 
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.HTTPRequest;
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
 
 
/**
* A composite that displays a list of emails that can be selected.
*/
public class TaxonList extends Composite implements AutoCompleteAsyncTextBoxListener {
 
 
private Grid header = new Grid(1,3);
private FlexTable table = new FlexTable();
private CellFormatter cellFormater = table.getCellFormatter();
private VerticalPanel panel = new VerticalPanel();
public TaxonList() {
// Setup the header
header.setCellSpacing(0);
header.setCellPadding(2);
header.setWidth("100%");
 
header.setStyleName("taxon-ListHeader");
header.setText(0, 0, "Action");
header.setText(0, 1, "Nom");
header.setText(0, 2, "Famille");
// Setup the table.
table.setCellSpacing(0);
table.setCellPadding(2);
table.setWidth("100%");
 
table.setStyleName("taxon-List");
 
panel.add(header);
panel.add(table);
initWidget(panel);
update();
 
}
public void onValidate(SourcesAutoCompleteAsyncTextBoxEvents sender, String str) {
// TODO : passer par une table de stockage temporaire
// TODO : creer un objet externe ...
int lastOrdre=new Integer(table.getText(table.getRowCount()-1,2)).intValue()+1;
int row=table.insertRow(table.getRowCount());
table.setWidget(row,0,new CheckBox());
table.setText(row,1,str);
table.setText(row,2,new Integer(lastOrdre).toString());
cellFormater.setVisible(row,2,false);
HTTPRequest.asyncPost("http://localhost/david/jrest/Inventory/", "identifiant=dd&nom="+str,
new ResponseTextHandler(){
 
public void onCompletion(String str) {
}
});
 
}
 
public void deleteElement() {
 
// Lifo ...
for (int i=table.getRowCount()-1; i>=0;i--){
if (((CheckBox) table.getWidget(i,0)).isChecked()) {
String str=table.getText(i,2);
table.removeRow(i);
HTTPRequest.asyncPost("http://localhost/david/jrest/Inventory/dd/"+str, "action=DELETE",
new ResponseTextHandler(){
 
public void onCompletion(String str) {
}
});
 
}
}
}
private void update() {
HTTPRequest.asyncGet("http://localhost/david/jrest/InventoryList/dd/"+"1",
new ResponseTextHandler(){
 
public void onCompletion(String str) {
 
JSONValue jsonValue= JSONParser.parse(str);
JSONArray jsonArray;
JSONArray jsonArrayNested;
// Lifo ...
for (int i=table.getRowCount()-1; i>=0;i--){
table.removeRow(i);
}
 
 
if ((jsonArray = jsonValue.isArray()) != null) {
for (int i = 0; i < jsonArray.size(); ++i) {
if ((jsonArrayNested = jsonArray.get(i).isArray()) != null) {
int row=table.insertRow(table.getRowCount());
table.setWidget(row,0,new CheckBox());
table.setText(row,1,((JSONString) jsonArrayNested.get(0)).stringValue());
table.setText(row,2,((JSONString) jsonArrayNested.get(1)).stringValue());
cellFormater.setVisible(row,2,false);
}
}
}
}
});
 
}
 
}
/trunk/src/org/tela_botanica/client/SourcesAutoCompleteAsyncTextBoxEvents.java
New file
0,0 → 1,7
package org.tela_botanica.client;
 
public interface SourcesAutoCompleteAsyncTextBoxEvents {
 
public void addAutoCompleteAsyncTextBoxListener(AutoCompleteAsyncTextBoxListener listener);
 
}
/trunk/src/org/tela_botanica/client/InventoryList.java
New file
0,0 → 1,38
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.tela_botanica.client;
 
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
 
/**
* A tree displaying a set of email folders.
*/
public class InventoryList extends Composite {
 
private Tree tree = new Tree();
 
public InventoryList() {
TreeItem root = new TreeItem("G&eacute;n&eacute;ral");
tree.addItem(root);
 
root.setState(true);
initWidget(tree);
}
 
}
/trunk/src/org/tela_botanica/client/NameAssistant.java
New file
0,0 → 1,40
package org.tela_botanica.client;
 
 
 
import java.util.EventListener;
 
 
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
 
 
import org.tela_botanica.client.AutoCompleteAsyncTextBox;
 
/**
* A composite that displays a list of names that can be selected.
*/
 
public class NameAssistant extends Composite implements EventListener {
 
private AutoCompleteAsyncTextBox autoCompletebox = new AutoCompleteAsyncTextBox();
private HorizontalPanel panel = new HorizontalPanel();
 
public NameAssistant(AutoCompleteAsyncTextBoxListener listener) {
// autoCompletebox.setSearchUrl("http://localhost/david/PHPJSON/server/server.php");
// autoCompletebox.setSearchUrl("http://localhost/david/papyrus/client/eflore_bp/index.php?module=recherche&action=completion_nom_latin&referentiel=25&format=json&nom=");
autoCompletebox.setSearchUrl("http://localhost/david/jrest/NameSearch/");
panel.add(autoCompletebox);
 
autoCompletebox.setWidth("100%");
initWidget(panel);
autoCompletebox.addAutoCompleteAsyncTextBoxListener(listener);
 
}
 
}
/trunk/src/org/tela_botanica/client/AutoCompleteAsyncTextBox.java
New file
0,0 → 1,328
/*
Auto-Completion Textbox for GWT
Copyright (C) 2006 Oliver Albers http://gwt.components.googlepages.com/
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
*/
package org.tela_botanica.client;
 
 
// TODO : traiter latence (augmenter en fonction rapidité saisie + texte vide)
// TODO : traiter Tab (selection)
// TODO : revoir traitement keyup, keydown
 
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.HTTPRequest;
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
 
import java.util.Vector;
import java.util.HashMap;
 
 
 
public class AutoCompleteAsyncTextBox extends TextBox
implements KeyboardListener, ChangeListener, SourcesAutoCompleteAsyncTextBoxEvents {
private String searchUrl = null;
private AutoCompleteAsyncTextBoxListenerCollection autoCompleteAsyncTextBoxListeners=null;
private HashMap cache = new HashMap();
private boolean searching = false;
protected PopupPanel choicesPopup = new PopupPanel(true);
protected ListBox choices = new ListBox();
protected Vector items = new Vector();
protected boolean popupAdded = false;
protected boolean visible = false;
/**
* Default Constructor
*
*/
public AutoCompleteAsyncTextBox()
{
super();
this.addKeyboardListener(this);
choices.addChangeListener(this);
this.setStyleName("AutoCompleteAsyncTextBox");
choicesPopup.add(choices);
choicesPopup.addStyleName("AutoCompleteChoices");
choices.setStyleName("list");
}
 
public void addAutoCompleteAsyncTextBoxListener(AutoCompleteAsyncTextBoxListener listener) {
if (autoCompleteAsyncTextBoxListeners == null) {
autoCompleteAsyncTextBoxListeners = new AutoCompleteAsyncTextBoxListenerCollection();
}
autoCompleteAsyncTextBoxListeners.addElement(listener);
}
 
 
public void setSearchUrl(String url) {
this.searchUrl=url;
}
private void doFetchURL(String match) {
/*
* Here we fetch the URL and call the handler
*/
if (this.searchUrl!=null && searching==false) {
searching=true;
HTTPRequest.asyncGet(this.searchUrl + match,
new ResponseTextHandler(){
public void onCompletion(String str) {
JSONValue jsonValue= JSONParser.parse(str);
JSONArray jsonArray;
JSONString jsonString;
 
if ((jsonArray = jsonValue.isArray()) != null) {
for (int i = 0; i < jsonArray.size(); ++i) {
if ((jsonString = (jsonArray.get(i)).isString()) != null) {
addItem(jsonString.stringValue());
}
}
}
 
displayList();
 
}
 
});
 
}
}
 
/**
* Not used at all
*/
public void onKeyDown(Widget arg0, char arg1, int arg2) {
}
 
/**
* Not used at all
*/
public void onKeyPress(Widget arg0, char arg1, int arg2) {
if(arg1 == KEY_DOWN)
{
int selectedIndex = choices.getSelectedIndex();
selectedIndex++;
if(selectedIndex >= choices.getItemCount())
{
selectedIndex = 0;
}
choices.setSelectedIndex(selectedIndex);
return;
}
if(arg1 == KEY_UP)
{
int selectedIndex = choices.getSelectedIndex();
selectedIndex--;
if(selectedIndex < 0)
{
selectedIndex = choices.getItemCount() - 1 ;
}
choices.setSelectedIndex(selectedIndex);
return;
}
}
 
/**
* A key was released, start autocompletion
*/
public void onKeyUp(Widget arg0, char arg1, int arg2) {
 
 
if(arg1 == KEY_DOWN)
{
return;
 
}
 
if(arg1 == KEY_UP)
{
return;
 
}
 
if(arg1 == KEY_ENTER)
{
if(visible)
{
complete();
}
else {
// Validation de l'entree :
if (autoCompleteAsyncTextBoxListeners!= null) {
autoCompleteAsyncTextBoxListeners.fireTextBoxEnter(this, this.getText());
}
this.setText("");
}
return;
}
if(arg1 == KEY_ESCAPE)
{
choices.clear();
items.clear();
choicesPopup.hide();
visible = false;
return;
}
// Lancement appel
String text = this.getText();
if(text.length() > 0)
{
items.clear();
if (getFromCache(text)!=null) {
items=getFromCache(text);
displayList();
}
else {
this.doFetchURL(text);
}
}
}
// Display assistant
public void displayList() {
searching=false;
if(this.items.size() > 0)
{
addToCache(this.getText(),(Vector) items.clone());
choices.clear();
for(int i = 0; i < items.size(); i++)
{
choices.addItem((String) items.get(i));
}
// if there is only one match and it is what is in the
// text field anyways there is no need to show autocompletion
if(items.size() == 1 && ((String) items.get(0)).compareTo(this.getText()) == 0)
{
choicesPopup.hide();
} else {
choices.setSelectedIndex(0);
choices.setVisibleItemCount(items.size());
if(!popupAdded)
{
RootPanel.get().add(choicesPopup);
popupAdded = true;
}
choicesPopup.show();
visible = true;
choicesPopup.setPopupPosition(this.getAbsoluteLeft(),
this.getAbsoluteTop() + this.getOffsetHeight());
//choicesPopup.setWidth(this.getOffsetWidth() + "px");
choices.setWidth(this.getOffsetWidth() + "px");
}
} else {
visible = false;
choicesPopup.hide();
}
}
 
/**
* A mouseclick in the list of items
*/
public void onChange(Widget arg0) {
complete();
}
public void onClick(Widget arg0) {
complete();
}
// add selected item to textbox
protected void complete()
{
if(choices.getItemCount() > 0)
{
this.setText(choices.getItemText(choices.getSelectedIndex()));
}
 
visible=false;
items.clear();
choices.clear();
choicesPopup.hide();
}
public void addItem(String item) {
items.add(item);
}
private void addToCache (String query, Vector result)
{
cache.put(query.toLowerCase(),result);
}
 
private Vector getFromCache (String query)
{
return (Vector) cache.get(query.toLowerCase());
}
 
 
}
/trunk/src/org/tela_botanica/client/Shortcuts.java
New file
0,0 → 1,44
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.tela_botanica.client;
 
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.StackPanel;
 
import org.tela_botanica.client.InventoryList;
 
/**
* A composite that contains the shortcut stack panel on the left side. The
* mailbox tree and shortcut lists don't actually do anything, but serve to show
* how you can construct an interface using
* {@link com.google.gwt.user.client.ui.StackPanel},
* {@link com.google.gwt.user.client.ui.Tree}, and other custom widgets.
*/
public class Shortcuts extends Composite {
 
private StackPanel stackPanel = new StackPanel();
 
public Shortcuts() {
// Create the groups within the stack panel.
stackPanel.add(new InventoryList(), "Relev&eacute;s", true);
 
// Show the mailboxes group by default.
stackPanel.showStack(0);
 
initWidget(stackPanel);
}
 
}
/trunk/src/org/tela_botanica/client/AutoCompleteAsyncTextBoxListenerCollection.java
New file
0,0 → 1,21
package org.tela_botanica.client;
 
import java.util.Iterator;
import java.util.Vector;
 
public class AutoCompleteAsyncTextBoxListenerCollection extends Vector {
private static final long serialVersionUID = -2767605614048989439L;
/**
* Fires a cellClicked event to all listeners.
*
* @param sender the widget sending the event
* @param text the text sent
*/
public void fireTextBoxEnter(SourcesAutoCompleteAsyncTextBoxEvents sender, String text) {
for (Iterator it = iterator(); it.hasNext();) {
AutoCompleteAsyncTextBoxListener listener = (AutoCompleteAsyncTextBoxListener) it.next();
listener.onValidate(sender, text);
}
}
}
/trunk/src/org/tela_botanica/client/CenterPanel.java
New file
0,0 → 1,50
package org.tela_botanica.client;
 
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Widget;
 
 
import org.tela_botanica.client.TaxonList;
import org.tela_botanica.client.NameAssistant;
 
 
/**
* Composite permet de wrapper des Widgett pour creer un nouveau Widget cf methode initWidget()
*/
 
public class CenterPanel extends Composite {
private TaxonList taxonList = new TaxonList();
private NameAssistant nameAssistant = new NameAssistant(taxonList);
 
 
public CenterPanel() {
VerticalPanel outer = new VerticalPanel();
VerticalPanel inner = new VerticalPanel();
inner.add(nameAssistant);
inner.add(new Button("Suppression",
new ClickListener() {
public void onClick(Widget sender) {
taxonList.deleteElement();
}
}
)
);
nameAssistant.setWidth("50%");
outer.add(inner);
inner.setWidth("100%");
outer.add(taxonList);
taxonList.setWidth("100%");
 
initWidget(outer);
}
 
}
/trunk/src/org/tela_botanica/public/blue_gradient.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/src/org/tela_botanica/public/blue_gradient.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/src/org/tela_botanica/public/Cel.css
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/src/org/tela_botanica/public/Cel.css
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/src/org/tela_botanica/public/gray_gradient.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/src/org/tela_botanica/public/gray_gradient.gif
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/src/org/tela_botanica/public/Cel.html
New file
0,0 → 1,46
<html>
<head>
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>Wrapper HTML for Cel</title>
 
<!-- -->
<!-- Use normal html, such as style -->
<!-- -->
<style>
body,td,a,div,.p{font-family:arial,sans-serif}
div,td{color:#000000}
a:link,.w,.w a:link{color:#0000cc}
a:visited{color:#551a8b}
a:active{color:#ff0000}
</style>
 
<!-- -->
<!-- The module reference below is the link -->
<!-- between html and your Web Toolkit module -->
<!-- -->
<meta name='gwt:module' content='org.tela_botanica.Cel'>
</head>
 
<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic ui -->
<!-- -->
<body>
 
<!-- -->
<!-- This script is required bootstrap stuff. -->
<!-- You can put it in the HEAD, but startup -->
<!-- is slightly faster if you include it here. -->
<!-- -->
<script language="javascript" src="gwt.js"></script>
 
<!-- OPTIONAL: include this if you want history support -->
<iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
 
</body>
</html>
/trunk/src/org/tela_botanica/Cel.gwt.xml
New file
0,0 → 1,11
<module>
 
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<inherits name='com.google.gwt.json.JSON' />
 
<!-- Specify the app entry point class. -->
<entry-point class='org.tela_botanica.client.Cel'/>
<stylesheet src='Cel.css'/>
</module>