Commit 2edbe1bf authored by Riegel's avatar Riegel
Browse files

Build: Remove CityDoctorWebService module

parent 04387e46
package de.hft.stuttgart.citydoctor2.webservice.model.entities;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
@Entity
@Table(name = "geometries")
public class WebGeometry {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private int id;
@NotNull
private byte[] data;
@NotNull
private Lod lod;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public Lod getLod() {
return lod;
}
public void setLod(Lod lod) {
this.lod = lod;
}
}
package de.hft.stuttgart.citydoctor2.webservice.utils;
import java.time.LocalDateTime;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.HttpHeaders;
import de.hft.stuttgart.citydoctor2.webservice.AuthenticationException;
import de.hft.stuttgart.citydoctor2.webservice.database.TokenQueries;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.Token;
import de.hft.stuttgart.citydoctor2.webservice.model.entities.User;
public class AuthenticationUtils {
public static final String AUTHENTICATION_DENIED = "Authentication denied for address {}, reason: {}";
private AuthenticationUtils() {
// only static use
}
public static User authenticateUser(HttpServletRequest request, EntityManager manager) throws AuthenticationException {
final String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
if (authorization != null && authorization.toLowerCase().startsWith("bearer")) {
// Authorization: Bearer token
String token = authorization.substring("Bearer".length()).trim();
return validateToken(token, request.getRemoteAddr(), manager);
}
throw new AuthenticationException("No bearer token provided with request");
}
private static User validateToken(String token, String remoteAddr, EntityManager manager) throws AuthenticationException {
Token tokenForUser = TokenQueries.getTokenForTokenString(token, remoteAddr, manager);
if (tokenForUser == null) {
throw new AuthenticationException("No token for user");
}
if (!tokenForUser.getTokenString().equals(token)) {
throw new AuthenticationException("Token does not match");
}
LocalDateTime now = LocalDateTime.now();
if (tokenForUser.getExpires().isBefore(now)) {
throw new AuthenticationException("Token expired");
}
// update expiration date
TokenQueries.updateExpirationDate(now.plusHours(3), tokenForUser, manager);
return tokenForUser.getUser();
}
public static void removeTokenFromUser(HttpServletRequest request, EntityManager manager) throws AuthenticationException {
final String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
if (authorization != null && authorization.toLowerCase().startsWith("bearer")) {
String token = authorization.substring("Bearer".length()).trim();
Token tokenForUser = TokenQueries.getTokenForTokenString(token, request.getRemoteAddr(), manager);
if (tokenForUser == null) {
throw new AuthenticationException("No token for user");
}
manager.getTransaction().begin();
manager.remove(tokenForUser);
manager.getTransaction().commit();
return;
}
throw new AuthenticationException("No bearer token provided with request");
}
}
package de.hft.stuttgart.citydoctor2.webservice.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class HashUtils {
private HashUtils() {
// only static use
}
public static String createPasswordHash(String password, String salt) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(salt.getBytes());
digest.update(password.getBytes());
return Base64.getEncoder().encodeToString(digest.digest());
}
}
package de.hft.stuttgart.citydoctor2.webservice.utils;
public class HexUtils {
private HexUtils() {
// not used
}
public static String encode(byte[] bytes) {
return encodeHexString(bytes);
}
private static String encodeHexString(byte[] byteArray) {
StringBuilder hexStringBuffer = new StringBuilder();
for (int i = 0; i < byteArray.length; i++) {
byte num = byteArray[i];
hexStringBuffer.append(Character.forDigit((num >> 4) & 0xF, 16));
hexStringBuffer.append(Character.forDigit((num & 0xF), 16));
}
return hexStringBuffer.toString();
}
}
package de.hft.stuttgart.citydoctor2.webservice.utils;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class HibernateUtils {
private HibernateUtils() {
// only static use
}
private static EntityManagerFactory factory;
public static void init() {
if (factory == null) {
factory = Persistence.createEntityManagerFactory("CDPersistence");
}
}
public static EntityManager createManager() {
init();
return factory.createEntityManager();
}
public static void shutdown() {
if (factory != null) {
factory.close();
}
}
public static void closeManager(EntityManager manager) {
if (manager != null) {
manager.close();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="CDPersistence"
transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/CityDoctorDB?currentSchema=citydoctordb" />
<property name="javax.persistence.jdbc.user"
value="postgres" />
<property name="javax.persistence.jdbc.password"
value="admin" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQL10Dialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property
name="hibernate.connection.provider_disables_autocommit"
value="true" />
</properties>
</persistence-unit>
</persistence>
\ No newline at end of file
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/citydoctordb</property>
<property name="connection.username">postgres</property>
<property name="connection.password">admin</property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.PostgreSQL10Dialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create-drop</property>
<!-- dbcp connection pool configuration -->
<property name="hibernate.dbcp.initialSize">5</property>
<property name="hibernate.dbcp.maxTotal">20</property>
<property name="hibernate.dbcp.maxIdle">10</property>
<property name="hibernate.dbcp.minIdle">5</property>
<property name="hibernate.dbcp.maxWaitMillis">-1</property>
</session-factory>
</hibernate-configuration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configuration>
<Configuration status="INFO">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout
pattern="[%-5level] %d{HH:mm:ss.SSS} %c{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.hibernate" level="info" additivity="false">
<AppenderRef ref="console" />
</Logger>
<Root level="trace" additivity="false">
<AppenderRef ref="console" />
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>fileStorage</param-name>
<param-value>C:/WebService/files/</param-value>
</context-param>
</web-app>
var mat4 = glMatrix.mat4;
var vec3 = glMatrix.vec3;
var state = {
drag : {
dragging : false,
startX : -1,
startY : -1,
},
camera : {
dirty : true,
angleX : 90,
angleY : 0,
distance : 80,
viewMatrix : mat4.create(),
projectionMatrix : mat4.create(),
mvpPosition : null,
},
nrOfVertices: 3,
}
var vertexBuffer;
var gl;
var loop;
var mv;
var mvp;
var eyeVec;
var sx;
var cx;
var sy;
var cy;
var stop = false;
var resizeCanvas;
var vertexShaderText =
[
'precision mediump float;',
'',
'attribute vec3 vertPosition;',
'attribute vec3 vertColor;',
'attribute vec3 vertNormal;',
'',
'uniform mat4 mvp;',
'',
'varying vec3 fragColor;',
'',
'void main()',
'{',
'',
' float diff = dot(vertNormal, vec3(0.99602, 0.04193, 0.0786));',
' diff = diff * 0.3 + 0.7;',
' vec3 diffuse = diff * vertColor;',
' fragColor = diffuse;',
' gl_Position = mvp * vec4(vertPosition, 1.0);',
'}'
].join('\n');
var fragmentShaderText =
[
'precision mediump float;',
'',
'varying vec3 fragColor;',
'',
'void main()',
'{',
' gl_FragColor = vec4(fragColor, 1.0);',
'}'
].join('\n');
$(document).ready(function() {
var canvas = document.getElementById('testCanvas');
resizeCanvas = function () {
var width = canvas.clientWidth;
var height = canvas.clientHeight;
if (canvas.width != width || canvas.height != height) {
canvas.width = width;
canvas.height = height;
mat4.perspective(state.camera.projectionMatrix, glMatrix.glMatrix.toRadian(45),
canvas.width / canvas.height, 0.1, 1000.0);
state.camera.dirty = true;
}
}
window.addEventListener('resize', resizeCanvas);
setupMouseListeners(canvas);
gl = canvas.getContext('webgl');
if (!gl) {
console.log('WebGL not supported, switching to experimental web gl');
gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
alert('Browser does not support WebGL');
return;
}
gl.clearColor(0.75, 0.85, 0.8, 1.0);
gl.enable(gl.DEPTH_TEST)
var program = setupShaders(gl);
if (!program) {
return;
}
gl.useProgram(program);
eyeVec = vec3.create();
state.camera.mvpPosition = gl.getUniformLocation(program, 'mvp');
mat4.perspective(state.camera.projectionMatrix, glMatrix.glMatrix.toRadian(45),
canvas.width / canvas.height, 0.1, 1000.0);
resetCamera();
mv = mat4.create();
mvp = mat4.create();
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
var attribLoc = gl.getAttribLocation(program, 'vertPosition');
gl.vertexAttribPointer(attribLoc, 3, gl.FLOAT, false, 9 * Float32Array.BYTES_PER_ELEMENT, 0);
gl.enableVertexAttribArray(attribLoc);
var colorAttrib = gl.getAttribLocation(program, 'vertColor');
gl.vertexAttribPointer(colorAttrib, 3, gl.FLOAT, false, 9 * Float32Array.BYTES_PER_ELEMENT,
6 * Float32Array.BYTES_PER_ELEMENT);
gl.enableVertexAttribArray(colorAttrib);
var normalAttrib = gl.getAttribLocation(program, 'vertNormal');
gl.vertexAttribPointer(normalAttrib, 3, gl.FLOAT, false, 9 * Float32Array.BYTES_PER_ELEMENT,
3 * Float32Array.BYTES_PER_ELEMENT);
gl.enableVertexAttribArray(normalAttrib);
resizeCanvas();
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
loop = function () {
resizeCanvas();
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (state.camera.dirty) {
state.camera.dirty = false;
updateCamera();
}
gl.drawArrays(gl.TRIANGLES, 0, state.nrOfVertices);
if (!stop) {
requestAnimationFrame(loop);
} else {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}
}
});
function updateCamera() {
sx = Math.sin(glMatrix.glMatrix.toRadian(state.camera.angleX));
cx = Math.cos(glMatrix.glMatrix.toRadian(state.camera.angleX));
sy = Math.sin(glMatrix.glMatrix.toRadian(state.camera.angleY));
cy = Math.cos(glMatrix.glMatrix.toRadian(state.camera.angleY));
eyeVec[0] = state.camera.distance * sx * cy;
eyeVec[1] = state.camera.distance * sx * sy;
eyeVec[2] = state.camera.distance * cx;
mat4.lookAt(state.camera.viewMatrix, eyeVec, [0, 0, 0], [0, 0, 1]);
mat4.multiply(mvp, state.camera.projectionMatrix, state.camera.viewMatrix);
gl.uniformMatrix4fv(state.camera.mvpPosition, false, mvp);
}
function resetCamera() {
state.camera.angleX = 60;
state.camera.angleY = 330;
state.camera.dirty = true;
mat4.lookAt(state.camera.viewMatrix, [state.camera.distance, 0, 0], [0, 0, 0], [0, 0, 1]);
}
function drawModel(nrOfVertices, byteArray, width) {
stop = false;
state.camera.distance = Math.max(25, 1.5 * width);
state.camera.dirty = true;
state.nrOfVertices = nrOfVertices;
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, byteArray, gl.STATIC_DRAW);
requestAnimationFrame(loop);
}
function stopRender() {
stop = true;
}
function setupShaders(gl) {
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, vertexShaderText);
gl.shaderSource(fragmentShader, fragmentShaderText);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling vertex shader!', gl.getShaderInfoLog(vertexShader));
return 0;
}
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling fragment shader!', gl.getShaderInfoLog(fragmentShader));
return 0;
}
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('ERROR linking program!', gl.getProgramInfoLog(program));
return 0;
}
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) {
console.error('ERROR validating program!', gl.getProgramInfoLog(program));
return 0;
}
return program;
}
function zoom(event) {
event.preventDefault();
state.camera.distance += event.deltaY * 0.8;
state.camera.dirty = true;
}
function setupMouseListeners(canvas) {
canvas.onwheel = zoom;
canvas.onmousedown = function (e) {
// left mouse button
if (e.buttons == 1 && e.button == 0) {
state.drag.dragging = true;
state.drag.startX = e.x;
state.drag.startY = e.y;
}
}
canvas.onmousemove = function (e) {
if (state.drag.dragging && e.buttons == 1 && e.button == 0) {
var difX = (e.x - state.drag.startX) / 2.0;
var difY = (e.y - state.drag.startY) / 2.0;
state.drag.startX = e.x;
state.drag.startY = e.y;
state.camera.angleX -= difY;
state.camera.angleY -= difX;
if (state.camera.angleX < 1) {
state.camera.angleX = 1;
} else if (state.camera.angleX >= 179) {
state.camera.angleX = 179;
}
if (state.camera.angleY < 0) {
state.camera.angleY += 360;
} else if (state.camera.angleY >= 360) {
state.camera.angleY -= 360;
}
state.camera.dirty = true;
}
}
canvas.onmouseup = function (e) {
state.drag.dragging = false;
}
}
\ No newline at end of file
/*\
|*| ========================================================================
|*| Bootstrap Toggle: bootstrap4-toggle.css v3.5.0
|*| https://gitbrent.github.io/bootstrap-toggle/
|*| ========================================================================
|*| Copyright 2018-2019 Brent Ely
|*| Licensed under MIT
|*| ========================================================================
\*/
.btn-group-xs>.btn,.btn-xs{padding:.35rem .4rem .25rem;font-size:.875rem;line-height:.5;border-radius:.2rem}
.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-1.25rem;margin-right:.35rem}
.toggle{position:relative;overflow:hidden}
.toggle.btn.btn-light,.toggle.btn.btn-outline-light{border-color:rgba(0,0,0,.15)}
.toggle input[type=checkbox]{display:none}
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
.toggle-group label,.toggle-group span{cursor:pointer}
.toggle.off .toggle-group{left:-100%}
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0;box-shadow:none}
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px;background-color:#fff}
.toggle.btn-outline-primary .toggle-handle{background-color:var(--primary);border-color:var(--primary)}
.toggle.btn-outline-secondary .toggle-handle{background-color:var(--secondary);border-color:var(--secondary)}
.toggle.btn-outline-success .toggle-handle{background-color:var(--success);border-color:var(--success)}
.toggle.btn-outline-danger .toggle-handle{background-color:var(--danger);border-color:var(--danger)}
.toggle.btn-outline-warning .toggle-handle{background-color:var(--warning);border-color:var(--warning)}
.toggle.btn-outline-info .toggle-handle{background-color:var(--info);border-color:var(--info)}
.toggle.btn-outline-light .toggle-handle{background-color:var(--light);border-color:var(--light)}
.toggle.btn-outline-dark .toggle-handle{background-color:var(--dark);border-color:var(--dark)}
.toggle[class*=btn-outline]:hover .toggle-handle{background-color:var(--light);opacity:.5}
.toggle.btn{min-width:3.7rem;min-height:2.15rem}
.toggle-on.btn{padding-right:1.5rem}
.toggle-off.btn{padding-left:1.5rem}
.toggle.btn-lg{min-width:5rem;min-height:2.815rem}
.toggle-on.btn-lg{padding-right:2rem}
.toggle-off.btn-lg{padding-left:2rem}
.toggle-handle.btn-lg{width:2.5rem}
.toggle.btn-sm{min-width:3.125rem;min-height:1.938rem}
.toggle-on.btn-sm{padding-right:1rem}
.toggle-off.btn-sm{padding-left:1rem}
.toggle.btn-xs{min-width:2.19rem;min-height:1.375rem}
.toggle-on.btn-xs{padding-right:.8rem}
.toggle-off.btn-xs{padding-left:.8rem}
/*\
|*| ========================================================================
|*| Bootstrap Toggle: bootstrap4-toggle.js v3.5.0
|*| https://gitbrent.github.io/bootstrap-toggle/
|*| ========================================================================
|*| Copyright 2018-2019 Brent Ely
|*| Licensed under MIT
|*| ========================================================================
\*/
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="3.5.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"light",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size||"lg"===this.options.size?"btn-lg":"small"===this.options.size||"sm"===this.options.size?"btn-sm":"mini"===this.options.size||"xs"===this.options.size?"btn-xs":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b),e=a('<span class="toggle-handle btn btn-light">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle" role="button">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),a||this.trigger()},c.prototype.off=function(a){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),a||this.trigger()},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){a(this).find("input[type=checkbox]").bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
//# sourceMappingURL=bootstrap4-toggle.min.js.map
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment