www/views/devices/view_device.jsp

Code
Comments
Other
Rev Date Author Line
7407 05 Oct 17 nicklas 1 <%-- $Id7 $
7407 05 Oct 17 nicklas 2   ------------------------------------------------------------------
7407 05 Oct 17 nicklas 3   Copyright (C) 2017 Nicklas Nordborg
7407 05 Oct 17 nicklas 4
7407 05 Oct 17 nicklas 5   This file is part of BASE - BioArray Software Environment.
7407 05 Oct 17 nicklas 6   Available at http://base.thep.lu.se/
7407 05 Oct 17 nicklas 7
7407 05 Oct 17 nicklas 8   BASE is free software; you can redistribute it and/or
7407 05 Oct 17 nicklas 9   modify it under the terms of the GNU General Public License
7407 05 Oct 17 nicklas 10   as published by the Free Software Foundation; either version 3
7407 05 Oct 17 nicklas 11   of the License, or (at your option) any later version.
7407 05 Oct 17 nicklas 12
7407 05 Oct 17 nicklas 13   BASE is distributed in the hope that it will be useful,
7407 05 Oct 17 nicklas 14   but WITHOUT ANY WARRANTY; without even the implied warranty of
7407 05 Oct 17 nicklas 15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7407 05 Oct 17 nicklas 16   GNU General Public License for more details.
7407 05 Oct 17 nicklas 17
7407 05 Oct 17 nicklas 18   You should have received a copy of the GNU General Public License
7407 05 Oct 17 nicklas 19   along with BASE. If not, see <http://www.gnu.org/licenses/>.
7407 05 Oct 17 nicklas 20   ------------------------------------------------------------------
7407 05 Oct 17 nicklas 21
7407 05 Oct 17 nicklas 22   @author Nicklas
7407 05 Oct 17 nicklas 23 --%>
7407 05 Oct 17 nicklas 24 <%@ page pageEncoding="UTF-8" session="false"
7407 05 Oct 17 nicklas 25   import="net.sf.basedb.core.SessionControl"
7407 05 Oct 17 nicklas 26   import="net.sf.basedb.core.DbControl"
7407 05 Oct 17 nicklas 27   import="net.sf.basedb.core.Item"
7407 05 Oct 17 nicklas 28   import="net.sf.basedb.core.ItemContext"
7407 05 Oct 17 nicklas 29   import="net.sf.basedb.core.Permission"
7407 05 Oct 17 nicklas 30   import="net.sf.basedb.core.UserDevice"
7407 05 Oct 17 nicklas 31   import="net.sf.basedb.core.PermissionDeniedException"
7407 05 Oct 17 nicklas 32   import="net.sf.basedb.core.PluginDefinition"
7407 05 Oct 17 nicklas 33   import="net.sf.basedb.core.plugin.GuiContext"
7407 05 Oct 17 nicklas 34   import="net.sf.basedb.core.plugin.Plugin"
7407 05 Oct 17 nicklas 35   import="net.sf.basedb.core.Project"
7818 08 Jun 20 nicklas 36   import="net.sf.basedb.core.Session"
7818 08 Jun 20 nicklas 37   import="net.sf.basedb.core.ItemQuery"
7818 08 Jun 20 nicklas 38   import="net.sf.basedb.core.ItemResultList"
7818 08 Jun 20 nicklas 39   import="net.sf.basedb.core.query.Orders"
7818 08 Jun 20 nicklas 40   import="net.sf.basedb.core.query.Hql"
7414 12 Oct 17 nicklas 41   import="net.sf.basedb.util.GeoLocation"
7407 05 Oct 17 nicklas 42   import="net.sf.basedb.util.Values"
7411 10 Oct 17 nicklas 43   import="net.sf.basedb.util.HttpUtil"
7407 05 Oct 17 nicklas 44   import="net.sf.basedb.clients.web.Base"
7407 05 Oct 17 nicklas 45   import="net.sf.basedb.clients.web.PermissionUtil"
7407 05 Oct 17 nicklas 46   import="net.sf.basedb.clients.web.util.HTML"
7407 05 Oct 17 nicklas 47   import="net.sf.basedb.util.formatter.Formatter"
7407 05 Oct 17 nicklas 48   import="net.sf.basedb.clients.web.formatter.FormatterFactory"
7407 05 Oct 17 nicklas 49   import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
7407 05 Oct 17 nicklas 50   import="net.sf.basedb.clients.web.extensions.JspContext"
7407 05 Oct 17 nicklas 51   import="net.sf.basedb.clients.web.extensions.renderer.PrefixSuffixRenderer"
7604 25 Feb 19 nicklas 52   import="net.sf.basedb.clients.web.extensions.toolbar.ButtonAction" 
7407 05 Oct 17 nicklas 53   import="net.sf.basedb.clients.web.extensions.toolbar.ToolbarUtil"
7407 05 Oct 17 nicklas 54   import="net.sf.basedb.util.extensions.ExtensionsInvoker"
7407 05 Oct 17 nicklas 55   import="java.util.Date"
7407 05 Oct 17 nicklas 56   import="java.util.Collections"
7407 05 Oct 17 nicklas 57   import="java.util.List"
7407 05 Oct 17 nicklas 58   import="java.util.Map"
7407 05 Oct 17 nicklas 59   import="java.util.Set"
7407 05 Oct 17 nicklas 60 %>
7407 05 Oct 17 nicklas 61 <%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
7407 05 Oct 17 nicklas 62 <%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
7407 05 Oct 17 nicklas 63 <%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
7407 05 Oct 17 nicklas 64 <%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
7407 05 Oct 17 nicklas 65 <%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
7407 05 Oct 17 nicklas 66 <%!
7407 05 Oct 17 nicklas 67   private static final Item itemType = Item.USERDEVICE;
7407 05 Oct 17 nicklas 68   private static final GuiContext guiContext = new GuiContext(itemType, GuiContext.Type.ITEM);
7407 05 Oct 17 nicklas 69 %>
7407 05 Oct 17 nicklas 70 <%
7407 05 Oct 17 nicklas 71 final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
7407 05 Oct 17 nicklas 72 final String ID = sc.getId();
7407 05 Oct 17 nicklas 73 final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
7407 05 Oct 17 nicklas 74 final int itemId = cc.getId();
7407 05 Oct 17 nicklas 75 final String tab = Values.getString(request.getParameter("tab"), "properties");
7407 05 Oct 17 nicklas 76 final float scale = Base.getScale(sc);
7954 12 May 21 nicklas 77 final DbControl dc = sc.newDbControl(":View "+itemType);
7407 05 Oct 17 nicklas 78 try
7407 05 Oct 17 nicklas 79 {
7407 05 Oct 17 nicklas 80   Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
7407 05 Oct 17 nicklas 81   Formatter<Date> dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
7407 05 Oct 17 nicklas 82   Map<Plugin.MainType, Integer> pluginCount = PluginDefinition.countPlugins(dc, guiContext);
7407 05 Oct 17 nicklas 83
7407 05 Oct 17 nicklas 84   String title = null;
7407 05 Oct 17 nicklas 85   final UserDevice device = UserDevice.getById(dc, itemId);
7818 08 Jun 20 nicklas 86   String mapURL = GeoLocation.getURLToMap(device.getLocationLatitude(), device.getLocationLongitude());
7407 05 Oct 17 nicklas 87   final boolean writePermission = device.hasPermission(Permission.WRITE);
7407 05 Oct 17 nicklas 88   final boolean deletePermission = device.hasPermission(Permission.DELETE);
7407 05 Oct 17 nicklas 89   JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, guiContext, device);
7604 25 Feb 19 nicklas 90   ExtensionsInvoker<ButtonAction> invoker = ToolbarUtil.useExtensions(jspContext);
7407 05 Oct 17 nicklas 91   %>
7407 05 Oct 17 nicklas 92   <base:page title="<%=title%>" id="view-page">
7407 05 Oct 17 nicklas 93   <base:head scripts="table.js,tabcontrol-2.js,~devices.js" styles="table.css,toolbar.css,headertabcontrol.css,path.css">
7407 05 Oct 17 nicklas 94     <ext:scripts context="<%=jspContext%>" />
7407 05 Oct 17 nicklas 95     <ext:stylesheets context="<%=jspContext%>" />
7407 05 Oct 17 nicklas 96   </base:head>
7407 05 Oct 17 nicklas 97   <base:body>
7407 05 Oct 17 nicklas 98     <p:path><p:pathelement
7407 05 Oct 17 nicklas 99       title="Devices" href="<%="index.jsp?ID="+ID%>" 
7407 05 Oct 17 nicklas 100       /><p:pathelement title="<%=HTML.encodeTags(device.getName())%>"
7407 05 Oct 17 nicklas 101       /></p:path>
7407 05 Oct 17 nicklas 102     <div id="page-data" data-item-id="<%=itemId%>"></div>
7407 05 Oct 17 nicklas 103     
7407 05 Oct 17 nicklas 104     <t:tabcontrol 
7407 05 Oct 17 nicklas 105       id="main" 
7407 05 Oct 17 nicklas 106       subclass="content mastertabcontrol" 
7407 05 Oct 17 nicklas 107       active="<%=tab%>">
7407 05 Oct 17 nicklas 108     <t:tab id="properties" title="Properties">
7407 05 Oct 17 nicklas 109       <div>
7407 05 Oct 17 nicklas 110       <table class="fullform bottomborder">
7407 05 Oct 17 nicklas 111       <tr>
7407 05 Oct 17 nicklas 112         <th class="itemstatus">
7407 05 Oct 17 nicklas 113         </th>
7407 05 Oct 17 nicklas 114         <td style="padding: 0px;">
7407 05 Oct 17 nicklas 115           <tbl:toolbar subclass="bottomborder bg-filled-50">
7407 05 Oct 17 nicklas 116             <tbl:button 
7407 05 Oct 17 nicklas 117               id="btnEdit"
7407 05 Oct 17 nicklas 118               disabled="<%=!writePermission%>" 
7407 05 Oct 17 nicklas 119               image="edit.png" 
7407 05 Oct 17 nicklas 120               title="Edit&hellip;" 
7407 05 Oct 17 nicklas 121               tooltip="<%=writePermission ? "Edit this device" : "You do not have permission to edit this device"%>" 
7407 05 Oct 17 nicklas 122             />
7407 05 Oct 17 nicklas 123             <tbl:button 
7407 05 Oct 17 nicklas 124               id="btnDelete"
7407 05 Oct 17 nicklas 125               disabled="<%=!deletePermission%>" 
7407 05 Oct 17 nicklas 126               image="delete.png" 
7407 05 Oct 17 nicklas 127               title="Delete"
7407 05 Oct 17 nicklas 128               tooltip="<%=deletePermission ? "Delete this device" : "You do not have permission to delete this device"%>" 
7407 05 Oct 17 nicklas 129             />
7407 05 Oct 17 nicklas 130             <tbl:button 
7407 05 Oct 17 nicklas 131               id="btnExport"
7407 05 Oct 17 nicklas 132               image="export.png"
7407 05 Oct 17 nicklas 133               data-plugin-type="EXPORT" 
7407 05 Oct 17 nicklas 134               title="Export&hellip;" 
7407 05 Oct 17 nicklas 135               tooltip="Export data" 
7407 05 Oct 17 nicklas 136               visible="<%=pluginCount.containsKey(Plugin.MainType.EXPORT)%>"
7407 05 Oct 17 nicklas 137             />
7407 05 Oct 17 nicklas 138             <tbl:button 
7407 05 Oct 17 nicklas 139               id="btnRunPlugin"
7407 05 Oct 17 nicklas 140               image="runplugin.png"  
7407 05 Oct 17 nicklas 141               data-plugin-type="OTHER" 
7407 05 Oct 17 nicklas 142               title="Run plugin&hellip;" 
7407 05 Oct 17 nicklas 143               tooltip="Run a plugin" 
7407 05 Oct 17 nicklas 144               visible="<%=pluginCount.containsKey(Plugin.MainType.OTHER)%>"
7407 05 Oct 17 nicklas 145             />
7407 05 Oct 17 nicklas 146             <ext:render extensions="<%=invoker%>" context="<%=jspContext%>" 
7604 25 Feb 19 nicklas 147               wrapper="<%=new PrefixSuffixRenderer<ButtonAction>(jspContext, "<td>", "</td>") %>"/>
7407 05 Oct 17 nicklas 148             <tbl:button
7407 05 Oct 17 nicklas 149               image="help.png"
7407 05 Oct 17 nicklas 150               subclass="auto-init"
7407 05 Oct 17 nicklas 151               data-auto-init="help"
7407 05 Oct 17 nicklas 152               data-help-id="device.view.properties"
7407 05 Oct 17 nicklas 153               title="Help&hellip;"
7407 05 Oct 17 nicklas 154               tooltip="Get help about this page"
7407 05 Oct 17 nicklas 155             />
7407 05 Oct 17 nicklas 156           </tbl:toolbar>
7407 05 Oct 17 nicklas 157         </td>
7407 05 Oct 17 nicklas 158       </tr>
7407 05 Oct 17 nicklas 159       <tr>
7407 05 Oct 17 nicklas 160         <th>Name</th>
7407 05 Oct 17 nicklas 161         <td><%=HTML.encodeTags(device.getName())%></td>
7407 05 Oct 17 nicklas 162       </tr>
7407 05 Oct 17 nicklas 163       <tr>
7816 05 Jun 20 nicklas 164         <th>Verified</th>
7816 05 Jun 20 nicklas 165         <td><%=device.isVerified() ? "Yes" : "No"%></td>
7816 05 Jun 20 nicklas 166       </tr>
7816 05 Jun 20 nicklas 167       <tr>
7407 05 Oct 17 nicklas 168         <th>Registered</th>
7407 05 Oct 17 nicklas 169         <td><%=dateFormatter.format(device.getEntryDate())%></td>
7407 05 Oct 17 nicklas 170       </tr>
7407 05 Oct 17 nicklas 171       <tr>
7407 05 Oct 17 nicklas 172         <th>Last used</th>
7407 05 Oct 17 nicklas 173         <td><%=dateTimeFormatter.format(device.getLastUsed())%></td>
7407 05 Oct 17 nicklas 174       </tr>
7407 05 Oct 17 nicklas 175       <tr>
7411 10 Oct 17 nicklas 176         <th>Last remote ID</th>
7411 10 Oct 17 nicklas 177         <td><%=HTML.encodeTags(device.getLastRemoteId())%></td>
7411 10 Oct 17 nicklas 178       </tr>
7411 10 Oct 17 nicklas 179       <tr>
7414 12 Oct 17 nicklas 180         <th>Location</th>
7414 12 Oct 17 nicklas 181         <td><%=HTML.encodeTags(device.getLocation())%> 
7414 12 Oct 17 nicklas 182           <base:icon href="<%=mapURL%>" image="map.png" tooltip="Show map" visible="<%=mapURL != null %>" />
7414 12 Oct 17 nicklas 183         </td>
7414 12 Oct 17 nicklas 184       </tr>
7414 12 Oct 17 nicklas 185       <tr>
7407 05 Oct 17 nicklas 186         <th>User</th>
7407 05 Oct 17 nicklas 187         <td><base:propertyvalue item="<%=device%>" property="user" /></td>
7407 05 Oct 17 nicklas 188       </tr>
7407 05 Oct 17 nicklas 189       <tr>
7407 05 Oct 17 nicklas 190         <th>Client application</th>
7407 05 Oct 17 nicklas 191         <td><base:propertyvalue item="<%=device%>" property="client" /></td>
7407 05 Oct 17 nicklas 192       </tr>
7407 05 Oct 17 nicklas 193       <tr>
7407 05 Oct 17 nicklas 194         <th>User agent</th>
7411 10 Oct 17 nicklas 195         <td><%=HTML.encodeTags(HttpUtil.getSummaryOfUserAgent(device.getUserAgent()))%></td>
7407 05 Oct 17 nicklas 196       </tr>
7407 05 Oct 17 nicklas 197       <tr>
7411 10 Oct 17 nicklas 198         <th>User agent (raw)</th>
7411 10 Oct 17 nicklas 199         <td><%=HTML.encodeTags(device.getUserAgent())%></td>
7411 10 Oct 17 nicklas 200       </tr>
7411 10 Oct 17 nicklas 201       <tr>
7407 05 Oct 17 nicklas 202         <th>Permissions</th>
7407 05 Oct 17 nicklas 203         <td><%=PermissionUtil.getFullPermissionNames(device)%></td>
7407 05 Oct 17 nicklas 204       </tr>
7407 05 Oct 17 nicklas 205       <tr>
7407 05 Oct 17 nicklas 206         <th>Description</th>
7407 05 Oct 17 nicklas 207         <td><%=HTML.niceFormat(device.getDescription())%></td>
7407 05 Oct 17 nicklas 208       </tr>
7407 05 Oct 17 nicklas 209       </table>
7407 05 Oct 17 nicklas 210       </div>
7818 08 Jun 20 nicklas 211       
7818 08 Jun 20 nicklas 212       <%
7818 08 Jun 20 nicklas 213       ItemQuery<Session> sessionQuery = device.getSessions();
7818 08 Jun 20 nicklas 214       sessionQuery.order(Orders.desc(Hql.property("loginTime")));
7818 08 Jun 20 nicklas 215       sessionQuery.setMaxResults(10);
7818 08 Jun 20 nicklas 216       ItemResultList<Session> sessions = sessionQuery.list(dc);
7818 08 Jun 20 nicklas 217       %>
7818 08 Jun 20 nicklas 218       <base:section 
7818 08 Jun 20 nicklas 219         id="sessions"
7818 08 Jun 20 nicklas 220         title="<%="Recent sessions with this device (max 10)"%>"
7818 08 Jun 20 nicklas 221         context="<%=cc%>"
7818 08 Jun 20 nicklas 222         >
7818 08 Jun 20 nicklas 223         <%
7818 08 Jun 20 nicklas 224         if (sessions.size() == 0)
7818 08 Jun 20 nicklas 225         {
7818 08 Jun 20 nicklas 226           %>
7818 08 Jun 20 nicklas 227           <div class="messagecontainer note">
7818 08 Jun 20 nicklas 228           There are no registered sessions with this device.
7818 08 Jun 20 nicklas 229           </div>
7818 08 Jun 20 nicklas 230           <%
7818 08 Jun 20 nicklas 231         }
7818 08 Jun 20 nicklas 232         else
7818 08 Jun 20 nicklas 233         {
7818 08 Jun 20 nicklas 234           %>
7818 08 Jun 20 nicklas 235           <tbl:table
7818 08 Jun 20 nicklas 236             id="tbl.sessions"
7818 08 Jun 20 nicklas 237             columns="all"
7818 08 Jun 20 nicklas 238             >
7818 08 Jun 20 nicklas 239             <tbl:columndef 
7818 08 Jun 20 nicklas 240               id="loginTime"
7818 08 Jun 20 nicklas 241               title="Login time"
7818 08 Jun 20 nicklas 242             />
7818 08 Jun 20 nicklas 243             <tbl:columndef 
7818 08 Jun 20 nicklas 244               id="logoutTime"
7818 08 Jun 20 nicklas 245               title="Logout time"
7818 08 Jun 20 nicklas 246             />
7818 08 Jun 20 nicklas 247             <tbl:columndef 
7818 08 Jun 20 nicklas 248               id="authenticationMethod"
7818 08 Jun 20 nicklas 249               title="Authentication method" 
7818 08 Jun 20 nicklas 250             />
7818 08 Jun 20 nicklas 251             <tbl:columndef 
7818 08 Jun 20 nicklas 252               id="impersonated"
7818 08 Jun 20 nicklas 253               title="Impersonated" 
7818 08 Jun 20 nicklas 254             />
7818 08 Jun 20 nicklas 255             <tbl:columndef 
7818 08 Jun 20 nicklas 256               id="remoteId"
7818 08 Jun 20 nicklas 257               title="Remote ID"
7818 08 Jun 20 nicklas 258             />
7818 08 Jun 20 nicklas 259             <tbl:columndef 
7818 08 Jun 20 nicklas 260               id="location"
7818 08 Jun 20 nicklas 261               title="Location"
7818 08 Jun 20 nicklas 262             />
7818 08 Jun 20 nicklas 263             <tbl:columndef 
7818 08 Jun 20 nicklas 264               id="comment"
7818 08 Jun 20 nicklas 265               title="Comment" 
7818 08 Jun 20 nicklas 266             />
7818 08 Jun 20 nicklas 267             <tbl:data>
7818 08 Jun 20 nicklas 268               <tbl:headers>
7818 08 Jun 20 nicklas 269                 <tbl:headerrow>
7818 08 Jun 20 nicklas 270                   <tbl:columnheaders />
7818 08 Jun 20 nicklas 271                 </tbl:headerrow>
7818 08 Jun 20 nicklas 272               </tbl:headers>            
7818 08 Jun 20 nicklas 273               <tbl:rows>
7818 08 Jun 20 nicklas 274               <%
7818 08 Jun 20 nicklas 275               for (Session item : sessions)
7818 08 Jun 20 nicklas 276               {
7818 08 Jun 20 nicklas 277                 %>
7818 08 Jun 20 nicklas 278                 <tbl:row>
7952 12 May 21 nicklas 279                   <tbl:cell column="loginTime"><%=Base.getLink(ID, dateTimeFormatter.format(item.getLoginTime()), Item.SESSION, item.getId(), false)%></tbl:cell>
7818 08 Jun 20 nicklas 280                   <tbl:cell column="logoutTime"><%=dateTimeFormatter.format(item.getLogoutTime())%></tbl:cell>
7818 08 Jun 20 nicklas 281                   <tbl:cell column="authenticationMethod"><%=HTML.encodeTags(item.getAuthenticationMethod())%></tbl:cell>
7818 08 Jun 20 nicklas 282                   <tbl:cell column="impersonated"><%=item.getImpersonated()%></tbl:cell>
7818 08 Jun 20 nicklas 283                   <tbl:cell column="remoteId"><%=HTML.encodeTags(item.getRemoteId())%></tbl:cell>
7818 08 Jun 20 nicklas 284                   <tbl:cell column="location"><%=HTML.encodeTags(item.getLocation())%>
7818 08 Jun 20 nicklas 285                     <% mapURL = GeoLocation.getURLToMap(item.getLocationLatitude(), item.getLocationLongitude()); %>
7818 08 Jun 20 nicklas 286                     <base:icon href="<%=mapURL%>" image="map.png" tooltip="Show map" visible="<%=mapURL != null %>"/>                
7818 08 Jun 20 nicklas 287                   </tbl:cell>
7818 08 Jun 20 nicklas 288                   <tbl:cell column="comment"><%=HTML.encodeTags(item.getLoginComment())%></tbl:cell>
7818 08 Jun 20 nicklas 289                 </tbl:row>
7818 08 Jun 20 nicklas 290                 <%
7818 08 Jun 20 nicklas 291               }
7818 08 Jun 20 nicklas 292               %>
7818 08 Jun 20 nicklas 293               </tbl:rows>
7818 08 Jun 20 nicklas 294             </tbl:data>
7818 08 Jun 20 nicklas 295           </tbl:table>
7818 08 Jun 20 nicklas 296           <%
7818 08 Jun 20 nicklas 297         }
7818 08 Jun 20 nicklas 298         %>
7818 08 Jun 20 nicklas 299       </base:section>
7818 08 Jun 20 nicklas 300       
7818 08 Jun 20 nicklas 301       
7407 05 Oct 17 nicklas 302     </t:tab>
7407 05 Oct 17 nicklas 303     </t:tabcontrol>
7407 05 Oct 17 nicklas 304
7407 05 Oct 17 nicklas 305   </base:body>
7407 05 Oct 17 nicklas 306   </base:page>
7407 05 Oct 17 nicklas 307   <%
7407 05 Oct 17 nicklas 308 }
7407 05 Oct 17 nicklas 309 finally
7407 05 Oct 17 nicklas 310 {
7407 05 Oct 17 nicklas 311   if (dc != null) dc.close();
7407 05 Oct 17 nicklas 312 }
7407 05 Oct 17 nicklas 313
7407 05 Oct 17 nicklas 314 %>