From e65a0f24b32985037ce70ae71e0437f16e80f9fc Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Thu, 29 Apr 2010 10:26:15 +0000 Subject: [PATCH] LMS-1445 first check in SVN: 15674 --- openbis_knime/.classpath | 10 ++ openbis_knime/.gitignore | 0 openbis_knime/.project | 17 +++ openbis_knime/build/build.xml | 108 +++++++++++++++++ openbis_knime/dist/META-INF/MANIFEST.MF | 15 +++ openbis_knime/dist/icons/openbis.png | Bin 0 -> 707 bytes openbis_knime/dist/plugin.properties | 1 + openbis_knime/dist/plugin.xml | 14 +++ .../cisd/openbis/knime/TestNodeDialog.java | 111 +++++++++++++++++ .../cisd/openbis/knime/TestNodeFactory.java | 61 ++++++++++ .../cisd/openbis/knime/TestNodeFactory.xml | 26 ++++ .../cisd/openbis/knime/TestNodeModel.java | 113 ++++++++++++++++++ .../systemsx/cisd/openbis/knime/openbis.png | Bin 0 -> 707 bytes 13 files changed, 476 insertions(+) create mode 100644 openbis_knime/.classpath delete mode 100644 openbis_knime/.gitignore create mode 100644 openbis_knime/.project create mode 100644 openbis_knime/build/build.xml create mode 100755 openbis_knime/dist/META-INF/MANIFEST.MF create mode 100644 openbis_knime/dist/icons/openbis.png create mode 100644 openbis_knime/dist/plugin.properties create mode 100644 openbis_knime/dist/plugin.xml create mode 100644 openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeDialog.java create mode 100644 openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.java create mode 100644 openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.xml create mode 100644 openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeModel.java create mode 100644 openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/openbis.png diff --git a/openbis_knime/.classpath b/openbis_knime/.classpath new file mode 100644 index 00000000000..8e08285d5bf --- /dev/null +++ b/openbis_knime/.classpath @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="source/java"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="lib" path="/libraries/knime/knime-base.jar"/> + <classpathentry kind="lib" path="/libraries/knime/knime-core.jar"/> + <classpathentry kind="lib" path="/libraries/openbis-apis/query/openbis-query-api.jar"/> + <classpathentry kind="lib" path="/libraries/log4j/log4j.jar" sourcepath="/libraries/log4j/src.zip"/> + <classpathentry kind="output" path="targets/classes"/> +</classpath> diff --git a/openbis_knime/.gitignore b/openbis_knime/.gitignore deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/openbis_knime/.project b/openbis_knime/.project new file mode 100644 index 00000000000..9ef2c13b77e --- /dev/null +++ b/openbis_knime/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>openbis_knime</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/openbis_knime/build/build.xml b/openbis_knime/build/build.xml new file mode 100644 index 00000000000..d1c06b489b1 --- /dev/null +++ b/openbis_knime/build/build.xml @@ -0,0 +1,108 @@ +<project name="openbis_knime" basedir=".."> + <import file="../../build_resources/ant/build-common.xml" /> + <project-classpath name="ecp" classes="${classes}" /> + <property name="mainfolder" value="openbis_knime"/> + <property name="version" value="0.1.0"/> + <property name="jar.file.name" value="openbis-knime.jar"/> + <property name="jar.file" value="${dist}/${jar.file.name}"/> + <property name="original.dist" value="../${ant.project.name}/dist" /> + + + <!-- + // Cleans distribution directory. + --> + <target name="clean" description="Cleans distribution directory."> + <delete dir="${dist}" failonerror="true" /> + <mkdir dir="${dist}" /> + </target> + + <!-- + // Runs tests. + --> + <target name="run-tests"> + <antcall target="build-common.run-tests"> + <param name="test.suite" value="tests.xml" /> + </antcall> + </target> + + <!-- + // Creates build information. + --> + <target name="build-info" description="Creates build information."> + <!--build-info revision="revision.number" version="version.number" clean="clean.flag" /> + <echo file="${build.info.file}">${version.number}:${revision.number}:${clean.flag}</echo--> + <echo file="${build.info.file}">abc:123:d</echo> + </target> + + <!-- + // Creates JAR file. + --> + <target name="jar" depends="compile, build-info" description="Creates project jar file."> + <delete file="${jar.file}" /> + <recursive-jar destfile="${jar.file}"> + <fileset dir="${classes}"> + <include name="**/*.class" /> + <include name="${build.info.filename}" /> + </fileset> + <fileset dir="${sources}"> + <include name="**/*.xml" /> + <include name="**/*.png" /> + </fileset> + </recursive-jar> + </target> + + <!-- + // Makes a distribution file. + --> + <target name="dist" description="Makes a distribution file." depends="clean, jar"> + + <!--property name="dist.file.name" value="ch.systemsx.cisd.openbis.knime-${version}.v${version.number}-r${revision.number}.zip" /--> + <property name="dist.file.name" value="${dist}/ch.systemsx.cisd.openbis.knime-${version}.jar" /> + + <jar destfile="${dist.file.name}" manifest="${original.dist}/META-INF/MANIFEST.MF"> + <fileset dir="${dist}"> + <include name="${jar.file.name}"/> + </fileset> + <fileset dir="${original.dist}"> + <include name="**/*"/> + </fileset> + <zipfileset prefix="lib" file="${lib}/openbis-apis/query/openbis-query-api.jar"/> + <zipfileset prefix="lib" file="${lib}/cisd-base/cisd-base.jar"/> + <zipfileset prefix="lib" file="${lib}/commons-codec/commons-codec.jar"/> + <zipfileset prefix="lib" file="${lib}/commons-httpclient/commons-httpclient.jar"/> + <zipfileset prefix="lib" file="${lib}/commons-logging/commons-logging.jar"/> + <zipfileset prefix="lib" file="${lib}/log4j/log4j.jar"/> + <zipfileset prefix="lib" file="${lib}/spring/spring.jar"/> + <zipfileset prefix="lib" file="${lib}/spring/third-party/stream-supporting-httpinvoker.jar"/> + </jar> + <delete file="${jar.file}"/> + </target> + + <!-- + // Task for continuous integration server. + --> + <target name="ci" depends="build-common.ci, check-dependencies, dist" + description="Task for continuous integration server." /> + + <!-- + // Compiles the javascript using GWT compiler. + --> + <target name="compile-javascript" description="Compiles the javascript using GWT compiler."> + <property name="application.gwt.path" value="ch.systemsx.cisd.datamover.console.DatamoverConsole" /> + <echo></echo> + <delete dir="${webapp.dist}" /> + <java classpath="${ecp}:${gwt.dev.lib}:${gwt.user.lib}:${sources}" + classname="com.google.gwt.dev.GWTCompiler" + fork="true"> + <jvmarg value="-Xmx512M" /> + <arg value="-out" /> + <arg value="${webapp.dist}" /> + <arg value="${application.gwt.path}" /> + </java> + <move todir="${webapp.dist}"> + <fileset dir="${webapp.dist}/${application.gwt.path}" /> + </move> + </target> + + +</project> \ No newline at end of file diff --git a/openbis_knime/dist/META-INF/MANIFEST.MF b/openbis_knime/dist/META-INF/MANIFEST.MF new file mode 100755 index 00000000000..9fc60748ee5 --- /dev/null +++ b/openbis_knime/dist/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: openBIS nodes +Bundle-SymbolicName: ch.systemsx.cisd.openbis.knime; singleton:=true +Bundle-Version: 0.1.0 +Bundle-ClassPath: openbis-knime.jar,lib/cisd-base.jar,lib/commons-codec.jar, + lib/commons-httpclient.jar,lib/commons-logging.jar,lib/log4j.jar,lib/openbis-query-api.jar, + lib/spring.jar,lib/stream-supporting-httpinvoker.jar +Bundle-Vendor: CISD +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime,org.knime.workbench.core, + org.knime.workbench.repository,org.knime.base +Eclipse-RegisterBuddy: org.knime.base +Export-Package: ch.systemsx.cisd.openbis.knime +Bundle-ActivationPolicy: lazy diff --git a/openbis_knime/dist/icons/openbis.png b/openbis_knime/dist/icons/openbis.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b30672e374063ad0b36c4469a028e9e61090d7 GIT binary patch literal 707 zcmV;!0zCbRP)<h;3K|Lk000e1NJLTq000mG000mO0ssI2kdbIM00009a7bBm001r{ z001r{0eGc9b^rhX2XskIMF-ad7ZEZ6&JsRh0007FNkl<ZD9>$@TS$~q6ouD0=l{oX zpi*h3LWt6g6fDz7XUtM8C=3jui@roi`5+3Cj0J)gY7r=;1-?XK#N@*i5p)^vS!3l$ zT4a>?P}GY>R~vt4{&RK@<Be=Ruf5k^ADe|0H9UB(q^jBP)ENN`OJo8~zM*fyP<^3G zYwip*-XA7_F<w)UsV(tKpt&<pdoLh~teo-n_85y`Vep2BfeVj@OacG`&AVHAU)J1x zF+<G4S%M>0bhNc3td8@&nlOkDy#J&NxDw+9W3%p_k?PxnVF(+i%f)%evXVtzU0uqW zxOI+L-|Gp3_`vvQox_<JPYkWSBWLamhQMu{E*0e-cP4Xy5fK0dc!tMMT=z|ru)-WT zeb}an%!XT2B%+vXEy^o#r7(a2TI5y^6lWw!Qf2L3VN*_rO%760+60=8=9aip_#A`T zgoqR{@#SYQ6y9K8!5AB#{9)C#Bu5Ni1Wo$~q9K)GDoGF^Ln<&uL|_ZB7ZMb3)jwA0 z>5-=FbRV+mBB!x~I6r?dr#x@Vd<dWCeQj{8!qfMMG%iH6MYmcsp=s05+}@{G`bH%! z8c;y{v$qwVeuKD$sj~;N)8g%$9B~(q<V1570(X1;ZI4G~q=N!(4!tY)^amBwA<q>$ zEAzJs0AMGxQ;Ddu<B37M%IoKhm+njz8w-j`Z*&J0)1m4MomIQj#oP-rAY<*SmCK{L z-h7xL-aYowzAQ?c{553~voNYH*nVnHdSo{iRV>}HIV@GR*Dn>m{tjy8`57ToNu}I- pw+Z}594OnBMoN933RUmR`U_EO4a}K3EwTUr002ovPDHLkV1f|?F*pDK literal 0 HcmV?d00001 diff --git a/openbis_knime/dist/plugin.properties b/openbis_knime/dist/plugin.properties new file mode 100644 index 00000000000..93a2dde057f --- /dev/null +++ b/openbis_knime/dist/plugin.properties @@ -0,0 +1 @@ +% plugin properties for "openBIS" \ No newline at end of file diff --git a/openbis_knime/dist/plugin.xml b/openbis_knime/dist/plugin.xml new file mode 100644 index 00000000000..c2ef9769295 --- /dev/null +++ b/openbis_knime/dist/plugin.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?eclipse version="3.0"?> + +<plugin> + <extension point="org.knime.workbench.repository.nodes"> + <node category-path="/openbis" factory-class="ch.systemsx.cisd.openbis.knime.TestNodeFactory" + id="ch.systemsx.cisd.openbis.knime.node"/> + </extension> + + <extension point="org.knime.workbench.repository.categories"> + <category icon="icons/openbis.png" level-id="openbis" name="openBIS" path="/"/> + </extension> + +</plugin> \ No newline at end of file diff --git a/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeDialog.java b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeDialog.java new file mode 100644 index 00000000000..f06e6eeb620 --- /dev/null +++ b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeDialog.java @@ -0,0 +1,111 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.knime; + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; + +import org.apache.log4j.Logger; +import org.knime.core.node.InvalidSettingsException; +import org.knime.core.node.NodeDialogPane; +import org.knime.core.node.NodeSettingsRO; +import org.knime.core.node.NodeSettingsWO; +import org.knime.core.node.NotConfigurableException; +import org.knime.core.node.port.PortObjectSpec; + +import ch.systemsx.cisd.openbis.plugin.query.client.api.v1.QueryApiFacade; +import ch.systemsx.cisd.openbis.plugin.query.shared.api.v1.dto.QueryDescription; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class TestNodeDialog extends NodeDialogPane +{ + private JTextField urlField; + private JTextField userField; + private JPasswordField passwordField; + private JComboBox queryComboBox; + + TestNodeDialog() + { + super(); + addTab("openBIS Settings", createGUI()); + } + + private JPanel createGUI() + { + JPanel panel = new JPanel(new BorderLayout()); + JPanel form = new JPanel(new GridLayout(0, 2)); + form.add(new JLabel("openBIS URL:")); + urlField = new JTextField(); + form.add(urlField); + form.add(new JLabel("User:")); + userField = new JTextField(); + form.add(userField); + form.add(new JLabel("Password:")); + passwordField = new JPasswordField(); + form.add(passwordField); + form.add(new JLabel("Queries:")); + queryComboBox = new JComboBox(); + form.add(queryComboBox); + panel.add(form, BorderLayout.NORTH); + JButton button = new JButton("connect"); + button.addActionListener(new ActionListener() + { + + public void actionPerformed(ActionEvent e) + { + QueryApiFacade facade = QueryApiFacade.create(urlField.getText(), userField.getText(), passwordField.getText()); + List<QueryDescription> queries = facade.listQueries(); + for (QueryDescription queryDescription : queries) + { + queryComboBox.addItem(queryDescription.getName()); + } + // TODO Auto-generated method stub + + } + }); + panel.add(button, BorderLayout.SOUTH); + return panel; + } + + @Override + protected void loadSettingsFrom(NodeSettingsRO settings, PortObjectSpec[] specs) + throws NotConfigurableException + { + } + + @Override + protected void saveSettingsTo(NodeSettingsWO settings) throws InvalidSettingsException + { + // TODO Auto-generated method stub + + } + +} diff --git a/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.java b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.java new file mode 100644 index 00000000000..daa77002197 --- /dev/null +++ b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.knime; + +import org.knime.core.node.NodeDialogPane; +import org.knime.core.node.NodeFactory; +import org.knime.core.node.NodeView; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class TestNodeFactory extends NodeFactory<TestNodeModel> +{ + + @Override + protected NodeDialogPane createNodeDialogPane() + { + return new TestNodeDialog(); + } + + @Override + public TestNodeModel createNodeModel() + { + return new TestNodeModel(); + } + + @Override + public NodeView<TestNodeModel> createNodeView(int arg0, TestNodeModel arg1) + { + return null; + } + + @Override + protected int getNrNodeViews() + { + return 0; + } + + @Override + protected boolean hasDialog() + { + return true; + } + +} diff --git a/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.xml b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.xml new file mode 100644 index 00000000000..8128aed79d1 --- /dev/null +++ b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeFactory.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE knimeNode PUBLIC "-//UNIKN//DTD KNIME Node 2.0//EN" "http://www.knime.org/Node.dtd"> +<knimeNode icon="./openbis.png" type="Source"> + <name>openBIS Test</name> + + <shortDescription> + openBIS test node + </shortDescription> + + <fullDescription> + <intro>Just testing a very simple node. + </intro> + + + <option name="short name of first option (like in the dialog)">has no first option</option> + <option name="short name of second option (like in the dialog)">has no second option</option> + </fullDescription> + + <ports> + <inPort index="0" name="First In Port">Actual there are no in ports I guess</inPort> + <outPort index="0" name="First out Port">A simple table</outPort> + </ports> + <views> + <view index="0" name="name of first view">Description of first view...</view> + </views> +</knimeNode> diff --git a/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeModel.java b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeModel.java new file mode 100644 index 00000000000..ba1e739538a --- /dev/null +++ b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/TestNodeModel.java @@ -0,0 +1,113 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.knime; + +import java.io.File; +import java.io.IOException; + +import org.knime.core.data.DataTableSpec; +import org.knime.core.data.DataType; +import org.knime.core.data.def.DefaultRow; +import org.knime.core.data.def.StringCell; +import org.knime.core.node.BufferedDataContainer; +import org.knime.core.node.BufferedDataTable; +import org.knime.core.node.CanceledExecutionException; +import org.knime.core.node.ExecutionContext; +import org.knime.core.node.ExecutionMonitor; +import org.knime.core.node.InvalidSettingsException; +import org.knime.core.node.NodeModel; +import org.knime.core.node.NodeSettingsRO; +import org.knime.core.node.NodeSettingsWO; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class TestNodeModel extends NodeModel +{ + + protected TestNodeModel() + { + super(0, 1); + } + + @Override + protected void loadInternals(File arg0, ExecutionMonitor arg1) throws IOException, + CanceledExecutionException + { + // TODO Auto-generated method stub + + } + + @Override + protected void loadValidatedSettingsFrom(NodeSettingsRO arg0) throws InvalidSettingsException + { + // TODO Auto-generated method stub + + } + + @Override + protected void reset() + { + // TODO Auto-generated method stub + + } + + @Override + protected void saveInternals(File arg0, ExecutionMonitor arg1) throws IOException, + CanceledExecutionException + { + // TODO Auto-generated method stub + + } + + @Override + protected void saveSettingsTo(NodeSettingsWO arg0) + { + // TODO Auto-generated method stub + + } + + @Override + protected void validateSettings(NodeSettingsRO arg0) throws InvalidSettingsException + { + // TODO Auto-generated method stub + + } + + @Override + protected BufferedDataTable[] execute(BufferedDataTable[] inData, ExecutionContext exec) + throws Exception + { + BufferedDataContainer container = exec.createDataContainer(new DataTableSpec(new String[] {"col1", "col2"}, + new DataType[] {StringCell.TYPE, StringCell.TYPE})); + for (int i = 0; i < 5; i++) + { + container.addRowToTable(new DefaultRow("row-"+i, "a-"+i, "b-"+i)); + } + container.close(); + return new BufferedDataTable[] {container.getTable()}; + } + + @Override + protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) + throws InvalidSettingsException + { + return new DataTableSpec[0]; + } +} diff --git a/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/openbis.png b/openbis_knime/source/java/ch/systemsx/cisd/openbis/knime/openbis.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b30672e374063ad0b36c4469a028e9e61090d7 GIT binary patch literal 707 zcmV;!0zCbRP)<h;3K|Lk000e1NJLTq000mG000mO0ssI2kdbIM00009a7bBm001r{ z001r{0eGc9b^rhX2XskIMF-ad7ZEZ6&JsRh0007FNkl<ZD9>$@TS$~q6ouD0=l{oX zpi*h3LWt6g6fDz7XUtM8C=3jui@roi`5+3Cj0J)gY7r=;1-?XK#N@*i5p)^vS!3l$ zT4a>?P}GY>R~vt4{&RK@<Be=Ruf5k^ADe|0H9UB(q^jBP)ENN`OJo8~zM*fyP<^3G zYwip*-XA7_F<w)UsV(tKpt&<pdoLh~teo-n_85y`Vep2BfeVj@OacG`&AVHAU)J1x zF+<G4S%M>0bhNc3td8@&nlOkDy#J&NxDw+9W3%p_k?PxnVF(+i%f)%evXVtzU0uqW zxOI+L-|Gp3_`vvQox_<JPYkWSBWLamhQMu{E*0e-cP4Xy5fK0dc!tMMT=z|ru)-WT zeb}an%!XT2B%+vXEy^o#r7(a2TI5y^6lWw!Qf2L3VN*_rO%760+60=8=9aip_#A`T zgoqR{@#SYQ6y9K8!5AB#{9)C#Bu5Ni1Wo$~q9K)GDoGF^Ln<&uL|_ZB7ZMb3)jwA0 z>5-=FbRV+mBB!x~I6r?dr#x@Vd<dWCeQj{8!qfMMG%iH6MYmcsp=s05+}@{G`bH%! z8c;y{v$qwVeuKD$sj~;N)8g%$9B~(q<V1570(X1;ZI4G~q=N!(4!tY)^amBwA<q>$ zEAzJs0AMGxQ;Ddu<B37M%IoKhm+njz8w-j`Z*&J0)1m4MomIQj#oP-rAY<*SmCK{L z-h7xL-aYowzAQ?c{553~voNYH*nVnHdSo{iRV>}HIV@GR*Dn>m{tjy8`57ToNu}I- pw+Z}594OnBMoN933RUmR`U_EO4a}K3EwTUr002ovPDHLkV1f|?F*pDK literal 0 HcmV?d00001 -- GitLab