浏览代码

security add

shjung 3 年之前
父节点
当前提交
9a3db442b1
共有 42 个文件被更改,包括 5340 次插入109 次删除
  1. 10 8
      pom.xml
  2. 1 0
      src/main/java/com/its/api/ItsOpServerApplication.java
  3. 34 0
      src/main/java/com/its/api/aop/ApiHandlerInterceptor.java
  4. 29 0
      src/main/java/com/its/api/config/AuditorAwareConfig.java
  5. 0 9
      src/main/java/com/its/api/config/RootContextConfig.java
  6. 1 2
      src/main/java/com/its/api/its/controller/cctv/TbCctvPsetController.java
  7. 4 0
      src/main/java/com/its/api/its/model/dto/LoginDto.java
  8. 2 2
      src/main/java/com/its/api/its/model/dto/vms/TbVmsSttsDto.java
  9. 29 8
      src/main/java/com/its/api/its/model/entity/AuditingEntity.java
  10. 0 30
      src/main/java/com/its/api/its/model/entity/database/BaseEntity.java
  11. 21 0
      src/main/java/com/its/api/its/model/entity/oper/TbUserInfr.java
  12. 25 0
      src/main/java/com/its/api/its/service/LoginService.java
  13. 3 2
      src/main/java/com/its/api/its/service/cctv/TbCctvPsetService.java
  14. 16 1
      src/main/java/com/its/api/webapp/config/WebMvcConfig.java
  15. 102 0
      src/main/java/com/its/api/webapp/config/WebSecurityConfig.java
  16. 0 23
      src/main/java/com/its/api/webapp/controller/FcltRedirectController.java
  17. 4 4
      src/main/java/com/its/api/webapp/controller/WebFacilityController.java
  18. 35 0
      src/main/java/com/its/api/webapp/controller/WebOpController.java
  19. 2 2
      src/main/java/com/its/api/webapp/controller/WebRedirectController.java
  20. 2 2
      src/main/java/com/its/api/webapp/controller/WebWallController.java
  21. 12 0
      src/main/java/com/its/api/webapp/domain/Login.java
  22. 144 0
      src/main/java/com/its/api/webapp/domain/UserInfrVo.java
  23. 32 0
      src/main/java/com/its/api/webapp/security/WebSessionListener.java
  24. 36 0
      src/main/java/com/its/api/webapp/service/WebLoginService.java
  25. 5 0
      src/main/resources/logback-spring.xml
  26. 1 0
      src/main/resources/logback.properties
  27. 11 11
      src/main/resources/mybatis/mapper/its/common/CommonMapper.xml
  28. 二进制
      src/main/resources/static/MainLogo.png
  29. 二进制
      src/main/resources/static/MainLogo1.png
  30. 1 1
      src/main/resources/static/application/facility/index.html
  31. 1 1
      src/main/resources/static/application/index.html
  32. 1 1
      src/main/resources/static/application/op/index.html
  33. 1 1
      src/main/resources/static/application/wall/index.html
  34. 2333 0
      src/main/resources/static/font-awesome.min.css
  35. 1 1
      src/main/resources/static/index.html
  36. 1007 0
      src/main/resources/static/js/utils/Parking copy.asn
  37. 457 0
      src/main/resources/static/js/utils/Parking-2016v2.asn
  38. 700 0
      src/main/resources/static/js/utils/Parking-2021v3.asn
  39. 180 0
      src/main/resources/static/login.css
  40. 37 0
      src/main/resources/static/login.html
  41. 60 0
      src/main/resources/static/login.js
  42. 二进制
      src/main/resources/static/loginPage.png

+ 10 - 8
pom.xml

@@ -55,12 +55,12 @@
             <artifactId>jansi</artifactId>
             <version>1.8</version>
         </dependency>
-        <dependency>
-            <groupId>com.jcabi</groupId>
-            <artifactId>jcabi-log</artifactId>
-            <version>LATEST</version>
-            <optional>true</optional>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.jcabi</groupId>-->
+<!--            <artifactId>jcabi-log</artifactId>-->
+<!--            <version>LATEST</version>-->
+<!--            <optional>true</optional>-->
+<!--        </dependency>-->
 
         <dependency>
             <groupId>com.oracle</groupId>
@@ -272,12 +272,14 @@
             <version>1.18.0</version>
         </dependency>
 
-        <!-- FOR WEB UI: START -->
-        <!--
+        <!-- WebSecurity: WebSecurityConfigurerAdapter -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
+
+        <!-- FOR WEB UI: START -->
+        <!--
         -->
         <!--
                 <dependency>

+ 1 - 0
src/main/java/com/its/api/ItsOpServerApplication.java

@@ -26,6 +26,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 
 @Slf4j
+//@EnableJpaAuditing    // JPA Auditing 활성화
 @EnableAspectJAutoProxy
 @EnableAsync
 @Configuration

+ 34 - 0
src/main/java/com/its/api/aop/ApiHandlerInterceptor.java

@@ -0,0 +1,34 @@
+package com.its.api.aop;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.lang.Nullable;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Slf4j
+public class ApiHandlerInterceptor implements HandlerInterceptor {
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        if (StringUtils.equalsIgnoreCase("GET", request.getMethod())) {
+            log.error("{}", request.getRequestURI());
+        }
+        log.error("preHandle: {}, {}, {}", request.getRequestURI(), request.getMethod(), handler);
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
+        log.error("postHandle: {}, {}, {}", request.getRequestURI(), response.toString(), handler);
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
+        log.error("afterCompletion: {}, {}, {}", request.getRequestURI(), response.toString(), handler);
+    }
+
+}

+ 29 - 0
src/main/java/com/its/api/config/AuditorAwareConfig.java

@@ -0,0 +1,29 @@
+package com.its.api.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+import java.util.Optional;
+
+@EnableJpaAuditing
+@Configuration
+public class AuditorAwareConfig {
+
+    // 로그인 사용자 정보 저장소 ......
+
+    @Bean
+    public AuditorAware<String> auditorAware() {
+        return (AuditorAware) () -> {
+            String userId = "ADMIN";
+            return Optional.of(userId);
+        };
+
+//        return Optional.ofNullable(SecurityContextHolder.getContext())
+//                .map(SecurityContext::getAuthentication)
+//                .filter(Authentication::isAuthenticated)
+//                .map(Authentication::getPrincipal)
+//                .map(User.class::cast);
+    }
+}

+ 0 - 9
src/main/java/com/its/api/config/RootContextConfig.java

@@ -3,9 +3,6 @@ package com.its.api.config;
 import org.modelmapper.ModelMapper;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.data.domain.AuditorAware;
-
-import java.util.Optional;
 
 @Configuration
 public class RootContextConfig {
@@ -15,10 +12,4 @@ public class RootContextConfig {
         return new ModelMapper();
     }
 
-    @Bean
-    public AuditorAware<String> auditorProvider() {
-        // 로그인한 사용자의 ID 를 가지고 와서 설정하도록 한다.
-        // AuditingEntity 에서 사용됨. @CreatedBy
-        return () -> Optional.of(new String("ADMIN").toString());
-    }
 }

+ 1 - 2
src/main/java/com/its/api/its/controller/cctv/TbCctvPsetController.java

@@ -1,7 +1,6 @@
 package com.its.api.its.controller.cctv;
 
 import com.its.api.its.model.dto.cctv.TbCctvPsetDto;
-import com.its.api.its.model.entity.cctv.TbCctvPsetKey;
 import com.its.api.its.service.cctv.TbCctvPsetService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -35,7 +34,7 @@ public class TbCctvPsetController {
 
     @ApiOperation(value = "CCTV 프리셋 정보변경(TB_CCTV_PSET)", response = TbCctvPsetDto.class)
     @PutMapping(value = "/{id}", produces = {"application/json; charset=utf8"})
-    public TbCctvPsetDto updateById(@PathVariable final TbCctvPsetKey id, @RequestBody @Valid final TbCctvPsetDto.TbCctvPsetUpdReq req) {
+    public TbCctvPsetDto updateById(@PathVariable final Long id, @RequestBody @Valid final TbCctvPsetDto.TbCctvPsetUpdReq req) {
         return this.service.updateById(id, req);
     }
 

+ 4 - 0
src/main/java/com/its/api/its/model/dto/LoginDto.java

@@ -1,5 +1,6 @@
 package com.its.api.its.model.dto;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.its.api.its.model.entity.oper.TbUserCnncHs;
 import com.its.api.its.model.entity.oper.TbUserInfr;
@@ -36,6 +37,9 @@ public class LoginDto implements Serializable {
     @JsonProperty("role")
     private String role;
 
+    @JsonIgnore
+    private String password;
+
     @ApiModel("LoginReqDto(로그인 요청)")
     @Getter
     @Setter

+ 2 - 2
src/main/java/com/its/api/its/model/dto/vms/TbVmsSttsDto.java

@@ -57,11 +57,11 @@ public class TbVmsSttsDto implements Serializable {
     @JsonProperty("brgh_val")
     private Integer brghVal;
 
-    @ApiModelProperty("모듈개별상태(가로->세로순서, 0:정상,1:오류)")  // Y VARCHAR(200)
+    @ApiModelProperty("모듈개별상태(가로->세로, 0:이상,1:정상,2:알수없음)")  // Y VARCHAR(200)
     @JsonProperty("modl_stts")
     private String modlStts;
 
-    @ApiModelProperty("모듈전원개별상태(가로->세로순서, 0:켜짐,1:꺼짐)")  // Y VARCHAR(10)
+    @ApiModelProperty("모듈전원개별상태(가로->세로, 0:꺼짐,1:켜짐,2:알수없음)")  // Y VARCHAR(100)
     @JsonProperty("pwer_stts")
     private String pwerStts;
 

+ 29 - 8
src/main/java/com/its/api/its/model/entity/database/AuditingEntity.java → src/main/java/com/its/api/its/model/entity/AuditingEntity.java

@@ -1,4 +1,4 @@
-package com.its.api.its.model.entity.database;
+package com.its.api.its.model.entity;
 
 import lombok.Getter;
 import org.springframework.data.annotation.CreatedBy;
@@ -12,33 +12,54 @@ import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 
 @Getter
-@MappedSuperclass
-@EntityListeners(AuditingEntityListener.class)
+@MappedSuperclass   // JPA Entity 클래스들이 AuditingEntity 를 상속할 경우 필드들(createdDate, lastModifiedDate)도 칼럼으로 인식하도록 함
+@EntityListeners(AuditingEntityListener.class)  // AuditingEntity 클래스에 Auditing 기능을 포함
 public class AuditingEntity {
 
     @CreatedDate
     @Column(updatable = false)
-    private LocalDateTime createdDate;
-
-    @LastModifiedDate
-    private LocalDateTime lastModifiedDate;
+    private LocalDateTime createdTime;
 
+    // AuditorAwareConfig
+    // @Bean
+    // public AuditorAware<String> auditorProvider()
     @CreatedBy
     @Column(updatable = false)
     private String createdBy;
 
+    @LastModifiedDate
+    private LocalDateTime modifiedTime;
+
     @LastModifiedBy
-    private String lastModifiedBy;
+    private String modifiedBy;
 
+    // 생성
     @PrePersist
     public void onPrePersist() {
         LocalDateTime now = LocalDateTime.now();
         String createDt = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        this.createdTime = now;
+        this.modifiedTime = now;
     }
 
+    // 업데이트
     @PreUpdate
     public void onPreUpdate() {
         LocalDateTime now = LocalDateTime.now();
         String updateDt = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        this.modifiedTime = now;
     }
 }
+
+//// JPA Auditing 클래스 상속
+//public class MyEntiry extends AuditingEntity {
+//}
+//
+//@EnableJpaAuditing    // JPA Auditing 활성화
+//@SpringBootApplication
+//public class Application {
+//    public static void main(String[] args) {
+//        SpringApplication.run(Application.class, args);
+//    }
+//}
+//

+ 0 - 30
src/main/java/com/its/api/its/model/entity/database/BaseEntity.java

@@ -1,30 +0,0 @@
-package com.its.api.its.model.entity.database;
-
-import lombok.Getter;
-
-import javax.persistence.Column;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.PrePersist;
-import javax.persistence.PreUpdate;
-import java.time.LocalDateTime;
-
-@Getter
-@MappedSuperclass
-public class BaseEntity {
-
-    @Column(updatable = false)
-    private LocalDateTime createTime;
-    private LocalDateTime updateTime;
-
-    @PrePersist
-    public void beforeInsert() {
-        LocalDateTime now = LocalDateTime.now();
-        this.createTime = now;
-        this.updateTime = now;
-    }
-
-    @PreUpdate
-    public void beforeUpdate() {
-        this.updateTime = LocalDateTime.now();
-    }
-}

+ 21 - 0
src/main/java/com/its/api/its/model/entity/oper/TbUserInfr.java

@@ -1,6 +1,7 @@
 package com.its.api.its.model.entity.oper;
 
 import com.its.api.its.model.dto.oper.TbUserInfrDto;
+import com.its.api.webapp.domain.UserInfrVo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.*;
@@ -105,6 +106,26 @@ public class TbUserInfr implements Serializable {
                 .build();
     }
 
+    public UserInfrVo toVo() {
+        return UserInfrVo.builder()
+                .userId(this.userId)
+                .pwd(this.pwd)
+                .name(this.name)
+                .comp(this.comp)
+                .tel(this.tel)
+                .addr(this.addr)
+                .mobile(this.mobile)
+                .emal(this.emal)
+                .delYn(this.delYn)
+                .rgstymd(this.rgstymd)
+                .crctymd(this.crctymd)
+                .hintQues(this.hintQues)
+                .hintAns(this.hintAns)
+                .gropId(this.gropId)
+                .operSystId(this.operSystId)
+                .build();
+    }
+
     public TbUserInfr(String userId) {
         this.userId = userId;
     }

+ 25 - 0
src/main/java/com/its/api/its/service/LoginService.java

@@ -57,4 +57,29 @@ public class LoginService {
         TbUserCnncHs cnncHs = req.toCnnsHsEntity();
         this.cnncHsRepo.save(cnncHs);
     }
+
+    /**
+     * 사용자 ID 로 조회
+     * @param userId
+     * @return
+     */
+    public LoginDto findById(String userId) {
+
+        LoginDto result = LoginDto.builder()
+                .userId(userId)
+                .loginHms(ItsUtils.getSysTime())
+                .build();
+
+        Optional<TbUserInfr> userInfr = this.userRepo.findById(userId);
+        if (userInfr.isPresent()) {
+            result.setPassword(userInfr.get().getPwd());
+            result.setLoginResult("success");
+        }
+        else {
+            result.setLoginResult("fail");
+        }
+
+        return result;
+    }
+
 }

+ 3 - 2
src/main/java/com/its/api/its/service/cctv/TbCctvPsetService.java

@@ -96,8 +96,9 @@ public class TbCctvPsetService {
 
     // 데이터 변경
     @Transactional
-    public TbCctvPsetDto updateById(TbCctvPsetKey id, TbCctvPsetDto.TbCctvPsetUpdReq req) {
-        TbCctvPset entity = requireOne(id);
+    public TbCctvPsetDto updateById(Long id, TbCctvPsetDto.TbCctvPsetUpdReq req) {
+        TbCctvPsetKey key = new TbCctvPsetKey(id, req.getPsetNmbr());
+        TbCctvPset entity = requireOne(key);
         entity.updateInfo(req);
         this.repo.save(entity);
         return entity.toDto();

+ 16 - 1
src/main/java/com/its/api/webapp/config/WebConfig.java → src/main/java/com/its/api/webapp/config/WebMvcConfig.java

@@ -1,12 +1,22 @@
 package com.its.api.webapp.config;
 
+import com.its.api.aop.ApiHandlerInterceptor;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 @Configuration
-public class WebConfig implements WebMvcConfigurer {
+public class WebMvcConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(new ApiHandlerInterceptor())
+                .addPathPatterns("/api/**")      // 해당 경로에 접근하기 전에 인터셉터가 가로챈다.
+                .excludePathPatterns("/boards") // 해당 경로는 인터셉터가 가로채지 않는다.
+                ;
+    }
 
     @Override
     public void addCorsMappings(CorsRegistry registry) {
@@ -20,6 +30,11 @@ public class WebConfig implements WebMvcConfigurer {
     }
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
+//        registry.addResourceHandler("swagger-ui.html")
+//                .addResourceLocations("classpath:/META-INF/resources/");
+//        registry.addResourceHandler("/webjars/**")
+//                .addResourceLocations("classpath:/META-INF/resources/webjars/");
+
         String separator = System.getProperty("file.separator");
         String mapDataDir = System.getProperty("user.dir")+separator+"MAPDATA/";
         registry.addResourceHandler("/MAPDATA/**")

+ 102 - 0
src/main/java/com/its/api/webapp/config/WebSecurityConfig.java

@@ -0,0 +1,102 @@
+package com.its.api.webapp.config;
+
+import com.its.api.webapp.security.WebSessionListener;
+import com.its.api.webapp.service.WebLoginService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.session.SessionRegistry;
+import org.springframework.security.core.session.SessionRegistryImpl;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import javax.servlet.http.HttpSessionListener;
+
+@Configuration
+@EnableWebSecurity
+@RequiredArgsConstructor
+//@EnableGlobalMethodSecurity(securedEnabled = true)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    private final WebLoginService loginService;
+
+    @Override
+    public void configure(WebSecurity web) {
+        // static 디렉터리의 하위 파일 목록은 인증 무시 ( = 항상통과 )
+        web.ignoring().antMatchers("/js/**", "/images/**", "/libs/**", "/css/**");
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable();  // REST API 호출 유효하게.....
+        http.authorizeRequests()
+                // 페이지 권한 설정
+                .antMatchers("/index.html").permitAll()
+                .antMatchers("/application/facility/**").permitAll()
+                .antMatchers("/application/wall/**").permitAll()
+                .antMatchers("/swagger-ui.html", "/swagger/**", "/swagger-resources/**", "/webjars/**", "/v2/api-docs", "/login.do").permitAll()
+                .antMatchers("/login.do").permitAll()
+                .antMatchers("/**").permitAll()
+//                .and()
+//                .formLogin()
+//                .loginPage("login.html")
+//                .permitAll()
+//                .antMatchers("/index").hasRole("ADMIN")
+//                .antMatchers("/**").hasRole("ADMIN")
+//                .and() // 로그인 설정
+//                .formLogin()
+//                .loginPage("/login")
+//                .defaultSuccessUrl("/index")
+//                .permitAll()
+//                .and() // 로그아웃 설정
+//                .logout()
+//                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
+//                .logoutSuccessUrl("/login")
+//                .invalidateHttpSession(true)
+//                .deleteCookies("JSESSIONID")
+//                .and()
+//                // 403 예외처리 핸들링
+//                .exceptionHandling().accessDeniedPage("/login");
+        ;
+
+
+
+//        http.sessionManagement()
+//                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
+//                .invalidSessionUrl("/login")
+//                .sessionFixation()
+//                .migrateSession()
+//                .maximumSessions(5)
+//                .maxSessionsPreventsLogin(true)
+//                .expiredUrl("/login")
+//                .sessionRegistry(sessionRegistry())
+//        ;
+    }
+
+    @Override
+    public void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.userDetailsService(loginService);
+        //auth.userDetailsService(loginService).passwordEncoder(passwordEncoder());
+    }
+
+    @Bean
+    public PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+    @Bean
+    public SessionRegistry sessionRegistry() {
+        return new SessionRegistryImpl();
+    }
+
+    @Bean
+    public HttpSessionListener httpSessionListener(){
+        return new WebSessionListener();
+    }
+
+}

+ 0 - 23
src/main/java/com/its/api/webapp/controller/FcltRedirectController.java

@@ -1,23 +0,0 @@
-package com.its.api.webapp.controller;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.servlet.ModelAndView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-@Slf4j
-@Controller
-@RequestMapping("/fclt")
-public class FcltRedirectController {
-
-    private final String baseContext = "forward:/application/fclt";
-
-    @RequestMapping("/index.do")
-    public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
-        return new ModelAndView(this.baseContext + "/index.html");
-    }
-
-}

+ 4 - 4
src/main/java/com/its/api/webapp/controller/ItsRedirectController.java → src/main/java/com/its/api/webapp/controller/WebFacilityController.java

@@ -10,12 +10,12 @@ import javax.servlet.http.HttpServletResponse;
 
 @Slf4j
 @Controller
-@RequestMapping("/op")
-public class ItsRedirectController {
+@RequestMapping("/facility")
+public class WebFacilityController {
 
-    private final String baseContext = "forward:/application/op";
+    private final String baseContext = "forward:/application/facility";
 
-    @RequestMapping("/index.do")
+    @RequestMapping({"", "/", "/index.do"})
     public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
         return new ModelAndView(this.baseContext + "/index.html");
     }

+ 35 - 0
src/main/java/com/its/api/webapp/controller/WebOpController.java

@@ -0,0 +1,35 @@
+package com.its.api.webapp.controller;
+
+import com.its.api.its.model.dto.LoginDto;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Slf4j
+@Controller
+@RequestMapping("/op")
+public class WebOpController {
+
+    private final String baseContext = "forward:/application/op";
+
+    @RequestMapping({"", "/", "/index.do"})
+    public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
+        return new ModelAndView(this.baseContext + "/index.html");
+    }
+
+    @PostMapping("/login.do")
+    public String greetingSubmit(@ModelAttribute LoginDto.LoginReqDto login, Model model) {
+        log.error("{}", login.toString());
+        log.error("{}", model.toString());
+        model.addAttribute("greeting", login);
+        return "/op/login.do";
+    }
+
+}

+ 2 - 2
src/main/java/com/its/api/webapp/controller/WebRedirectController.java

@@ -10,12 +10,12 @@ import javax.servlet.http.HttpServletResponse;
 
 @Slf4j
 @Controller
-@RequestMapping("/")
+@RequestMapping("")
 public class WebRedirectController {
 
     private final String baseContext = "forward:/application";
 
-    @RequestMapping("/index.do")
+    @RequestMapping({"", "/", "/index.do"})
     public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
         return new ModelAndView(this.baseContext + "/index.html");
     }

+ 2 - 2
src/main/java/com/its/api/webapp/controller/WallRedirectController.java → src/main/java/com/its/api/webapp/controller/WebWallController.java

@@ -11,11 +11,11 @@ import javax.servlet.http.HttpServletResponse;
 @Slf4j
 @Controller
 @RequestMapping("/wall")
-public class WallRedirectController {
+public class WebWallController {
 
     private final String baseContext = "forward:/application/wall";
 
-    @RequestMapping("/index.do")
+    @RequestMapping({"", "/", "/index.do"})
     public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
         return new ModelAndView(this.baseContext + "/index.html");
     }

+ 12 - 0
src/main/java/com/its/api/webapp/domain/Login.java

@@ -0,0 +1,12 @@
+package com.its.api.webapp.domain;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class Login {
+
+    private String userId;
+    private String password;
+}

+ 144 - 0
src/main/java/com/its/api/webapp/domain/UserInfrVo.java

@@ -0,0 +1,144 @@
+package com.its.api.webapp.domain;
+
+import com.its.api.its.model.dto.oper.TbUserInfrDto;
+import com.its.api.its.model.entity.oper.TbUserInfr;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * 사용자정보 Entity Class
+ */
+@Data
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Builder
+@AllArgsConstructor
+public class UserInfrVo implements UserDetails {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("사용자ID")  // N VARCHAR(20)
+    private String userId;
+    @ApiModelProperty("암호")  // Y VARCHAR(64)
+    private String pwd;
+    @ApiModelProperty("성명")  // Y VARCHAR(30)
+    private String name;
+    @ApiModelProperty("회사")  // Y VARCHAR(50)
+    private String comp;
+    @ApiModelProperty("전화번호")  // Y VARCHAR(128)
+    private String tel;
+    @ApiModelProperty("주소")  // Y VARCHAR(200)
+    private String addr;
+    @ApiModelProperty("이동전화")  // Y VARCHAR(128)
+    private String mobile;
+    @ApiModelProperty("이메일")  // Y VARCHAR(128)
+    private String emal;
+    @ApiModelProperty("삭제 여부")  // Y CHAR(1)
+    private String delYn;
+
+    @ApiModelProperty("등록일자")  // Y VARCHAR(14)
+    private String rgstymd;
+    @ApiModelProperty("수정일자")  // Y VARCHAR(14)
+    private String crctymd;
+
+    @ApiModelProperty("힌트질문")  // Y VARCHAR(7)
+    private String hintQues;
+    @ApiModelProperty("힌트질문답")  // Y VARCHAR(100)
+    private String hintAns;
+
+    @ApiModelProperty("그룹ID")  // Y VARCHAR(30)
+    private String gropId;
+    @ApiModelProperty("운영시스템ID")  // Y VARCHAR(30)
+    private String operSystId;
+
+    public TbUserInfrDto toDto() {
+        return TbUserInfrDto.builder()
+                .userId(this.userId)
+                .pwd(this.pwd)
+                .name(this.name)
+                .comp(this.comp)
+                .tel(this.tel)
+                .addr(this.addr)
+                .mobile(this.mobile)
+                .emal(this.emal)
+                .delYn(this.delYn)
+                .rgstymd(this.rgstymd)
+                .crctymd(this.crctymd)
+                .hintQues(this.hintQues)
+                .hintAns(this.hintAns)
+                .gropId(this.gropId)
+                .operSystId(this.operSystId)
+                .build();
+    }
+    public TbUserInfr toEntity() {
+        return TbUserInfr.builder()
+                .userId(this.userId)
+                .pwd(this.pwd)
+                .name(this.name)
+                .comp(this.comp)
+                .tel(this.tel)
+                .addr(this.addr)
+                .mobile(this.mobile)
+                .emal(this.emal)
+                .delYn(this.delYn)
+                .rgstymd(this.rgstymd)
+                .crctymd(this.crctymd)
+                .hintQues(this.hintQues)
+                .hintAns(this.hintAns)
+                .gropId(this.gropId)
+                .operSystId(this.operSystId)
+                .build();
+    }
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        Set<GrantedAuthority> roles = new HashSet<GrantedAuthority>();
+        if (StringUtils.equalsIgnoreCase("GROPMANAGER", this.gropId)) {
+            roles.add(new SimpleGrantedAuthority("ADMIN"));
+        }
+        else if (StringUtils.equalsIgnoreCase("GROPSYSOP", this.gropId)) {
+            roles.add(new SimpleGrantedAuthority("ADMIN"));
+        }
+        else {
+            roles.add(new SimpleGrantedAuthority("ADMIN"));
+        }
+        return roles;
+    }
+
+    @Override
+    public String getPassword() {
+//        BCryptPasswordEncoder be = new BCryptPasswordEncoder();
+//        return be.encode(this.pwd);
+        return pwd;
+    }
+
+    @Override
+    public String getUsername() {
+        return this.userId;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return StringUtils.equalsIgnoreCase("N", this.delYn);
+    }
+}

+ 32 - 0
src/main/java/com/its/api/webapp/security/WebSessionListener.java

@@ -0,0 +1,32 @@
+package com.its.api.webapp.security;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.web.session.HttpSessionEventPublisher;
+
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
+
+@Slf4j
+public class WebSessionListener extends HttpSessionEventPublisher {
+    //세션이 생성될때 호출
+    @Override
+    public void sessionCreated(HttpSessionEvent se) {
+        HttpSession session = se.getSession();
+
+        if (session != null) {
+            session.setMaxInactiveInterval(60*5);
+            log.info("sessionCreated session.id: {}, setMaxInactiveInterval: {}, isNew: {} time:{}", session.getId(), session.getMaxInactiveInterval(), session.isNew(),session.getAttribute("time"));
+        }
+        super.sessionCreated(se);
+    }
+
+    //세션이 만료될때 호출
+    @Override
+    public  void sessionDestroyed(HttpSessionEvent se) {
+        HttpSession session = se.getSession();
+        if (session != null) {
+            log.info("sessionDestroyed session.id: {}, setMaxInactiveInterval: {}, isNew: {}", session.getId(), session.getMaxInactiveInterval(), session.isNew());
+        }
+        super.sessionDestroyed(se);
+    }
+}

+ 36 - 0
src/main/java/com/its/api/webapp/service/WebLoginService.java

@@ -0,0 +1,36 @@
+package com.its.api.webapp.service;
+
+import com.its.api.its.model.dto.LoginDto;
+import com.its.api.its.model.entity.oper.TbUserInfr;
+import com.its.api.its.repository.oper.TbUserCnncHsRepository;
+import com.its.api.its.repository.oper.TbUserInfrRepository;
+import com.its.utils.ItsUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+public class WebLoginService implements UserDetailsService {
+
+    private final TbUserInfrRepository userRepo;
+    private final TbUserCnncHsRepository cnncHsRepo;
+
+    @Override
+    public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
+        LoginDto result = LoginDto.builder()
+                .userId(userId)
+                .loginHms(ItsUtils.getSysTime())
+                .build();
+
+        Optional<TbUserInfr> optUserInfr = this.userRepo.findById(userId);
+        if (optUserInfr.isPresent()) {
+            return optUserInfr.get().toVo();
+        }
+        throw new UsernameNotFoundException(userId);
+    }
+}

+ 5 - 0
src/main/resources/logback-spring.xml

@@ -4,9 +4,14 @@
 
     <property resource="logback.properties"/>
 
+<!--    <springProfile name="dev">-->
+<!--        <property name="LOGS_PATH" value="./logs" />-->
+<!--    </springProfile>-->
+
     <property name="PROJECT_NAME"    value="${log.name}"/>
     <property name="ROOT_LOG_LEVEL"  value="${log.level.root}"/>
     <property name="LOG_CHARSET"     value="${log.charset}" />
+    <property name="LOG_ENCODING"    value="${log.encoding}" />
     <property name="LOG_PATH"        value="${log.path}"/>
     <property name="LOG_BACKUP_PATH" value="${log.backup.path}"/>
 

+ 1 - 0
src/main/resources/logback.properties

@@ -1,5 +1,6 @@
 log.name = its-op-server
 log.charset = UTF-8
+log.encoding = UTF-8
 log.level.root = INFO
 #log.path = c:/YONGIN/logs/
 #log.backup.path = c:/YONGIN/logs/backup/

+ 11 - 11
src/main/resources/mybatis/mapper/its/common/CommonMapper.xml

@@ -7,14 +7,14 @@
 <![CDATA[
         SELECT * FROM
             (SELECT
-                 AA.IFSC_ID,
-                 AA.SPED,
-                 AA.CMTR_GRAD_CD,
-                 AA.STRT_NM,
-                 AA.END_NM,
-                 AA.CMMN_CD_KOR_NM,
-                 ROUND(AA.SECT_LNGT, 2) AS SECT_LNGT,
-                 BB.ATRD_NM
+                 A.IFSC_ID,
+                 A.SPED,
+                 A.CMTR_GRAD_CD,
+                 A.STRT_NM,
+                 A.END_NM,
+                 A.CMMN_CD_KOR_NM,
+                 A.SECT_LNGT AS SECT_LNGT,
+                 B.ATRD_NM
              FROM
                  (
                      SELECT
@@ -33,7 +33,7 @@
                        AND C.CMMN_CLSF_CD = 'LTC'
                        AND A.CMTR_GRAD_CD = C.CMMN_CD
                        AND (A.CMTR_GRAD_CD = 'LTC2' OR A.CMTR_GRAD_CD = 'LTC3')
-                 ) AA LEFT OUTER JOIN
+                 ) A LEFT OUTER JOIN
                  (
                      SELECT
                          A.IFSC_ID,
@@ -47,8 +47,8 @@
                          A.IFSC_ID = B.IFSC_ID
                        AND B.ROAD_ID = C.ROAD_ID
                        AND C.ATRD_ID = D.ATRD_ID
-                 ) BB
-                 ON AA.IFSC_ID = BB.IFSC_ID
+                 ) B
+                 ON A.IFSC_ID = B.IFSC_ID
             )
         WHERE ATRD_NM IS NOT NULL
         ]]>

二进制
src/main/resources/static/MainLogo.png


二进制
src/main/resources/static/MainLogo1.png


+ 1 - 1
src/main/resources/static/application/facility/index.html

@@ -4,7 +4,7 @@
         <meta charset="UTF-8" />
         <meta http-equiv="X-UA-Compatible" content="IE=edge" />
         <meta name="viewport" content="width=<device-width>, initial-scale=1.0" />
-        <meta http-equiv="refresh" content="0; url=./main/main.html" />
+        <meta http-equiv="refresh" content="0; url=/application/facility/main/main.html" />
         <title>시설물 모니터링</title>
 
     </head>

+ 1 - 1
src/main/resources/static/application/index.html

@@ -5,7 +5,7 @@
     <title>Title</title>
 </head>
 <body>
-<h1>Main Index-call login</h1>
+<h1>static/application/index.html</h1>
 
 </body>
 </html>

+ 1 - 1
src/main/resources/static/application/op/index.html

@@ -5,6 +5,6 @@
     <title>Title</title>
 </head>
 <body>
-<h1>Operator Terminal</h1>
+<h1>static/application/op/index.html</h1>
 </body>
 </html>

+ 1 - 1
src/main/resources/static/application/wall/index.html

@@ -4,7 +4,7 @@
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta http-equiv="refresh" content="0; url=./main/main.html" />
+    <meta http-equiv="refresh" content="0; url=/application/wall/main/main.html" />
     <title>상황판</title>
 </head>
 <body>

+ 2333 - 0
src/main/resources/static/font-awesome.min.css

@@ -0,0 +1,2333 @@
+/*!
+ *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
+ *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */
+@font-face {
+    font-family: "FontAwesome";
+    src: url("../fonts/fontawesome-webfont.eot?v=4.7.0");
+    src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0") format("embedded-opentype"), url("../fonts/fontawesome-webfont.woff2?v=4.7.0") format("woff2"),
+        url("../fonts/fontawesome-webfont.woff?v=4.7.0") format("woff"), url("../fonts/fontawesome-webfont.ttf?v=4.7.0") format("truetype"),
+        url("../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular") format("svg");
+    font-weight: normal;
+    font-style: normal;
+}
+.fa {
+    display: inline-block;
+    font: normal normal normal 14px/1 FontAwesome;
+    font-size: inherit;
+    text-rendering: auto;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+}
+.fa-lg {
+    font-size: 1.33333333em;
+    line-height: 0.75em;
+    vertical-align: -15%;
+}
+.fa-2x {
+    font-size: 2em;
+}
+.fa-3x {
+    font-size: 3em;
+}
+.fa-4x {
+    font-size: 4em;
+}
+.fa-5x {
+    font-size: 5em;
+}
+.fa-fw {
+    width: 1.28571429em;
+    text-align: center;
+}
+.fa-ul {
+    padding-left: 0;
+    margin-left: 2.14285714em;
+    list-style-type: none;
+}
+.fa-ul > li {
+    position: relative;
+}
+.fa-li {
+    position: absolute;
+    left: -2.14285714em;
+    width: 2.14285714em;
+    top: 0.14285714em;
+    text-align: center;
+}
+.fa-li.fa-lg {
+    left: -1.85714286em;
+}
+.fa-border {
+    padding: 0.2em 0.25em 0.15em;
+    border: solid 0.08em #eee;
+    border-radius: 0.1em;
+}
+.fa-pull-left {
+    float: left;
+}
+.fa-pull-right {
+    float: right;
+}
+.fa.fa-pull-left {
+    margin-right: 0.3em;
+}
+.fa.fa-pull-right {
+    margin-left: 0.3em;
+}
+.pull-right {
+    float: right;
+}
+.pull-left {
+    float: left;
+}
+.fa.pull-left {
+    margin-right: 0.3em;
+}
+.fa.pull-right {
+    margin-left: 0.3em;
+}
+.fa-spin {
+    -webkit-animation: fa-spin 2s infinite linear;
+    animation: fa-spin 2s infinite linear;
+}
+.fa-pulse {
+    -webkit-animation: fa-spin 1s infinite steps(8);
+    animation: fa-spin 1s infinite steps(8);
+}
+@-webkit-keyframes fa-spin {
+    0% {
+        -webkit-transform: rotate(0deg);
+        transform: rotate(0deg);
+    }
+    100% {
+        -webkit-transform: rotate(359deg);
+        transform: rotate(359deg);
+    }
+}
+@keyframes fa-spin {
+    0% {
+        -webkit-transform: rotate(0deg);
+        transform: rotate(0deg);
+    }
+    100% {
+        -webkit-transform: rotate(359deg);
+        transform: rotate(359deg);
+    }
+}
+.fa-rotate-90 {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
+    -webkit-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    transform: rotate(90deg);
+}
+.fa-rotate-180 {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
+    -webkit-transform: rotate(180deg);
+    -ms-transform: rotate(180deg);
+    transform: rotate(180deg);
+}
+.fa-rotate-270 {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
+    -webkit-transform: rotate(270deg);
+    -ms-transform: rotate(270deg);
+    transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
+    -webkit-transform: scale(-1, 1);
+    -ms-transform: scale(-1, 1);
+    transform: scale(-1, 1);
+}
+.fa-flip-vertical {
+    -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
+    -webkit-transform: scale(1, -1);
+    -ms-transform: scale(1, -1);
+    transform: scale(1, -1);
+}
+:root .fa-rotate-90,
+:root .fa-rotate-180,
+:root .fa-rotate-270,
+:root .fa-flip-horizontal,
+:root .fa-flip-vertical {
+    filter: none;
+}
+.fa-stack {
+    position: relative;
+    display: inline-block;
+    width: 2em;
+    height: 2em;
+    line-height: 2em;
+    vertical-align: middle;
+}
+.fa-stack-1x,
+.fa-stack-2x {
+    position: absolute;
+    left: 0;
+    width: 100%;
+    text-align: center;
+}
+.fa-stack-1x {
+    line-height: inherit;
+}
+.fa-stack-2x {
+    font-size: 2em;
+}
+.fa-inverse {
+    color: #fff;
+}
+.fa-glass:before {
+    content: "\f000";
+}
+.fa-music:before {
+    content: "\f001";
+}
+.fa-search:before {
+    content: "\f002";
+}
+.fa-envelope-o:before {
+    content: "\f003";
+}
+.fa-heart:before {
+    content: "\f004";
+}
+.fa-star:before {
+    content: "\f005";
+}
+.fa-star-o:before {
+    content: "\f006";
+}
+.fa-user:before {
+    content: "\f007";
+}
+.fa-film:before {
+    content: "\f008";
+}
+.fa-th-large:before {
+    content: "\f009";
+}
+.fa-th:before {
+    content: "\f00a";
+}
+.fa-th-list:before {
+    content: "\f00b";
+}
+.fa-check:before {
+    content: "\f00c";
+}
+.fa-remove:before,
+.fa-close:before,
+.fa-times:before {
+    content: "\f00d";
+}
+.fa-search-plus:before {
+    content: "\f00e";
+}
+.fa-search-minus:before {
+    content: "\f010";
+}
+.fa-power-off:before {
+    content: "\f011";
+}
+.fa-signal:before {
+    content: "\f012";
+}
+.fa-gear:before,
+.fa-cog:before {
+    content: "\f013";
+}
+.fa-trash-o:before {
+    content: "\f014";
+}
+.fa-home:before {
+    content: "\f015";
+}
+.fa-file-o:before {
+    content: "\f016";
+}
+.fa-clock-o:before {
+    content: "\f017";
+}
+.fa-road:before {
+    content: "\f018";
+}
+.fa-download:before {
+    content: "\f019";
+}
+.fa-arrow-circle-o-down:before {
+    content: "\f01a";
+}
+.fa-arrow-circle-o-up:before {
+    content: "\f01b";
+}
+.fa-inbox:before {
+    content: "\f01c";
+}
+.fa-play-circle-o:before {
+    content: "\f01d";
+}
+.fa-rotate-right:before,
+.fa-repeat:before {
+    content: "\f01e";
+}
+.fa-refresh:before {
+    content: "\f021";
+}
+.fa-list-alt:before {
+    content: "\f022";
+}
+.fa-lock:before {
+    content: "\f023";
+}
+.fa-flag:before {
+    content: "\f024";
+}
+.fa-headphones:before {
+    content: "\f025";
+}
+.fa-volume-off:before {
+    content: "\f026";
+}
+.fa-volume-down:before {
+    content: "\f027";
+}
+.fa-volume-up:before {
+    content: "\f028";
+}
+.fa-qrcode:before {
+    content: "\f029";
+}
+.fa-barcode:before {
+    content: "\f02a";
+}
+.fa-tag:before {
+    content: "\f02b";
+}
+.fa-tags:before {
+    content: "\f02c";
+}
+.fa-book:before {
+    content: "\f02d";
+}
+.fa-bookmark:before {
+    content: "\f02e";
+}
+.fa-print:before {
+    content: "\f02f";
+}
+.fa-camera:before {
+    content: "\f030";
+}
+.fa-font:before {
+    content: "\f031";
+}
+.fa-bold:before {
+    content: "\f032";
+}
+.fa-italic:before {
+    content: "\f033";
+}
+.fa-text-height:before {
+    content: "\f034";
+}
+.fa-text-width:before {
+    content: "\f035";
+}
+.fa-align-left:before {
+    content: "\f036";
+}
+.fa-align-center:before {
+    content: "\f037";
+}
+.fa-align-right:before {
+    content: "\f038";
+}
+.fa-align-justify:before {
+    content: "\f039";
+}
+.fa-list:before {
+    content: "\f03a";
+}
+.fa-dedent:before,
+.fa-outdent:before {
+    content: "\f03b";
+}
+.fa-indent:before {
+    content: "\f03c";
+}
+.fa-video-camera:before {
+    content: "\f03d";
+}
+.fa-photo:before,
+.fa-image:before,
+.fa-picture-o:before {
+    content: "\f03e";
+}
+.fa-pencil:before {
+    content: "\f040";
+}
+.fa-map-marker:before {
+    content: "\f041";
+}
+.fa-adjust:before {
+    content: "\f042";
+}
+.fa-tint:before {
+    content: "\f043";
+}
+.fa-edit:before,
+.fa-pencil-square-o:before {
+    content: "\f044";
+}
+.fa-share-square-o:before {
+    content: "\f045";
+}
+.fa-check-square-o:before {
+    content: "\f046";
+}
+.fa-arrows:before {
+    content: "\f047";
+}
+.fa-step-backward:before {
+    content: "\f048";
+}
+.fa-fast-backward:before {
+    content: "\f049";
+}
+.fa-backward:before {
+    content: "\f04a";
+}
+.fa-play:before {
+    content: "\f04b";
+}
+.fa-pause:before {
+    content: "\f04c";
+}
+.fa-stop:before {
+    content: "\f04d";
+}
+.fa-forward:before {
+    content: "\f04e";
+}
+.fa-fast-forward:before {
+    content: "\f050";
+}
+.fa-step-forward:before {
+    content: "\f051";
+}
+.fa-eject:before {
+    content: "\f052";
+}
+.fa-chevron-left:before {
+    content: "\f053";
+}
+.fa-chevron-right:before {
+    content: "\f054";
+}
+.fa-plus-circle:before {
+    content: "\f055";
+}
+.fa-minus-circle:before {
+    content: "\f056";
+}
+.fa-times-circle:before {
+    content: "\f057";
+}
+.fa-check-circle:before {
+    content: "\f058";
+}
+.fa-question-circle:before {
+    content: "\f059";
+}
+.fa-info-circle:before {
+    content: "\f05a";
+}
+.fa-crosshairs:before {
+    content: "\f05b";
+}
+.fa-times-circle-o:before {
+    content: "\f05c";
+}
+.fa-check-circle-o:before {
+    content: "\f05d";
+}
+.fa-ban:before {
+    content: "\f05e";
+}
+.fa-arrow-left:before {
+    content: "\f060";
+}
+.fa-arrow-right:before {
+    content: "\f061";
+}
+.fa-arrow-up:before {
+    content: "\f062";
+}
+.fa-arrow-down:before {
+    content: "\f063";
+}
+.fa-mail-forward:before,
+.fa-share:before {
+    content: "\f064";
+}
+.fa-expand:before {
+    content: "\f065";
+}
+.fa-compress:before {
+    content: "\f066";
+}
+.fa-plus:before {
+    content: "\f067";
+}
+.fa-minus:before {
+    content: "\f068";
+}
+.fa-asterisk:before {
+    content: "\f069";
+}
+.fa-exclamation-circle:before {
+    content: "\f06a";
+}
+.fa-gift:before {
+    content: "\f06b";
+}
+.fa-leaf:before {
+    content: "\f06c";
+}
+.fa-fire:before {
+    content: "\f06d";
+}
+.fa-eye:before {
+    content: "\f06e";
+}
+.fa-eye-slash:before {
+    content: "\f070";
+}
+.fa-warning:before,
+.fa-exclamation-triangle:before {
+    content: "\f071";
+}
+.fa-plane:before {
+    content: "\f072";
+}
+.fa-calendar:before {
+    content: "\f073";
+}
+.fa-random:before {
+    content: "\f074";
+}
+.fa-comment:before {
+    content: "\f075";
+}
+.fa-magnet:before {
+    content: "\f076";
+}
+.fa-chevron-up:before {
+    content: "\f077";
+}
+.fa-chevron-down:before {
+    content: "\f078";
+}
+.fa-retweet:before {
+    content: "\f079";
+}
+.fa-shopping-cart:before {
+    content: "\f07a";
+}
+.fa-folder:before {
+    content: "\f07b";
+}
+.fa-folder-open:before {
+    content: "\f07c";
+}
+.fa-arrows-v:before {
+    content: "\f07d";
+}
+.fa-arrows-h:before {
+    content: "\f07e";
+}
+.fa-bar-chart-o:before,
+.fa-bar-chart:before {
+    content: "\f080";
+}
+.fa-twitter-square:before {
+    content: "\f081";
+}
+.fa-facebook-square:before {
+    content: "\f082";
+}
+.fa-camera-retro:before {
+    content: "\f083";
+}
+.fa-key:before {
+    content: "\f084";
+}
+.fa-gears:before,
+.fa-cogs:before {
+    content: "\f085";
+}
+.fa-comments:before {
+    content: "\f086";
+}
+.fa-thumbs-o-up:before {
+    content: "\f087";
+}
+.fa-thumbs-o-down:before {
+    content: "\f088";
+}
+.fa-star-half:before {
+    content: "\f089";
+}
+.fa-heart-o:before {
+    content: "\f08a";
+}
+.fa-sign-out:before {
+    content: "\f08b";
+}
+.fa-linkedin-square:before {
+    content: "\f08c";
+}
+.fa-thumb-tack:before {
+    content: "\f08d";
+}
+.fa-external-link:before {
+    content: "\f08e";
+}
+.fa-sign-in:before {
+    content: "\f090";
+}
+.fa-trophy:before {
+    content: "\f091";
+}
+.fa-github-square:before {
+    content: "\f092";
+}
+.fa-upload:before {
+    content: "\f093";
+}
+.fa-lemon-o:before {
+    content: "\f094";
+}
+.fa-phone:before {
+    content: "\f095";
+}
+.fa-square-o:before {
+    content: "\f096";
+}
+.fa-bookmark-o:before {
+    content: "\f097";
+}
+.fa-phone-square:before {
+    content: "\f098";
+}
+.fa-twitter:before {
+    content: "\f099";
+}
+.fa-facebook-f:before,
+.fa-facebook:before {
+    content: "\f09a";
+}
+.fa-github:before {
+    content: "\f09b";
+}
+.fa-unlock:before {
+    content: "\f09c";
+}
+.fa-credit-card:before {
+    content: "\f09d";
+}
+.fa-feed:before,
+.fa-rss:before {
+    content: "\f09e";
+}
+.fa-hdd-o:before {
+    content: "\f0a0";
+}
+.fa-bullhorn:before {
+    content: "\f0a1";
+}
+.fa-bell:before {
+    content: "\f0f3";
+}
+.fa-certificate:before {
+    content: "\f0a3";
+}
+.fa-hand-o-right:before {
+    content: "\f0a4";
+}
+.fa-hand-o-left:before {
+    content: "\f0a5";
+}
+.fa-hand-o-up:before {
+    content: "\f0a6";
+}
+.fa-hand-o-down:before {
+    content: "\f0a7";
+}
+.fa-arrow-circle-left:before {
+    content: "\f0a8";
+}
+.fa-arrow-circle-right:before {
+    content: "\f0a9";
+}
+.fa-arrow-circle-up:before {
+    content: "\f0aa";
+}
+.fa-arrow-circle-down:before {
+    content: "\f0ab";
+}
+.fa-globe:before {
+    content: "\f0ac";
+}
+.fa-wrench:before {
+    content: "\f0ad";
+}
+.fa-tasks:before {
+    content: "\f0ae";
+}
+.fa-filter:before {
+    content: "\f0b0";
+}
+.fa-briefcase:before {
+    content: "\f0b1";
+}
+.fa-arrows-alt:before {
+    content: "\f0b2";
+}
+.fa-group:before,
+.fa-users:before {
+    content: "\f0c0";
+}
+.fa-chain:before,
+.fa-link:before {
+    content: "\f0c1";
+}
+.fa-cloud:before {
+    content: "\f0c2";
+}
+.fa-flask:before {
+    content: "\f0c3";
+}
+.fa-cut:before,
+.fa-scissors:before {
+    content: "\f0c4";
+}
+.fa-copy:before,
+.fa-files-o:before {
+    content: "\f0c5";
+}
+.fa-paperclip:before {
+    content: "\f0c6";
+}
+.fa-save:before,
+.fa-floppy-o:before {
+    content: "\f0c7";
+}
+.fa-square:before {
+    content: "\f0c8";
+}
+.fa-navicon:before,
+.fa-reorder:before,
+.fa-bars:before {
+    content: "\f0c9";
+}
+.fa-list-ul:before {
+    content: "\f0ca";
+}
+.fa-list-ol:before {
+    content: "\f0cb";
+}
+.fa-strikethrough:before {
+    content: "\f0cc";
+}
+.fa-underline:before {
+    content: "\f0cd";
+}
+.fa-table:before {
+    content: "\f0ce";
+}
+.fa-magic:before {
+    content: "\f0d0";
+}
+.fa-truck:before {
+    content: "\f0d1";
+}
+.fa-pinterest:before {
+    content: "\f0d2";
+}
+.fa-pinterest-square:before {
+    content: "\f0d3";
+}
+.fa-google-plus-square:before {
+    content: "\f0d4";
+}
+.fa-google-plus:before {
+    content: "\f0d5";
+}
+.fa-money:before {
+    content: "\f0d6";
+}
+.fa-caret-down:before {
+    content: "\f0d7";
+}
+.fa-caret-up:before {
+    content: "\f0d8";
+}
+.fa-caret-left:before {
+    content: "\f0d9";
+}
+.fa-caret-right:before {
+    content: "\f0da";
+}
+.fa-columns:before {
+    content: "\f0db";
+}
+.fa-unsorted:before,
+.fa-sort:before {
+    content: "\f0dc";
+}
+.fa-sort-down:before,
+.fa-sort-desc:before {
+    content: "\f0dd";
+}
+.fa-sort-up:before,
+.fa-sort-asc:before {
+    content: "\f0de";
+}
+.fa-envelope:before {
+    content: "\f0e0";
+}
+.fa-linkedin:before {
+    content: "\f0e1";
+}
+.fa-rotate-left:before,
+.fa-undo:before {
+    content: "\f0e2";
+}
+.fa-legal:before,
+.fa-gavel:before {
+    content: "\f0e3";
+}
+.fa-dashboard:before,
+.fa-tachometer:before {
+    content: "\f0e4";
+}
+.fa-comment-o:before {
+    content: "\f0e5";
+}
+.fa-comments-o:before {
+    content: "\f0e6";
+}
+.fa-flash:before,
+.fa-bolt:before {
+    content: "\f0e7";
+}
+.fa-sitemap:before {
+    content: "\f0e8";
+}
+.fa-umbrella:before {
+    content: "\f0e9";
+}
+.fa-paste:before,
+.fa-clipboard:before {
+    content: "\f0ea";
+}
+.fa-lightbulb-o:before {
+    content: "\f0eb";
+}
+.fa-exchange:before {
+    content: "\f0ec";
+}
+.fa-cloud-download:before {
+    content: "\f0ed";
+}
+.fa-cloud-upload:before {
+    content: "\f0ee";
+}
+.fa-user-md:before {
+    content: "\f0f0";
+}
+.fa-stethoscope:before {
+    content: "\f0f1";
+}
+.fa-suitcase:before {
+    content: "\f0f2";
+}
+.fa-bell-o:before {
+    content: "\f0a2";
+}
+.fa-coffee:before {
+    content: "\f0f4";
+}
+.fa-cutlery:before {
+    content: "\f0f5";
+}
+.fa-file-text-o:before {
+    content: "\f0f6";
+}
+.fa-building-o:before {
+    content: "\f0f7";
+}
+.fa-hospital-o:before {
+    content: "\f0f8";
+}
+.fa-ambulance:before {
+    content: "\f0f9";
+}
+.fa-medkit:before {
+    content: "\f0fa";
+}
+.fa-fighter-jet:before {
+    content: "\f0fb";
+}
+.fa-beer:before {
+    content: "\f0fc";
+}
+.fa-h-square:before {
+    content: "\f0fd";
+}
+.fa-plus-square:before {
+    content: "\f0fe";
+}
+.fa-angle-double-left:before {
+    content: "\f100";
+}
+.fa-angle-double-right:before {
+    content: "\f101";
+}
+.fa-angle-double-up:before {
+    content: "\f102";
+}
+.fa-angle-double-down:before {
+    content: "\f103";
+}
+.fa-angle-left:before {
+    content: "\f104";
+}
+.fa-angle-right:before {
+    content: "\f105";
+}
+.fa-angle-up:before {
+    content: "\f106";
+}
+.fa-angle-down:before {
+    content: "\f107";
+}
+.fa-desktop:before {
+    content: "\f108";
+}
+.fa-laptop:before {
+    content: "\f109";
+}
+.fa-tablet:before {
+    content: "\f10a";
+}
+.fa-mobile-phone:before,
+.fa-mobile:before {
+    content: "\f10b";
+}
+.fa-circle-o:before {
+    content: "\f10c";
+}
+.fa-quote-left:before {
+    content: "\f10d";
+}
+.fa-quote-right:before {
+    content: "\f10e";
+}
+.fa-spinner:before {
+    content: "\f110";
+}
+.fa-circle:before {
+    content: "\f111";
+}
+.fa-mail-reply:before,
+.fa-reply:before {
+    content: "\f112";
+}
+.fa-github-alt:before {
+    content: "\f113";
+}
+.fa-folder-o:before {
+    content: "\f114";
+}
+.fa-folder-open-o:before {
+    content: "\f115";
+}
+.fa-smile-o:before {
+    content: "\f118";
+}
+.fa-frown-o:before {
+    content: "\f119";
+}
+.fa-meh-o:before {
+    content: "\f11a";
+}
+.fa-gamepad:before {
+    content: "\f11b";
+}
+.fa-keyboard-o:before {
+    content: "\f11c";
+}
+.fa-flag-o:before {
+    content: "\f11d";
+}
+.fa-flag-checkered:before {
+    content: "\f11e";
+}
+.fa-terminal:before {
+    content: "\f120";
+}
+.fa-code:before {
+    content: "\f121";
+}
+.fa-mail-reply-all:before,
+.fa-reply-all:before {
+    content: "\f122";
+}
+.fa-star-half-empty:before,
+.fa-star-half-full:before,
+.fa-star-half-o:before {
+    content: "\f123";
+}
+.fa-location-arrow:before {
+    content: "\f124";
+}
+.fa-crop:before {
+    content: "\f125";
+}
+.fa-code-fork:before {
+    content: "\f126";
+}
+.fa-unlink:before,
+.fa-chain-broken:before {
+    content: "\f127";
+}
+.fa-question:before {
+    content: "\f128";
+}
+.fa-info:before {
+    content: "\f129";
+}
+.fa-exclamation:before {
+    content: "\f12a";
+}
+.fa-superscript:before {
+    content: "\f12b";
+}
+.fa-subscript:before {
+    content: "\f12c";
+}
+.fa-eraser:before {
+    content: "\f12d";
+}
+.fa-puzzle-piece:before {
+    content: "\f12e";
+}
+.fa-microphone:before {
+    content: "\f130";
+}
+.fa-microphone-slash:before {
+    content: "\f131";
+}
+.fa-shield:before {
+    content: "\f132";
+}
+.fa-calendar-o:before {
+    content: "\f133";
+}
+.fa-fire-extinguisher:before {
+    content: "\f134";
+}
+.fa-rocket:before {
+    content: "\f135";
+}
+.fa-maxcdn:before {
+    content: "\f136";
+}
+.fa-chevron-circle-left:before {
+    content: "\f137";
+}
+.fa-chevron-circle-right:before {
+    content: "\f138";
+}
+.fa-chevron-circle-up:before {
+    content: "\f139";
+}
+.fa-chevron-circle-down:before {
+    content: "\f13a";
+}
+.fa-html5:before {
+    content: "\f13b";
+}
+.fa-css3:before {
+    content: "\f13c";
+}
+.fa-anchor:before {
+    content: "\f13d";
+}
+.fa-unlock-alt:before {
+    content: "\f13e";
+}
+.fa-bullseye:before {
+    content: "\f140";
+}
+.fa-ellipsis-h:before {
+    content: "\f141";
+}
+.fa-ellipsis-v:before {
+    content: "\f142";
+}
+.fa-rss-square:before {
+    content: "\f143";
+}
+.fa-play-circle:before {
+    content: "\f144";
+}
+.fa-ticket:before {
+    content: "\f145";
+}
+.fa-minus-square:before {
+    content: "\f146";
+}
+.fa-minus-square-o:before {
+    content: "\f147";
+}
+.fa-level-up:before {
+    content: "\f148";
+}
+.fa-level-down:before {
+    content: "\f149";
+}
+.fa-check-square:before {
+    content: "\f14a";
+}
+.fa-pencil-square:before {
+    content: "\f14b";
+}
+.fa-external-link-square:before {
+    content: "\f14c";
+}
+.fa-share-square:before {
+    content: "\f14d";
+}
+.fa-compass:before {
+    content: "\f14e";
+}
+.fa-toggle-down:before,
+.fa-caret-square-o-down:before {
+    content: "\f150";
+}
+.fa-toggle-up:before,
+.fa-caret-square-o-up:before {
+    content: "\f151";
+}
+.fa-toggle-right:before,
+.fa-caret-square-o-right:before {
+    content: "\f152";
+}
+.fa-euro:before,
+.fa-eur:before {
+    content: "\f153";
+}
+.fa-gbp:before {
+    content: "\f154";
+}
+.fa-dollar:before,
+.fa-usd:before {
+    content: "\f155";
+}
+.fa-rupee:before,
+.fa-inr:before {
+    content: "\f156";
+}
+.fa-cny:before,
+.fa-rmb:before,
+.fa-yen:before,
+.fa-jpy:before {
+    content: "\f157";
+}
+.fa-ruble:before,
+.fa-rouble:before,
+.fa-rub:before {
+    content: "\f158";
+}
+.fa-won:before,
+.fa-krw:before {
+    content: "\f159";
+}
+.fa-bitcoin:before,
+.fa-btc:before {
+    content: "\f15a";
+}
+.fa-file:before {
+    content: "\f15b";
+}
+.fa-file-text:before {
+    content: "\f15c";
+}
+.fa-sort-alpha-asc:before {
+    content: "\f15d";
+}
+.fa-sort-alpha-desc:before {
+    content: "\f15e";
+}
+.fa-sort-amount-asc:before {
+    content: "\f160";
+}
+.fa-sort-amount-desc:before {
+    content: "\f161";
+}
+.fa-sort-numeric-asc:before {
+    content: "\f162";
+}
+.fa-sort-numeric-desc:before {
+    content: "\f163";
+}
+.fa-thumbs-up:before {
+    content: "\f164";
+}
+.fa-thumbs-down:before {
+    content: "\f165";
+}
+.fa-youtube-square:before {
+    content: "\f166";
+}
+.fa-youtube:before {
+    content: "\f167";
+}
+.fa-xing:before {
+    content: "\f168";
+}
+.fa-xing-square:before {
+    content: "\f169";
+}
+.fa-youtube-play:before {
+    content: "\f16a";
+}
+.fa-dropbox:before {
+    content: "\f16b";
+}
+.fa-stack-overflow:before {
+    content: "\f16c";
+}
+.fa-instagram:before {
+    content: "\f16d";
+}
+.fa-flickr:before {
+    content: "\f16e";
+}
+.fa-adn:before {
+    content: "\f170";
+}
+.fa-bitbucket:before {
+    content: "\f171";
+}
+.fa-bitbucket-square:before {
+    content: "\f172";
+}
+.fa-tumblr:before {
+    content: "\f173";
+}
+.fa-tumblr-square:before {
+    content: "\f174";
+}
+.fa-long-arrow-down:before {
+    content: "\f175";
+}
+.fa-long-arrow-up:before {
+    content: "\f176";
+}
+.fa-long-arrow-left:before {
+    content: "\f177";
+}
+.fa-long-arrow-right:before {
+    content: "\f178";
+}
+.fa-apple:before {
+    content: "\f179";
+}
+.fa-windows:before {
+    content: "\f17a";
+}
+.fa-android:before {
+    content: "\f17b";
+}
+.fa-linux:before {
+    content: "\f17c";
+}
+.fa-dribbble:before {
+    content: "\f17d";
+}
+.fa-skype:before {
+    content: "\f17e";
+}
+.fa-foursquare:before {
+    content: "\f180";
+}
+.fa-trello:before {
+    content: "\f181";
+}
+.fa-female:before {
+    content: "\f182";
+}
+.fa-male:before {
+    content: "\f183";
+}
+.fa-gittip:before,
+.fa-gratipay:before {
+    content: "\f184";
+}
+.fa-sun-o:before {
+    content: "\f185";
+}
+.fa-moon-o:before {
+    content: "\f186";
+}
+.fa-archive:before {
+    content: "\f187";
+}
+.fa-bug:before {
+    content: "\f188";
+}
+.fa-vk:before {
+    content: "\f189";
+}
+.fa-weibo:before {
+    content: "\f18a";
+}
+.fa-renren:before {
+    content: "\f18b";
+}
+.fa-pagelines:before {
+    content: "\f18c";
+}
+.fa-stack-exchange:before {
+    content: "\f18d";
+}
+.fa-arrow-circle-o-right:before {
+    content: "\f18e";
+}
+.fa-arrow-circle-o-left:before {
+    content: "\f190";
+}
+.fa-toggle-left:before,
+.fa-caret-square-o-left:before {
+    content: "\f191";
+}
+.fa-dot-circle-o:before {
+    content: "\f192";
+}
+.fa-wheelchair:before {
+    content: "\f193";
+}
+.fa-vimeo-square:before {
+    content: "\f194";
+}
+.fa-turkish-lira:before,
+.fa-try:before {
+    content: "\f195";
+}
+.fa-plus-square-o:before {
+    content: "\f196";
+}
+.fa-space-shuttle:before {
+    content: "\f197";
+}
+.fa-slack:before {
+    content: "\f198";
+}
+.fa-envelope-square:before {
+    content: "\f199";
+}
+.fa-wordpress:before {
+    content: "\f19a";
+}
+.fa-openid:before {
+    content: "\f19b";
+}
+.fa-institution:before,
+.fa-bank:before,
+.fa-university:before {
+    content: "\f19c";
+}
+.fa-mortar-board:before,
+.fa-graduation-cap:before {
+    content: "\f19d";
+}
+.fa-yahoo:before {
+    content: "\f19e";
+}
+.fa-google:before {
+    content: "\f1a0";
+}
+.fa-reddit:before {
+    content: "\f1a1";
+}
+.fa-reddit-square:before {
+    content: "\f1a2";
+}
+.fa-stumbleupon-circle:before {
+    content: "\f1a3";
+}
+.fa-stumbleupon:before {
+    content: "\f1a4";
+}
+.fa-delicious:before {
+    content: "\f1a5";
+}
+.fa-digg:before {
+    content: "\f1a6";
+}
+.fa-pied-piper-pp:before {
+    content: "\f1a7";
+}
+.fa-pied-piper-alt:before {
+    content: "\f1a8";
+}
+.fa-drupal:before {
+    content: "\f1a9";
+}
+.fa-joomla:before {
+    content: "\f1aa";
+}
+.fa-language:before {
+    content: "\f1ab";
+}
+.fa-fax:before {
+    content: "\f1ac";
+}
+.fa-building:before {
+    content: "\f1ad";
+}
+.fa-child:before {
+    content: "\f1ae";
+}
+.fa-paw:before {
+    content: "\f1b0";
+}
+.fa-spoon:before {
+    content: "\f1b1";
+}
+.fa-cube:before {
+    content: "\f1b2";
+}
+.fa-cubes:before {
+    content: "\f1b3";
+}
+.fa-behance:before {
+    content: "\f1b4";
+}
+.fa-behance-square:before {
+    content: "\f1b5";
+}
+.fa-steam:before {
+    content: "\f1b6";
+}
+.fa-steam-square:before {
+    content: "\f1b7";
+}
+.fa-recycle:before {
+    content: "\f1b8";
+}
+.fa-automobile:before,
+.fa-car:before {
+    content: "\f1b9";
+}
+.fa-cab:before,
+.fa-taxi:before {
+    content: "\f1ba";
+}
+.fa-tree:before {
+    content: "\f1bb";
+}
+.fa-spotify:before {
+    content: "\f1bc";
+}
+.fa-deviantart:before {
+    content: "\f1bd";
+}
+.fa-soundcloud:before {
+    content: "\f1be";
+}
+.fa-database:before {
+    content: "\f1c0";
+}
+.fa-file-pdf-o:before {
+    content: "\f1c1";
+}
+.fa-file-word-o:before {
+    content: "\f1c2";
+}
+.fa-file-excel-o:before {
+    content: "\f1c3";
+}
+.fa-file-powerpoint-o:before {
+    content: "\f1c4";
+}
+.fa-file-photo-o:before,
+.fa-file-picture-o:before,
+.fa-file-image-o:before {
+    content: "\f1c5";
+}
+.fa-file-zip-o:before,
+.fa-file-archive-o:before {
+    content: "\f1c6";
+}
+.fa-file-sound-o:before,
+.fa-file-audio-o:before {
+    content: "\f1c7";
+}
+.fa-file-movie-o:before,
+.fa-file-video-o:before {
+    content: "\f1c8";
+}
+.fa-file-code-o:before {
+    content: "\f1c9";
+}
+.fa-vine:before {
+    content: "\f1ca";
+}
+.fa-codepen:before {
+    content: "\f1cb";
+}
+.fa-jsfiddle:before {
+    content: "\f1cc";
+}
+.fa-life-bouy:before,
+.fa-life-buoy:before,
+.fa-life-saver:before,
+.fa-support:before,
+.fa-life-ring:before {
+    content: "\f1cd";
+}
+.fa-circle-o-notch:before {
+    content: "\f1ce";
+}
+.fa-ra:before,
+.fa-resistance:before,
+.fa-rebel:before {
+    content: "\f1d0";
+}
+.fa-ge:before,
+.fa-empire:before {
+    content: "\f1d1";
+}
+.fa-git-square:before {
+    content: "\f1d2";
+}
+.fa-git:before {
+    content: "\f1d3";
+}
+.fa-y-combinator-square:before,
+.fa-yc-square:before,
+.fa-hacker-news:before {
+    content: "\f1d4";
+}
+.fa-tencent-weibo:before {
+    content: "\f1d5";
+}
+.fa-qq:before {
+    content: "\f1d6";
+}
+.fa-wechat:before,
+.fa-weixin:before {
+    content: "\f1d7";
+}
+.fa-send:before,
+.fa-paper-plane:before {
+    content: "\f1d8";
+}
+.fa-send-o:before,
+.fa-paper-plane-o:before {
+    content: "\f1d9";
+}
+.fa-history:before {
+    content: "\f1da";
+}
+.fa-circle-thin:before {
+    content: "\f1db";
+}
+.fa-header:before {
+    content: "\f1dc";
+}
+.fa-paragraph:before {
+    content: "\f1dd";
+}
+.fa-sliders:before {
+    content: "\f1de";
+}
+.fa-share-alt:before {
+    content: "\f1e0";
+}
+.fa-share-alt-square:before {
+    content: "\f1e1";
+}
+.fa-bomb:before {
+    content: "\f1e2";
+}
+.fa-soccer-ball-o:before,
+.fa-futbol-o:before {
+    content: "\f1e3";
+}
+.fa-tty:before {
+    content: "\f1e4";
+}
+.fa-binoculars:before {
+    content: "\f1e5";
+}
+.fa-plug:before {
+    content: "\f1e6";
+}
+.fa-slideshare:before {
+    content: "\f1e7";
+}
+.fa-twitch:before {
+    content: "\f1e8";
+}
+.fa-yelp:before {
+    content: "\f1e9";
+}
+.fa-newspaper-o:before {
+    content: "\f1ea";
+}
+.fa-wifi:before {
+    content: "\f1eb";
+}
+.fa-calculator:before {
+    content: "\f1ec";
+}
+.fa-paypal:before {
+    content: "\f1ed";
+}
+.fa-google-wallet:before {
+    content: "\f1ee";
+}
+.fa-cc-visa:before {
+    content: "\f1f0";
+}
+.fa-cc-mastercard:before {
+    content: "\f1f1";
+}
+.fa-cc-discover:before {
+    content: "\f1f2";
+}
+.fa-cc-amex:before {
+    content: "\f1f3";
+}
+.fa-cc-paypal:before {
+    content: "\f1f4";
+}
+.fa-cc-stripe:before {
+    content: "\f1f5";
+}
+.fa-bell-slash:before {
+    content: "\f1f6";
+}
+.fa-bell-slash-o:before {
+    content: "\f1f7";
+}
+.fa-trash:before {
+    content: "\f1f8";
+}
+.fa-copyright:before {
+    content: "\f1f9";
+}
+.fa-at:before {
+    content: "\f1fa";
+}
+.fa-eyedropper:before {
+    content: "\f1fb";
+}
+.fa-paint-brush:before {
+    content: "\f1fc";
+}
+.fa-birthday-cake:before {
+    content: "\f1fd";
+}
+.fa-area-chart:before {
+    content: "\f1fe";
+}
+.fa-pie-chart:before {
+    content: "\f200";
+}
+.fa-line-chart:before {
+    content: "\f201";
+}
+.fa-lastfm:before {
+    content: "\f202";
+}
+.fa-lastfm-square:before {
+    content: "\f203";
+}
+.fa-toggle-off:before {
+    content: "\f204";
+}
+.fa-toggle-on:before {
+    content: "\f205";
+}
+.fa-bicycle:before {
+    content: "\f206";
+}
+.fa-bus:before {
+    content: "\f207";
+}
+.fa-ioxhost:before {
+    content: "\f208";
+}
+.fa-angellist:before {
+    content: "\f209";
+}
+.fa-cc:before {
+    content: "\f20a";
+}
+.fa-shekel:before,
+.fa-sheqel:before,
+.fa-ils:before {
+    content: "\f20b";
+}
+.fa-meanpath:before {
+    content: "\f20c";
+}
+.fa-buysellads:before {
+    content: "\f20d";
+}
+.fa-connectdevelop:before {
+    content: "\f20e";
+}
+.fa-dashcube:before {
+    content: "\f210";
+}
+.fa-forumbee:before {
+    content: "\f211";
+}
+.fa-leanpub:before {
+    content: "\f212";
+}
+.fa-sellsy:before {
+    content: "\f213";
+}
+.fa-shirtsinbulk:before {
+    content: "\f214";
+}
+.fa-simplybuilt:before {
+    content: "\f215";
+}
+.fa-skyatlas:before {
+    content: "\f216";
+}
+.fa-cart-plus:before {
+    content: "\f217";
+}
+.fa-cart-arrow-down:before {
+    content: "\f218";
+}
+.fa-diamond:before {
+    content: "\f219";
+}
+.fa-ship:before {
+    content: "\f21a";
+}
+.fa-user-secret:before {
+    content: "\f21b";
+}
+.fa-motorcycle:before {
+    content: "\f21c";
+}
+.fa-street-view:before {
+    content: "\f21d";
+}
+.fa-heartbeat:before {
+    content: "\f21e";
+}
+.fa-venus:before {
+    content: "\f221";
+}
+.fa-mars:before {
+    content: "\f222";
+}
+.fa-mercury:before {
+    content: "\f223";
+}
+.fa-intersex:before,
+.fa-transgender:before {
+    content: "\f224";
+}
+.fa-transgender-alt:before {
+    content: "\f225";
+}
+.fa-venus-double:before {
+    content: "\f226";
+}
+.fa-mars-double:before {
+    content: "\f227";
+}
+.fa-venus-mars:before {
+    content: "\f228";
+}
+.fa-mars-stroke:before {
+    content: "\f229";
+}
+.fa-mars-stroke-v:before {
+    content: "\f22a";
+}
+.fa-mars-stroke-h:before {
+    content: "\f22b";
+}
+.fa-neuter:before {
+    content: "\f22c";
+}
+.fa-genderless:before {
+    content: "\f22d";
+}
+.fa-facebook-official:before {
+    content: "\f230";
+}
+.fa-pinterest-p:before {
+    content: "\f231";
+}
+.fa-whatsapp:before {
+    content: "\f232";
+}
+.fa-server:before {
+    content: "\f233";
+}
+.fa-user-plus:before {
+    content: "\f234";
+}
+.fa-user-times:before {
+    content: "\f235";
+}
+.fa-hotel:before,
+.fa-bed:before {
+    content: "\f236";
+}
+.fa-viacoin:before {
+    content: "\f237";
+}
+.fa-train:before {
+    content: "\f238";
+}
+.fa-subway:before {
+    content: "\f239";
+}
+.fa-medium:before {
+    content: "\f23a";
+}
+.fa-yc:before,
+.fa-y-combinator:before {
+    content: "\f23b";
+}
+.fa-optin-monster:before {
+    content: "\f23c";
+}
+.fa-opencart:before {
+    content: "\f23d";
+}
+.fa-expeditedssl:before {
+    content: "\f23e";
+}
+.fa-battery-4:before,
+.fa-battery:before,
+.fa-battery-full:before {
+    content: "\f240";
+}
+.fa-battery-3:before,
+.fa-battery-three-quarters:before {
+    content: "\f241";
+}
+.fa-battery-2:before,
+.fa-battery-half:before {
+    content: "\f242";
+}
+.fa-battery-1:before,
+.fa-battery-quarter:before {
+    content: "\f243";
+}
+.fa-battery-0:before,
+.fa-battery-empty:before {
+    content: "\f244";
+}
+.fa-mouse-pointer:before {
+    content: "\f245";
+}
+.fa-i-cursor:before {
+    content: "\f246";
+}
+.fa-object-group:before {
+    content: "\f247";
+}
+.fa-object-ungroup:before {
+    content: "\f248";
+}
+.fa-sticky-note:before {
+    content: "\f249";
+}
+.fa-sticky-note-o:before {
+    content: "\f24a";
+}
+.fa-cc-jcb:before {
+    content: "\f24b";
+}
+.fa-cc-diners-club:before {
+    content: "\f24c";
+}
+.fa-clone:before {
+    content: "\f24d";
+}
+.fa-balance-scale:before {
+    content: "\f24e";
+}
+.fa-hourglass-o:before {
+    content: "\f250";
+}
+.fa-hourglass-1:before,
+.fa-hourglass-start:before {
+    content: "\f251";
+}
+.fa-hourglass-2:before,
+.fa-hourglass-half:before {
+    content: "\f252";
+}
+.fa-hourglass-3:before,
+.fa-hourglass-end:before {
+    content: "\f253";
+}
+.fa-hourglass:before {
+    content: "\f254";
+}
+.fa-hand-grab-o:before,
+.fa-hand-rock-o:before {
+    content: "\f255";
+}
+.fa-hand-stop-o:before,
+.fa-hand-paper-o:before {
+    content: "\f256";
+}
+.fa-hand-scissors-o:before {
+    content: "\f257";
+}
+.fa-hand-lizard-o:before {
+    content: "\f258";
+}
+.fa-hand-spock-o:before {
+    content: "\f259";
+}
+.fa-hand-pointer-o:before {
+    content: "\f25a";
+}
+.fa-hand-peace-o:before {
+    content: "\f25b";
+}
+.fa-trademark:before {
+    content: "\f25c";
+}
+.fa-registered:before {
+    content: "\f25d";
+}
+.fa-creative-commons:before {
+    content: "\f25e";
+}
+.fa-gg:before {
+    content: "\f260";
+}
+.fa-gg-circle:before {
+    content: "\f261";
+}
+.fa-tripadvisor:before {
+    content: "\f262";
+}
+.fa-odnoklassniki:before {
+    content: "\f263";
+}
+.fa-odnoklassniki-square:before {
+    content: "\f264";
+}
+.fa-get-pocket:before {
+    content: "\f265";
+}
+.fa-wikipedia-w:before {
+    content: "\f266";
+}
+.fa-safari:before {
+    content: "\f267";
+}
+.fa-chrome:before {
+    content: "\f268";
+}
+.fa-firefox:before {
+    content: "\f269";
+}
+.fa-opera:before {
+    content: "\f26a";
+}
+.fa-internet-explorer:before {
+    content: "\f26b";
+}
+.fa-tv:before,
+.fa-television:before {
+    content: "\f26c";
+}
+.fa-contao:before {
+    content: "\f26d";
+}
+.fa-500px:before {
+    content: "\f26e";
+}
+.fa-amazon:before {
+    content: "\f270";
+}
+.fa-calendar-plus-o:before {
+    content: "\f271";
+}
+.fa-calendar-minus-o:before {
+    content: "\f272";
+}
+.fa-calendar-times-o:before {
+    content: "\f273";
+}
+.fa-calendar-check-o:before {
+    content: "\f274";
+}
+.fa-industry:before {
+    content: "\f275";
+}
+.fa-map-pin:before {
+    content: "\f276";
+}
+.fa-map-signs:before {
+    content: "\f277";
+}
+.fa-map-o:before {
+    content: "\f278";
+}
+.fa-map:before {
+    content: "\f279";
+}
+.fa-commenting:before {
+    content: "\f27a";
+}
+.fa-commenting-o:before {
+    content: "\f27b";
+}
+.fa-houzz:before {
+    content: "\f27c";
+}
+.fa-vimeo:before {
+    content: "\f27d";
+}
+.fa-black-tie:before {
+    content: "\f27e";
+}
+.fa-fonticons:before {
+    content: "\f280";
+}
+.fa-reddit-alien:before {
+    content: "\f281";
+}
+.fa-edge:before {
+    content: "\f282";
+}
+.fa-credit-card-alt:before {
+    content: "\f283";
+}
+.fa-codiepie:before {
+    content: "\f284";
+}
+.fa-modx:before {
+    content: "\f285";
+}
+.fa-fort-awesome:before {
+    content: "\f286";
+}
+.fa-usb:before {
+    content: "\f287";
+}
+.fa-product-hunt:before {
+    content: "\f288";
+}
+.fa-mixcloud:before {
+    content: "\f289";
+}
+.fa-scribd:before {
+    content: "\f28a";
+}
+.fa-pause-circle:before {
+    content: "\f28b";
+}
+.fa-pause-circle-o:before {
+    content: "\f28c";
+}
+.fa-stop-circle:before {
+    content: "\f28d";
+}
+.fa-stop-circle-o:before {
+    content: "\f28e";
+}
+.fa-shopping-bag:before {
+    content: "\f290";
+}
+.fa-shopping-basket:before {
+    content: "\f291";
+}
+.fa-hashtag:before {
+    content: "\f292";
+}
+.fa-bluetooth:before {
+    content: "\f293";
+}
+.fa-bluetooth-b:before {
+    content: "\f294";
+}
+.fa-percent:before {
+    content: "\f295";
+}
+.fa-gitlab:before {
+    content: "\f296";
+}
+.fa-wpbeginner:before {
+    content: "\f297";
+}
+.fa-wpforms:before {
+    content: "\f298";
+}
+.fa-envira:before {
+    content: "\f299";
+}
+.fa-universal-access:before {
+    content: "\f29a";
+}
+.fa-wheelchair-alt:before {
+    content: "\f29b";
+}
+.fa-question-circle-o:before {
+    content: "\f29c";
+}
+.fa-blind:before {
+    content: "\f29d";
+}
+.fa-audio-description:before {
+    content: "\f29e";
+}
+.fa-volume-control-phone:before {
+    content: "\f2a0";
+}
+.fa-braille:before {
+    content: "\f2a1";
+}
+.fa-assistive-listening-systems:before {
+    content: "\f2a2";
+}
+.fa-asl-interpreting:before,
+.fa-american-sign-language-interpreting:before {
+    content: "\f2a3";
+}
+.fa-deafness:before,
+.fa-hard-of-hearing:before,
+.fa-deaf:before {
+    content: "\f2a4";
+}
+.fa-glide:before {
+    content: "\f2a5";
+}
+.fa-glide-g:before {
+    content: "\f2a6";
+}
+.fa-signing:before,
+.fa-sign-language:before {
+    content: "\f2a7";
+}
+.fa-low-vision:before {
+    content: "\f2a8";
+}
+.fa-viadeo:before {
+    content: "\f2a9";
+}
+.fa-viadeo-square:before {
+    content: "\f2aa";
+}
+.fa-snapchat:before {
+    content: "\f2ab";
+}
+.fa-snapchat-ghost:before {
+    content: "\f2ac";
+}
+.fa-snapchat-square:before {
+    content: "\f2ad";
+}
+.fa-pied-piper:before {
+    content: "\f2ae";
+}
+.fa-first-order:before {
+    content: "\f2b0";
+}
+.fa-yoast:before {
+    content: "\f2b1";
+}
+.fa-themeisle:before {
+    content: "\f2b2";
+}
+.fa-google-plus-circle:before,
+.fa-google-plus-official:before {
+    content: "\f2b3";
+}
+.fa-fa:before,
+.fa-font-awesome:before {
+    content: "\f2b4";
+}
+.fa-handshake-o:before {
+    content: "\f2b5";
+}
+.fa-envelope-open:before {
+    content: "\f2b6";
+}
+.fa-envelope-open-o:before {
+    content: "\f2b7";
+}
+.fa-linode:before {
+    content: "\f2b8";
+}
+.fa-address-book:before {
+    content: "\f2b9";
+}
+.fa-address-book-o:before {
+    content: "\f2ba";
+}
+.fa-vcard:before,
+.fa-address-card:before {
+    content: "\f2bb";
+}
+.fa-vcard-o:before,
+.fa-address-card-o:before {
+    content: "\f2bc";
+}
+.fa-user-circle:before {
+    content: "\f2bd";
+}
+.fa-user-circle-o:before {
+    content: "\f2be";
+}
+.fa-user-o:before {
+    content: "\f2c0";
+}
+.fa-id-badge:before {
+    content: "\f2c1";
+}
+.fa-drivers-license:before,
+.fa-id-card:before {
+    content: "\f2c2";
+}
+.fa-drivers-license-o:before,
+.fa-id-card-o:before {
+    content: "\f2c3";
+}
+.fa-quora:before {
+    content: "\f2c4";
+}
+.fa-free-code-camp:before {
+    content: "\f2c5";
+}
+.fa-telegram:before {
+    content: "\f2c6";
+}
+.fa-thermometer-4:before,
+.fa-thermometer:before,
+.fa-thermometer-full:before {
+    content: "\f2c7";
+}
+.fa-thermometer-3:before,
+.fa-thermometer-three-quarters:before {
+    content: "\f2c8";
+}
+.fa-thermometer-2:before,
+.fa-thermometer-half:before {
+    content: "\f2c9";
+}
+.fa-thermometer-1:before,
+.fa-thermometer-quarter:before {
+    content: "\f2ca";
+}
+.fa-thermometer-0:before,
+.fa-thermometer-empty:before {
+    content: "\f2cb";
+}
+.fa-shower:before {
+    content: "\f2cc";
+}
+.fa-bathtub:before,
+.fa-s15:before,
+.fa-bath:before {
+    content: "\f2cd";
+}
+.fa-podcast:before {
+    content: "\f2ce";
+}
+.fa-window-maximize:before {
+    content: "\f2d0";
+}
+.fa-window-minimize:before {
+    content: "\f2d1";
+}
+.fa-window-restore:before {
+    content: "\f2d2";
+}
+.fa-times-rectangle:before,
+.fa-window-close:before {
+    content: "\f2d3";
+}
+.fa-times-rectangle-o:before,
+.fa-window-close-o:before {
+    content: "\f2d4";
+}
+.fa-bandcamp:before {
+    content: "\f2d5";
+}
+.fa-grav:before {
+    content: "\f2d6";
+}
+.fa-etsy:before {
+    content: "\f2d7";
+}
+.fa-imdb:before {
+    content: "\f2d8";
+}
+.fa-ravelry:before {
+    content: "\f2d9";
+}
+.fa-eercast:before {
+    content: "\f2da";
+}
+.fa-microchip:before {
+    content: "\f2db";
+}
+.fa-snowflake-o:before {
+    content: "\f2dc";
+}
+.fa-superpowers:before {
+    content: "\f2dd";
+}
+.fa-wpexplorer:before {
+    content: "\f2de";
+}
+.fa-meetup:before {
+    content: "\f2e0";
+}
+.sr-only {
+    position: absolute;
+    width: 1px;
+    height: 1px;
+    padding: 0;
+    margin: -1px;
+    overflow: hidden;
+    clip: rect(0, 0, 0, 0);
+    border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+    position: static;
+    width: auto;
+    height: auto;
+    margin: 0;
+    overflow: visible;
+    clip: auto;
+}

+ 1 - 1
src/main/resources/static/index.html

@@ -5,6 +5,6 @@
     <title>YONGIN ITS Operator System</title>
 </head>
 <body>
-    <h1>YONGIN ITS Operator System</h1>
+    <h1>static/index.html</h1>
 </body>
 </html>

+ 1007 - 0
src/main/resources/static/js/utils/Parking copy.asn

@@ -0,0 +1,1007 @@
+PARKING DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+-- [ITSK-00090_2021v3]_실시간 주차정보 수집·연계·제공 규격.pdf
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+ParkingC2FStaticInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time                 UTF8String (SIZE(1..14)),
+    parking-station-id                  UTF8String (SIZE(1..22)),
+    pkfc-parkingC2FStaticinfo-Version   INTEGER(0..65535),
+    pkfc-ParkName-txt                   UTF8String (SIZE(1..40)),
+    pkfc-ParkAddress                    SEQUENCE
+    {
+        sido-name       UTF8String (SIZE(1..16)),
+        gugun-name      UTF8String (SIZE(1..16)),
+        eupmyon-name    UTF8String (SIZE(1..16)) OPTIONAL,
+        road-name       UTF8String (SIZE(1..16)),
+        bldg-num        UTF8String (SIZE(1..16)) OPTIONAL,
+        dongho-name     UTF8String (SIZE(1..16)) OPTIONAL,
+        addr-text       UTF8String (SIZE(1..32)) OPTIONAL
+    },
+    pkfc-Installation-Date  UTF8String (SIZE(1..8)),
+    pkfc-Abolition-Date     UTF8String (SIZE(1..8)) OPTIONAL,
+    pkfc-ParkLocation       SEQUENCE OF ParkingLocationInfo,
+    pkfc-Gateway-Code       ENUMERATED
+    {
+        gw-share    (0),
+        gw-division (1),
+        gw-ETC      (9)
+    },
+    pkfc-Type-Code ENUMERATED
+    {
+        type-parallel           (0),
+        type-rightangled        (1),
+        type-60degreesforward   (2),
+        type-45degreesforward   (3),
+        type-ETC                (9)
+    },
+    pkfc-ParkUsing-Code BIT STRING
+    {
+        self-parking        (0),
+        mechanical-parking  (1),
+        others              (2)
+    },
+    pkfc-ParkingLand-Level ENUMERATED
+    {
+        level1  (0),
+        level2  (1),
+        level3  (2),
+        level4  (3),
+        level5  (4),
+        etc     (9)
+    },
+    pkfc-GraphicObjectData SEQUENCE
+    {
+        graphic-Type ENUMERATED
+        {
+            bitmap  (0),
+            gif     (1),
+            jpg     (2), 
+            png     (3), 
+            other   (4)
+        },
+        graphic-Data            OCTET STRING,
+        graphic-AdditionalText  UTF8String (SIZE(1..50)) OPTIONAL
+    },
+    pkfc-SystemName-txt                 UTF8String (SIZE(1..40)),
+    pkfc-SystemInstallation-Date        UTF8String (SIZE(1..8)) OPTIONAL,
+    pkfc-RelationLaw                    UTF8String (SIZE(1..50)) OPTIONAL,
+    pkfc-ParkingLots-available-cartype  ENUMERATED
+    {
+        compact-car     (0),
+        midsize-car     (1),
+        full-sized-car  (2),
+        SUV             (3),
+        VAN             (4),
+        Truck           (5)
+    } OPTIONAL,
+    pkfc-ParkingLots-total  INTEGER(0..65535),
+    pkfc-ParkingLots-floor  SEQUENCE OF FloorParkingLots OPTIONAL,
+    pkfc-ParkingLots-type   SEQUENCE OF TypedParkingLotsOPTIONAL,
+    pkfc-CollectionDevice   ENUMERATED
+    {
+        unInstallation  (0),
+        installation    (1)
+    },
+    pkfc-Controller-quantity SEQUENCE OF ControllerQty OPTIONAL,
+    pkfc-CollectionDevice-total INTEGER(0..65535) OPTIONAL,
+    pkfc-CollectionDevice-Type ENUMERATED
+    {
+        type-image          (0),
+        type-geomagnetic    (1),
+        type-radar          (2),
+        type-loop           (3),
+        type-ultrasonic     (4),
+        type-etc            (9)
+    } OPTIONAL,
+    pkfc-CollectionDevice-quantity          SEQUENCEOFCollectionDeviceQty OPTIONAL,
+    pkfc-CollectionDeviceInstallation-Date  UTF8String (SIZE(1..8)) OPTIONAL,
+    pkfc-CCTV-installation ENUMERATED
+    {
+        unInstallation  (0),
+        installation    (1)
+    } OPTIONAL,
+    pkfc-CCTV-quantity INTEGER (0..65535) OPTIONAL
+}
+
+ParkingLocationInfo ::= SEQUENCE
+{
+    entranceName-txt    UTF8String (SIZE(1..40)),
+    coordinate          NMEACoord
+}
+
+NMEACoord ::= SEQUENCE
+{
+    latitude SEQUENCE
+    {
+        integerValue INTEGER,
+        fractionValue INTEGER,
+        fracSize INTEGER(0..10),
+        compass ENUMERATED
+        {
+            north,
+            south
+        }
+    },
+    longitude SEQUENCE
+    {
+        integerValue INTEGER,
+        fractionValue INTEGER,
+        fracSize INTEGER(0..10),
+        compass ENUMERATED
+        {
+            east,
+            west
+        }
+    },
+    optData OCTET STRING OPTIONAL
+}
+FloorParkingLots ::= SEQUENCE
+{
+    floor-number                UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-number-parkinglots    INTEGER(0..65535) OPTIONAL,
+    floor-section               UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-section-parkinglots   INTEGER(0..65535) OPTIONAL
+}
+TypedParkingLots ::= SEQUENCE
+{
+    lots-for-general        INTEGER(0..65535) OPTIONAL,
+    lots-for-small-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-freight-car    INTEGER(0..65535) OPTIONAL,
+    lots-for-emergency-car  INTEGER(0..65535) OPTIONAL,
+    lots-for-handicapped    INTEGER(0..65535) OPTIONAL,
+    lots-for-women          INTEGER(0..65535) OPTIONAL,
+    lots-for-others         INTEGER(0..65535) OPTIONAL
+}
+ControllerQty ::= SEQUENCE
+{
+    contoller-master    INTEGER(0..65535) OPTIONAL,
+    contoller-slave     INTEGER(0..65535) OPTIONAL
+}
+CollectionDeviceQty ::= SEQUENCE
+{
+    qty-image       INTEGER(0..65535) OPTIONAL,
+    qty-geomagnetic INTEGER(0..65535) OPTIONAL,
+    qty-radar       INTEGER(0..65535) OPTIONAL,
+    qty-loop        INTEGER(0..65535) OPTIONAL,
+    qty-ultrasonic  INTEGER(0..65535) OPTIONAL,
+    qty-etc         INTEGER(0..65535) OPTIONAL
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2CStaticInfoList ::= SEQUENCE OF ParkingC2CStaticInfo
+ParkingC2CStaticInfo ::= SEQUENCE
+{
+    parking-station-id          UTF8String (SIZE(1..22)),
+    parking-station-static-info ParkingC2FStaticInfo
+}
+--------------------------------------------------------------------------------------------
+
+ParkingC2FOperateInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time                 UTF8String (SIZE(1..14)),
+    parking-station-id                  UTF8String (SIZE(1..22)),
+    pkfc-parkingC2FOperateinfo-Version  INTEGER(0..65535),
+    pkfc-Operate-Name                   UTF8String (SIZE(1..20)),
+    pkfc-Operate-Department             UTF8String (SIZE(1..20)) OPTIONAL,
+    pkfc-Operate-Contact                SEQUENCE
+    {
+        pkfc-Operate-person     UTF8String (SIZE(1..20)) OPTIONAL,
+        pkfc-Operate-telephone  UTF8String (SIZE(1..20)),
+        pkfc-Operate-email      UTF8String (SIZE(1..40)) OPTIONAL
+    },
+    pkfc-Restrict-Code ENUMERATED
+    {
+        the-2-day-rotation-system   (0),
+        the-5-day-rotation-system   (1),
+        the-10-day-rotation-system  (2),
+        no-driving-on-a-day-system  (3),
+        restrict-others             (4),
+        restrict-none               (5)
+    },
+    pkfc-Operation-Schedule ParkingOperationSchedule,
+    pkfc-FreeOpen-Code ENUMERATED
+    {
+        no-free-open        (0),
+        free-after-close    (1)
+    } OPTIONAL,
+    pkfc-Charge-Method ENUMERATED
+    {
+        manned      (0),
+        unmanned    (1),
+        mixed       (2),
+        etc         (9)
+    } OPTIONAL,
+    pkfc-Charge-Code ENUMERATED
+    {
+        charge-free (0),
+        charge      (1),
+        complex     (2)
+    },
+    pkfc-Pay-Type BIT STRING
+    {
+        pay-cash                (0),
+        pay-creditCard          (1),
+        pay-transportaionCard   (2),
+        pay-HipassCard          (3),
+        pay-mobilePay           (4),
+        pay-FinTech             (5),
+        pay-MaaS                (6),
+        pay-etc1                (7),
+        pay-etc2                (8),
+        pay-etc3                (9)
+    },
+    pkfc-FreeCharge-BaseTime INTEGER(0..99999) OPTIONAL,
+    pkfc-Parking-Rate SEQUENCE
+    {
+        base-time       INTEGER(0..1440),
+        base-rate       INTEGER(0..99999),
+        additional-time INTEGER(0..1440),
+        additional-rate INTEGER(0..99999)
+    },
+    pkfc-Parking-FlatRate SEQUENCE
+    {
+        daily-apply-time    INTEGER(0..99999),
+        a-daily-rate        INTEGER(0..99999),
+        monthly-rate        INTEGER(0..999999)
+    } OPTIONAL,
+    pkfc-Holiday-Rate SEQUENCE
+    {
+        holiday-base-time       INTEGER(0..1440),
+        holiday-base-rate       INTEGER(0..99999),
+        holiday-additional-time INTEGER(0..1440),
+        holiday-additional-rate INTEGER(0..999999),
+        holiday-a-daily-rate    INTEGER(0..999999)
+    } OPTIONAL,
+    pkfc-Extra-Rate SEQUENCE
+    {
+        extra-base-time         INTEGER(0..99999),
+        extra-additional-time   INTEGER(0..99999),
+        extra-additional-rate   INTEGER(0..999999)
+    } OPTIONAL,
+    pkfc-Discount-Rates SEQUENCE
+    {
+        small-car                       INTEGER(0..100),
+        handicapped                     INTEGER(0..100),
+        driving-system-car              INTEGER(0..100),
+        emergency-car                   INTEGER(0..100),
+        a-man-of-merit                  INTEGER(0..100),
+        earnest-taxpayer                INTEGER(0..100),
+        excellent-volunteer-car         INTEGER(0..100),
+        self-carfree-participation-car  INTEGER(0..100),
+        transit-car                     INTEGER(0..100),
+        official-car                    INTEGER(0..100),
+        defoliation-aftereffect-car     INTEGER(0..100),
+        military-faithful-family-car    INTEGER(0..100),
+        low-emission-car                INTEGER(0..100),
+        rescue-efforts-certificate-car  INTEGER(0..100),
+        multi-child-car                 INTEGER(0..100),
+        for-others                      INTEGER(0..100)
+    } OPTIONAL,
+    pkfc-ReservationService-Code ENUMERATED
+    {
+        reservation-none    (0),
+        parkinglot          (1),
+        parkingarea         (2),
+        parkingspace        (3)
+    },
+    pkfc-Parking-additional UTF8String (SIZE(1..256)) OPTIONAL
+}
+
+DailyTimeStamp ::= SEQUENCE
+{
+    hour    INTEGER(0..23),
+    min     INTEGER(0..59),
+    sec     INTEGER(0..59)
+}
+
+ParkingOperationSchedule ::= SEQUENCE
+{
+    sunday      ParkingOperationInfo,
+    monday      ParkingOperationInfo,
+    tuesday     ParkingOperationInfo,
+    wednesday   ParkingOperationInfo,
+    thursday    ParkingOperationInfo,
+    friday      ParkingOperationInfo,
+    saturday    ParkingOperationInfo,
+    holiday     ParkingOperationInfo
+}
+
+ParkingOperationInfo ::= CHOICE
+{
+    operational     ParkingOperationData,
+    not-operational NULL
+}
+
+ParkingOperationData ::= SEQUENCE
+{
+    open-time   DailyTimeStamp,
+    close-time  DailyTimeStamp,
+    charging    ParkingOperationCharge
+}
+
+ParkingOperationCharge ::= ENUMERATED
+{
+    charge-free (0),
+    charge      (1),
+    complex     (2)
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2COperateInfoList ::= SEQUENCE OF ParkingC2COperateInfo
+ParkingC2COperateInfo ::= SEQUENCE
+{
+    parking-station-id              UTF8String (SIZE(1..22)),
+    parking-station-operate-info    ParkingC2FOperateInfo
+}
+--------------------------------------------------------------------------------------------
+
+ParkingspaceF2DRealTimeInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time UTF8String (SIZE(1..14)) OPTIONAL,
+    pkfc-CollectionDevice-information SEQUENCE
+    {
+        device-id INTEGER(0..65535) OPTIONAL,
+        devicetype ENUMERATED
+        {
+            type-image (0),
+            type-geomagnetic (1),
+            type-radar (2),
+            type-loop (3),
+            type-ultrasonic (4),
+            type-etc (9)
+        } OPTIONAL,
+
+        parkingspace-id INTEGER(0..65535) OPTIONAL,
+
+        typedparkinglots ENUMERATED
+        {
+            lots-for-general (0),
+            lots-for-small-car (1),
+            lots-for-freight-car (2),
+            lots-for-emergency-car (3),
+            lots-for-handicapped (4),
+            lots-for-women (5),
+            lots-for-others (6), 
+            -- …
+        } OPTIONAL,
+
+        parkingspaceoccupation ENUMERATED
+        {
+            possible (0),
+            impossible (1)
+        } OPTIONAL,
+
+        connection ENUMERATED
+        {
+            abnormal (0),
+            normal (1)
+        } OPTIONAL
+    }
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2FRealTimeInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time         UTF8String (SIZE(1..14)),
+    pkfc-DataCollection-Time    UTF8String (SIZE(1..14)),
+    parking-station-id          UTF8String (SIZE(1..22)),
+    pkfc-Congestiont-Status ENUMERATED
+    {
+        available   (0),
+        normal      (1),
+        delay       (2),
+        full        (3)
+    } OPTIONAL,
+    pkfc-Parkingspace-Realtime-info     ParkingspaceF2DRealTimeInfo,
+    pkfc-ParkingLots-total              INTEGER(0..65535),
+    pkfc-AvailableParkingLots-total     INTEGER(0..65535),
+    pkfc-ParkingLots-floor              SEQUENCE OF FloorParkingLots OPTIONAL,
+    pkfc-AvailableParkingLots-floor     ParkingLotsFloorList OPTIONAL,
+    pkfc-ParkingLots-typed              ParkingLotsTypedList OPTIONAL,
+    pkfc-AvailableParkingLots-typed     ParkingLotsTypedList OPTIONAL,
+    pkfc-AvailableReservation-Quantity  INTEGER(0..65535) OPTIONAL,
+    pkfc-Parking-additional             UTF8String (SIZE(1..256)) OPTIONAL
+}
+
+ParkingLotsFloorList ::= SEQUENCE
+{
+    floor-number                UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-number-parkinglots    INTEGER(0..65535) OPTIONAL,
+    floor-section               UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-section-parkinglots   INTEGER(0..65535) OPTIONAL
+}
+
+ParkingLotsTypedList ::= SEQUENCE
+{
+    lots-for-general        INTEGER(0..65535) OPTIONAL,
+    lots-for-green-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-small-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-freight-car    INTEGER(0..65535) OPTIONAL,
+    lots-for-emergency-car  INTEGER(0..65535) OPTIONAL,
+    lots-for-handicapped    INTEGER(0..65535) OPTIONAL,
+    lots-for-elder-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-women          INTEGER(0..65535) OPTIONAL,
+    lots-for-others         INTEGER(0..65535) OPTIONAL
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+ParkingC2CRealtimeInfo ::= SEQUENCE
+{
+    parking-station-id              UTF8String (SIZE(1..22)),
+    parking-station-realtime-info   ParkingC2FRealTimeInfo
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+ParkingC2CRealtimeInfo ::= SEQUENCE
+{
+    parking-station-id              UTF8String (SIZE(1..22)),
+    parking-station-realtime-info   ParkingC2FRealTimeInfo
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationRequestInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time     UTF8String (SIZE(1..14)),
+    parking-station-id      UTF8String (SIZE(1..22)),
+    pkfc-Parking-additional UTF8String (SIZE(1..256)) OPTIONAL,
+    pkfc-Reservation-Code CHOICE
+    {
+        reservation-new     ReservationData,
+        reservation-update  ReservationUpdate,
+        reservation-cancel  ReservationUpdate
+    }
+}
+
+ReservationData ::= SEQUENCE
+{
+pkfc-resve-in-no            UTF8String (SIZE(1..32)),
+pkfc-resve-customer-info    SEQUENCE
+{
+    reservation-plate-num   UTF8String (SIZE(1..10)),
+    reservation-car-type    ENUMERATED
+    {
+        general(compact,mid)    (0),
+        general(large)          (1),
+        small-car               (2),
+        green-car               (3),
+        handicapped             (4),
+        van                     (5),
+        freight-car(mid)        (6),
+        freight-car(large)      (7),
+        others                  (8)
+    } OPTIONAL,
+    reservation-contact-name    UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-contact-email   UTF8String (SIZE(1..40)),
+    reservation-contact-num     UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-in-time         UTF8String (SIZE(1..14)),
+    reservation-out-time        UTF8String (SIZE(1..14)) OPTIONAL
+    }
+}
+
+ReservationUpdate ::= SEQUENCE
+{
+    pkfc-resve-in-no            UTF8String (SIZE(1..32)),
+    pkfc-resve-customer-info    SEQUENCE
+    {
+        reservation-plate-num-change    UTF8String (SIZE(1..10)) OPTIONAL,
+        reservation-car-type-change     ENUMERATED
+        {
+            general(compact,mid)    (0),
+            general(large)          (1),
+            small-car               (2),
+            green-car               (3),
+            handicapped             (4),
+            van                     (5),
+            freight-car(mid)        (6),
+            freight-car(large)      (7),
+            others                  (8)
+        } OPTIONAL,
+        reservation-contact-name-change UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-contact-email       UTF8String (SIZE(1..40)) OPTIONAL,
+        reservation-contact-num-change  UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-in-time-change      UTF8String (SIZE(1..14)) OPTIONAL,
+        reservation-out-time-change     UTF8String (SIZE(1..14)) OPTIONAL
+    }
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationResultInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time             UTF8String (SIZE(1..14)),
+    parking-station-id              UTF8String (SIZE(1..22)),
+    pkfc-Reservation-parkingspace   UTF8String (SIZE(1..20)) OPTIONAL,
+    pkfc-Reservation-Result         CHOICE
+    {
+        reservationNew-success          ReservationResult,
+        reservationUpdate-success       NULL,
+        reservationCancel-success       NULL,
+        reservationReject-Reason-txt    UTF8String (SIZE(1..256)
+    }
+    pkfc-Reservation-complete-Result    ENUMERATED
+    {
+        complete        (0),
+        cancellation    (1)
+    }
+}
+
+ReservationResult ::= SEQUENCE
+{
+    pkfc-resve-in-no            UTF8String (SIZE(1..32)),
+    pkfc-resve-customer-info    SEQUENCE
+    {
+        reservation-plate-num   UTF8String (SIZE(1..10)),
+        reservation-car-type    ENUMERATED
+        {
+            general(compact,mid)    (0),
+            general(large)          (1),
+            small-car               (2),
+            green-car               (3),
+            handicapped             (4),
+            van                     (5),
+            freight-car(mid)        (6),
+            freight-car(large)      (7),
+            others                  (8)
+        } OPTIONAL,
+        reservation-contact-name    UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-contact-email   UTF8String (SIZE(1..40)),
+        reservation-contact-num     UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-in-time         UTF8String (SIZE(1..14)),
+        reservation-out-time        UTF8String (SIZE(1..14)) OPTIONAL
+    }
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CReservationRequestInfoList ::= SEQUENCE OF ParkingC2CReservationRequestInfo
+ParkingC2CReservationRequestInfo ::= SEQUENCE
+{
+    parking-station-id                          UTF8String (SIZE(1..22)),
+    parking-station-reservation-request-info    ParkingC2FReservationRequestInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CReservationResultInfoList ::= SEQUENCE OF ParkingC2CReservationResultInfo
+ParkingC2CReservationResultInfo ::= SEQUENCE
+{
+    parking-station-id                      UTF8String (SIZE(1..22)),
+    parking-station-reservation-result-info ParkingC2FReservationResultInfo
+}
+--------------------------------------------------------------------------------------------
+PakingC2FVehicleLocationInfoRequest ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time UTF8String (SIZE(1..14)),
+    parking-station-id  UTF8String (SIZE(1..22)),
+    pkfc-Plate-Number   UTF8String (SIZE(1..20))
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FVehicleLocationInfoResult ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time UTF8String (SIZE(1..14)),
+    parking-station-id  UTF8String (SIZE(1..22)),
+    pkfc-Plate-Number   UTF8String (SIZE(1..20)),
+    pkfc-userLocation   UserLocation
+}
+UserLocation ::= SEQUENCE
+{
+    floor-number    UTF8String (SIZE(1..10)),
+    floor-section   UTF8String (SIZE(1..10))
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CVehicleLocationInfoRequestList ::= SEQUENCE OF ParkingC2CVehicleLocationInfoRequest
+ParkingC2CVehicleLocationInfoRequest ::= SEQUENCE
+{
+    parking-station-id                              UTF8String (SIZE(1..22)),
+    parking-station-vehiclelocation-request-info    ParkingC2FVehicleLocationInfoRequest
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CReservationResultInfoList ::= SEQUENCE OF ParkingC2CReservationResultInfo
+ParkingC2CReservationResultInfo ::= SEQUENCE
+{
+    parking-station-id                          UTF8String (SIZE(1..22)),
+    parking-station-vehiclelocation-result-info ParkingC2FVehicleLocationInfoResult
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CLinkStatusInfoList ::= SEQUENCE
+{
+    parkingCenterId             UTF8String (SIZE(1..12)),
+    parkingC2CLinkStatusInfo    SEQUENCE OF ParkingStaionC2FLinkStatusInfo
+}
+ParkingStaionC2FLinkStatusInfo ::= SEQUENCE
+{
+    parking-station-id          UTF8String,
+    parking-station-link-status ENUMERATED
+    {
+        offline (0),
+        online  (1)
+    }
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CLinkStatusInfoList ::= SEQUENCE
+{
+    parkingCenterId             UTF8String (SIZE(1..12)),
+    parkingC2CLinkStatusInfo    SEQUENCE OF ParkingStaionC2FLinkStatusInfo
+}
+ParkingStaionC2FLinkStatusInfo ::= SEQUENCE
+{
+    parking-station-id          UTF8String,
+    parking-station-link-status ENUMERATED
+    {
+        offline (0),
+        online  (1)
+    }
+}
+
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+-- [ITSK-00090_2016v2]_주차정보 수집·연계 및 제공을 위한 정보교환 표준.pdf
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+ParkingC2FStaticInfo ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-ParkName-txt   UTF8String (SIZE(1..40)),
+    pkfc-ParkAddress    SEQUENCE
+    {
+        sido-name       UTF8String (SIZE(1..16)) OPTIONAL,
+        gugun-name      UTF8String (SIZE(1..16)) OPTIONAL,
+        eupmyon-name    UTF8String (SIZE(1..16)) OPTIONAL,
+        road-name       UTF8String (SIZE(1..16)) OPTIONAL,
+        bldg-num        UTF8String (SIZE(1..16)) OPTIONAL,
+        dongho-name     UTF8String (SIZE(1..16)) OPTIONAL,
+        addr-text       UTF8String (SIZE(1..32)) OPTIONAL
+    },
+    pkfc-ParkLocation SEQUENCE OF ParkingLocationInfo,
+    pkfc-Divide-Code ENUMERATED
+    {
+        div-public,
+        div-private
+    },
+    pkfc-Type-Code ENUMERATED
+    {
+        type-street,
+        type-offsteet,
+        type-affiliate
+    },
+    pkfc-PatkUsing-Code BIT STRING
+    {
+        self-parking        (0),
+        mechanical-parking  (1),
+        others              (2)
+    },
+    pkfc-ParkingLand-Level ENUMERATED
+    {
+        level1,
+        level2,
+        level3,
+        level4
+    },
+    pkfc-ParkingLots-total INTEGER (0..65535),
+    pkfc-ParkingLots-floor ParkingLotsFloorList OPTIONAL,
+    pkfc-ParkingLots-typed ParkingLotsTypedList OPTIONAL,
+    pkfc-GraphicObjectData SEQUENCE
+    {
+    graphic-Type ENUMERATED
+    {
+        bitmap,
+        gif,
+        jpg,
+        png,
+        other 
+    },
+    graphic-Data            OCTET STRING,
+    graphic-AdditionalText  UTF8String (SIZE(1..50)) OPTIONAL
+    }
+}
+TypedParkingLots ::= SEQUENCE
+{
+    parking-lots-type ENUMERATED
+    {
+        lots-for-genenal, 
+        lots-for-small-car,
+        lots-for-freight-car,
+        lots-for-emergency-car,
+        lots-for-handicapped,
+        lots-for-women,
+        lots-for-others,
+        ... 
+    },
+    parking-lots-num INTEGER (0..65535)
+}
+ParkingLocationInfo ::= SEQUENCE
+{
+    entranceName-txt    UTF8String (SIZE(1..40)) OPTIONAL,
+    coordinate          GlobalCoordinate
+}
+FloorParkingLots ::= SEQUENCE
+{
+    floor-number        UTF8String (SIZE(1..10)),
+    floor-section       UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-parkinglots   INTEGER (0..65535)
+}
+--------------------------------------------------------------------------------------------
+-- 주1) 층 번호(floor-number) : 지상층(1F, 2F, 3F...), 지하층(B1, B2, B3 ...)
+-- 주2) 구역일련번호(floor-section) : 대규모 주차장이 한 개의 층을 구획으로 나누어 구분 할 경우
+-- 주3) other : graphic-Data의 이미지 파일 헤더를 통해 이미지 Type을 구분
+--------------------------------------------------------------------------------------------
+ParkingC2FOperateInfo ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-Operator-Info  SEQUENCE 
+    {
+        operator-name   UTF8String (SIZE(1..20)) OPTIONAL,
+        operator-num    UTF8String (SIZE(1..20))
+    } OPTIONAL,
+    pkfc-Restrict-Code  ENUMERATED 
+    {
+        restrict-none,
+        the-2-day-rotation-system,
+        the-5-day-rotation-system,
+        the-10-day-rotation-system,
+        no-driving-on-a-day-system,
+        restrict-others
+    } OPTIONAL,
+    pkfc-OperateDay-Code BIT STRING 
+    {
+        saturday    (0),
+        sunday      (1),
+        holyday     (2)
+    } OPTIONAL,
+    pkfc-Operate-Time SEQUENCE
+    {
+        weekday-open    DailyTimeStamp OPTIONAL,
+        weekday-close   DailyTimeStamp OPTIONAL,
+        sat-open        DailyTimeStamp OPTIONAL,
+        sat-close       DailyTimeStamp OPTIONAL,
+        holiday-open    DailyTimeStamp OPTIONAL,
+        holiday-close   DailyTimeStamp OPTIONAL
+    },
+    pkfc-FreeOpen-Code ENUMERATED 
+    {
+        no-free-open,
+        free-after-close
+    } OPTIONAL,
+    pkfc-Charge-Code ENUMERATED 
+    {
+        charge-free,
+        charge,
+        complex
+    },
+    pkfc-Pay-Type BIT STRING
+    {
+        pay-cash                (1),
+        pay-creditCard          (2),
+        pay-transportaionCard   (3),
+        pay-mobilePay           (4),
+        pay-etc1                (5),
+        pay-etc2                (6),
+        pay-etc3                (7),
+        pay-etc4                (8)
+    },
+    pkfc-FreeCharge-BaseTime    INTEGER (0..99999) OPTIONAL,
+    pkfc-Parking-Rate           SEQUENCE
+    {
+        base-time           INTEGER (0..1440),
+        base-rate           INTEGER (0..99999),
+        additional-time     INTEGER (0..1440) OPTIONAL,
+        additional-rate     INTEGER (0..99999) OPTIONAL,
+        daily-apply-time    INTEGER (0..99999) OPTIONAL,
+        a-daily-rate        INTEGER (0..99999) OPTIONAL,
+        monthly-rate        INTEGER (0..999999) OPTIONAL
+    } OPTIONAL,
+    pkfc-Holliday-Rate SEQUENCE
+    {
+        holiday-base-time       INTEGER (0..1440) OPTIONAL,
+        holiday-base-rate       INTEGER (0..99999) OPTIONAL,
+        holiday-additional-time INTEGER (0..1440) OPTIONAL,
+        holiday-additional-rate INTEGER (0..99999) OPTIONAL,
+        holiday-a-daily-rate    INTEGER (0..99999) OPTIONAL
+    } OPTIONAL,
+    pkfc-Extra-Rate SEQUENCE
+    {
+        extra-base-time         INTEGER (0..99999),
+        extra-additional-time   INTEGER (0..99999),
+        extra-additional-rate   INTEGER (0..99999)
+    } OPTIONAL,
+    pkfc-Discount-Rates             EQUENCE OF ParkingDiscountRate OPTIONAL,
+    pkfc-ReservationService-Code    ENUMERATED
+    {
+        reservation-service,
+        reservation-non-service
+    },
+    pkfc-Parking-additional UTF8String (SIZE(1..256)) OPTIONAL
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FRealtimeInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time                 GeneralizedTime,
+    pkfc-AvailableParkingLots-total     INTEGER (0..65535),
+    pkfc-AvailableParkingLots-floor     ParkingLotsFloorList OPTIONAL,
+    pkfc-AvailableParkingLots-typed     ParkingLotsTypedList OPTIONAL,
+    pkfc-AvailableReservation-Quantity  INTEGER (0..65535) OPTIONAL
+}
+ParkingLotsFloor ::= SEQUENCE
+{
+    floor-number        UTF8String (SIZE(1..10)),
+    floor-section       UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-parkinglots   INTEGER (0..65535)
+}
+ParkingLotsTyped ::= SEQUENCE
+{
+    parking-lots-type ENUMERATED
+    {
+        lots-for-genenal, 
+        lots-for-small-car,
+        lots-for-freight-car,
+        lots-for-emergency-car,
+        lots-for-handicapped,
+        lots-for-women,
+        lots-for-others,
+        ... 
+    },
+    parking-lots-num INTEGER (0..65535)
+}
+ParkingLotsTypedList ::= SEQUENCE OF ParkingLotsTyped
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationRequest ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time     GeneralizedTime,
+    pkfc-Reservation-Code   CHOICE
+    {
+        reservation-new     ReservationData,
+        reservation-update  ReservationUpdate,
+        reservation-cancel  ReservationUpdate,
+        reservation-query   ReservationQuery
+    }
+}
+ReservationData ::= SEQUENCE
+{
+    reservation-pin-code    UTF8String (SIZE(4..16)),
+    reservation-plate-num   UTF8String (SIZE(1..20)),
+    reservation-contact-num UTF8String (SIZE(1..16)),
+    reservation-time        GeneralizedTime
+}
+ReservationUpdate ::= SEQUENCE
+{
+    reservation-id                  UTF8String (SIZE(1..64)),
+    reservation-pin-code            UTF8String (SIZE(4..16)),
+    reservation-pin-code-change     UTF8String (SIZE(4..16)) OPTIONAL,
+    reservation-plate-num-change    UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-contact-num-change  UTF8String (SIZE(1..16)) OPTIONAL,
+    reservation-time-change         GeneralizedTime OPTIONAL
+}
+ReservationQuery ::= SEQUENCE
+{
+    reservation-plate-num   UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-contact-num UTF8String (SIZE(1..16)) OPTIONAL,
+    reservation-time        GeneralizedTime OPTIONAL,
+    reservation-id          UTF8String (SIZE(1..64)) OPTIONAL
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationResult ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time     GeneralizedTime,
+    pkfc-Reservation-Result CHOICE
+    {
+        reservationNew-success          ReservationResult,
+        reservationUpdate-success       NULL,
+        reservationCancel-success       NULL,
+        reservationQuery                SEQUENCE OF ReservationResult,
+        reservationReject-Reason-txt    UTF8String (SIZE(1..256))
+    }
+}
+ReservationResult ::= SEQUENCE
+{
+    reservation-id          UTF8String (SIZE(1..64)),
+    reservation-plate-num   UTF8String (SIZE(1..20)),
+    reservation-contact-num UTF8String (SIZE(1..16)),
+    reservation-time        GeneralizedTime
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FIncidentInfoList ::= SEQUENCE OF ParkingC2FIncidentInfo
+ParkingC2FIncidentInfo ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time     GeneralizedTime,
+    pkfc-Incident-Number    UTF8String (SIZE(1..20)), 
+    pkfc-IncidentInfoType   CHOICE 
+    {
+        incidentOccurence   UTF8String (SIZE(1..256)),
+        incidentStatus      UTF8String (SIZE(1..256)),
+        incidentEnd         NULL
+    }
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FVehicleLocationRequest ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-Plate-Number   UTF8String (SIZE(1..20))
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FVehicleLocationResponse ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-Plate-Number   UTF8String (SIZE(1..20)), 
+    userLocation        UTF8String (SIZE(1..256))
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CStaticInfoList ::= SEQUENCE OF ParkingC2CStaticInfo
+ParkingC2CStaticInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FStaticInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2COperateInfoList ::= SEQUENCE OF ParkingC2COperateInfo
+ParkingC2COperateInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FOperateInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+ParkingC2CRealtimeInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FRealtimeInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+ParkingC2CRealtimeInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FRealtimeInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CReservationRequestList ::= SEQUENCE OF ParkingC2CReservationRequest
+ParkingC2CReservationRequest ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FReservationRequest
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CReservationResultList ::= SEQUENCE OF ParkingC2CReservationResult
+ParkingC2CReservationResult ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FReservationResult
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CIncidentInfoList ::= SEQUENCE OF ParkingC2CIncidentInfo
+ParkingC2CIncidentInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FIncidentInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CIncidentInfoList ::= SEQUENCE OF ParkingC2CIncidentInfo
+ParkingC2CIncidentInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FIncidentInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CLinkStatusInfoList ::= SEQUENCE OF ParkingC2CLinkStatusInfo
+ParkingC2CLinkStatusInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-status  ENUMERATED
+    {
+        online,
+        offline
+    }
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CLinkStatusInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-status  ENUMERATED
+    {
+        online,
+        offline
+    }
+}
+--------------------------------------------------------------------------------------------
+
+END

+ 457 - 0
src/main/resources/static/js/utils/Parking-2016v2.asn

@@ -0,0 +1,457 @@
+PARKING DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+-- [ITSK-00090_2016v2]_주차정보 수집·연계 및 제공을 위한 정보교환 표준.pdf
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+ParkingC2FStaticInfo ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-ParkName-txt   UTF8String (SIZE(1..40)),
+    pkfc-ParkAddress    SEQUENCE
+    {
+        sido-name       UTF8String (SIZE(1..16)) OPTIONAL,
+        gugun-name      UTF8String (SIZE(1..16)) OPTIONAL,
+        eupmyon-name    UTF8String (SIZE(1..16)) OPTIONAL,
+        road-name       UTF8String (SIZE(1..16)) OPTIONAL,
+        bldg-num        UTF8String (SIZE(1..16)) OPTIONAL,
+        dongho-name     UTF8String (SIZE(1..16)) OPTIONAL,
+        addr-text       UTF8String (SIZE(1..32)) OPTIONAL
+    },
+    pkfc-ParkLocation SEQUENCE OF ParkingLocationInfo,
+    pkfc-Divide-Code ENUMERATED
+    {
+        div-public,
+        div-private
+    },
+    pkfc-Type-Code ENUMERATED
+    {
+        type-street,
+        type-offsteet,
+        type-affiliate
+    },
+    pkfc-PatkUsing-Code BIT STRING
+    {
+        self-parking        (0),
+        mechanical-parking  (1),
+        others              (2)
+    },
+    pkfc-ParkingLand-Level ENUMERATED
+    {
+        level1,
+        level2,
+        level3,
+        level4
+    },
+    pkfc-ParkingLots-total INTEGER (0..65535),
+    pkfc-ParkingLots-floor ParkingLotsFloorList OPTIONAL,
+    pkfc-ParkingLots-typed ParkingLotsTypedList OPTIONAL,
+    pkfc-GraphicObjectData SEQUENCE
+    {
+    graphic-Type ENUMERATED
+    {
+        bitmap,
+        gif,
+        jpg,
+        png,
+        other 
+    },
+    graphic-Data            OCTET STRING,
+    graphic-AdditionalText  UTF8String (SIZE(1..50)) OPTIONAL
+    }
+}
+TypedParkingLots ::= SEQUENCE
+{
+    parking-lots-type ENUMERATED
+    {
+        lots-for-genenal, 
+        lots-for-small-car,
+        lots-for-freight-car,
+        lots-for-emergency-car,
+        lots-for-handicapped,
+        lots-for-women,
+        lots-for-others,
+        ... 
+    },
+    parking-lots-num INTEGER (0..65535)
+}
+ParkingLocationInfo ::= SEQUENCE
+{
+    entranceName-txt    UTF8String (SIZE(1..40)) OPTIONAL,
+    coordinate          GlobalCoordinate
+}
+FloorParkingLots ::= SEQUENCE
+{
+    floor-number        UTF8String (SIZE(1..10)),
+    floor-section       UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-parkinglots   INTEGER (0..65535)
+}
+--------------------------------------------------------------------------------------------
+-- 주1) 층 번호(floor-number) : 지상층(1F, 2F, 3F...), 지하층(B1, B2, B3 ...)
+-- 주2) 구역일련번호(floor-section) : 대규모 주차장이 한 개의 층을 구획으로 나누어 구분 할 경우
+-- 주3) other : graphic-Data의 이미지 파일 헤더를 통해 이미지 Type을 구분
+--------------------------------------------------------------------------------------------
+ParkingC2FOperateInfo ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-Operator-Info  SEQUENCE 
+    {
+        operator-name   UTF8String (SIZE(1..20)) OPTIONAL,
+        operator-num    UTF8String (SIZE(1..20))
+    } OPTIONAL,
+    pkfc-Restrict-Code  ENUMERATED 
+    {
+        restrict-none,
+        the-2-day-rotation-system,
+        the-5-day-rotation-system,
+        the-10-day-rotation-system,
+        no-driving-on-a-day-system,
+        restrict-others
+    } OPTIONAL,
+    pkfc-OperateDay-Code BIT STRING 
+    {
+        saturday    (0),
+        sunday      (1),
+        holyday     (2)
+    } OPTIONAL,
+    pkfc-Operate-Time SEQUENCE
+    {
+        weekday-open    DailyTimeStamp OPTIONAL,
+        weekday-close   DailyTimeStamp OPTIONAL,
+        sat-open        DailyTimeStamp OPTIONAL,
+        sat-close       DailyTimeStamp OPTIONAL,
+        holiday-open    DailyTimeStamp OPTIONAL,
+        holiday-close   DailyTimeStamp OPTIONAL
+    },
+    pkfc-FreeOpen-Code ENUMERATED 
+    {
+        no-free-open,
+        free-after-close
+    } OPTIONAL,
+    pkfc-Charge-Code ENUMERATED 
+    {
+        charge-free,
+        charge,
+        complex
+    },
+    pkfc-Pay-Type BIT STRING
+    {
+        pay-cash                (1),
+        pay-creditCard          (2),
+        pay-transportaionCard   (3),
+        pay-mobilePay           (4),
+        pay-etc1                (5),
+        pay-etc2                (6),
+        pay-etc3                (7),
+        pay-etc4                (8)
+    },
+    pkfc-FreeCharge-BaseTime    INTEGER (0..99999) OPTIONAL,
+    pkfc-Parking-Rate           SEQUENCE
+    {
+        base-time           INTEGER (0..1440),
+        base-rate           INTEGER (0..99999),
+        additional-time     INTEGER (0..1440) OPTIONAL,
+        additional-rate     INTEGER (0..99999) OPTIONAL,
+        daily-apply-time    INTEGER (0..99999) OPTIONAL,
+        a-daily-rate        INTEGER (0..99999) OPTIONAL,
+        monthly-rate        INTEGER (0..999999) OPTIONAL
+    } OPTIONAL,
+    pkfc-Holliday-Rate SEQUENCE
+    {
+        holiday-base-time       INTEGER (0..1440) OPTIONAL,
+        holiday-base-rate       INTEGER (0..99999) OPTIONAL,
+        holiday-additional-time INTEGER (0..1440) OPTIONAL,
+        holiday-additional-rate INTEGER (0..99999) OPTIONAL,
+        holiday-a-daily-rate    INTEGER (0..99999) OPTIONAL
+    } OPTIONAL,
+    pkfc-Extra-Rate SEQUENCE
+    {
+        extra-base-time         INTEGER (0..99999),
+        extra-additional-time   INTEGER (0..99999),
+        extra-additional-rate   INTEGER (0..99999)
+    } OPTIONAL,
+    pkfc-Discount-Rates             SEQUENCE OF ParkingDiscountRate OPTIONAL,
+    pkfc-ReservationService-Code    ENUMERATED
+    {
+        reservation-service,
+        reservation-non-service
+    },
+    pkfc-Parking-additional UTF8String (SIZE(1..256)) OPTIONAL
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FRealtimeInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time                 GeneralizedTime,
+    pkfc-AvailableParkingLots-total     INTEGER (0..65535),
+    pkfc-AvailableParkingLots-floor     ParkingLotsFloorList OPTIONAL,
+    pkfc-AvailableParkingLots-typed     ParkingLotsTypedList OPTIONAL,
+    pkfc-AvailableReservation-Quantity  INTEGER (0..65535) OPTIONAL
+}
+ParkingLotsFloor ::= SEQUENCE
+{
+    floor-number        UTF8String (SIZE(1..10)),
+    floor-section       UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-parkinglots   INTEGER (0..65535)
+}
+ParkingLotsTyped ::= SEQUENCE
+{
+    parking-lots-type ENUMERATED
+    {
+        lots-for-genenal, 
+        lots-for-small-car,
+        lots-for-freight-car,
+        lots-for-emergency-car,
+        lots-for-handicapped,
+        lots-for-women,
+        lots-for-others,
+        ... 
+    },
+    parking-lots-num INTEGER (0..65535)
+}
+ParkingLotsTypedList ::= SEQUENCE OF ParkingLotsTyped
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationRequest ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time     GeneralizedTime,
+    pkfc-Reservation-Code   CHOICE
+    {
+        reservation-new     ReservationData,
+        reservation-update  ReservationUpdate,
+        reservation-cancel  ReservationUpdate,
+        reservation-query   ReservationQuery
+    }
+}
+ReservationData ::= SEQUENCE
+{
+    reservation-pin-code    UTF8String (SIZE(4..16)),
+    reservation-plate-num   UTF8String (SIZE(1..20)),
+    reservation-contact-num UTF8String (SIZE(1..16)),
+    reservation-time        GeneralizedTime
+}
+ReservationUpdate ::= SEQUENCE
+{
+    reservation-id                  UTF8String (SIZE(1..64)),
+    reservation-pin-code            UTF8String (SIZE(4..16)),
+    reservation-pin-code-change     UTF8String (SIZE(4..16)) OPTIONAL,
+    reservation-plate-num-change    UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-contact-num-change  UTF8String (SIZE(1..16)) OPTIONAL,
+    reservation-time-change         GeneralizedTime OPTIONAL
+}
+ReservationQuery ::= SEQUENCE
+{
+    reservation-plate-num   UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-contact-num UTF8String (SIZE(1..16)) OPTIONAL,
+    reservation-time        GeneralizedTime OPTIONAL,
+    reservation-id          UTF8String (SIZE(1..64)) OPTIONAL
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationResult ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time     GeneralizedTime,
+    pkfc-Reservation-Result CHOICE
+    {
+        reservationNew-success          ReservationResult,
+        reservationUpdate-success       NULL,
+        reservationCancel-success       NULL,
+        reservationQuery                SEQUENCE OF ReservationResult,
+        reservationReject-Reason-txt    UTF8String (SIZE(1..256))
+    }
+}
+ReservationResult ::= SEQUENCE
+{
+    reservation-id          UTF8String (SIZE(1..64)),
+    reservation-plate-num   UTF8String (SIZE(1..20)),
+    reservation-contact-num UTF8String (SIZE(1..16)),
+    reservation-time        GeneralizedTime
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FIncidentInfoList ::= SEQUENCE OF ParkingC2FIncidentInfo
+ParkingC2FIncidentInfo ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time     GeneralizedTime,
+    pkfc-Incident-Number    UTF8String (SIZE(1..20)), 
+    pkfc-IncidentInfoType   CHOICE 
+    {
+        incidentOccurence   UTF8String (SIZE(1..256)),
+        incidentStatus      UTF8String (SIZE(1..256)),
+        incidentEnd         NULL
+    }
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FVehicleLocationRequest ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-Plate-Number   UTF8String (SIZE(1..20))
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FVehicleLocationResponse ::= SEQUENCE 
+{
+    pkfc-MsgCreate-Time GeneralizedTime,
+    pkfc-Plate-Number   UTF8String (SIZE(1..20)), 
+    userLocation        UTF8String (SIZE(1..256))
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CStaticInfoList ::= SEQUENCE OF ParkingC2CStaticInfo
+ParkingC2CStaticInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FStaticInfo
+}
+--------------------------------------------------------------------------------------------
+ParkingC2COperateInfoList ::= SEQUENCE OF ParkingC2COperateInfo
+ParkingC2COperateInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FOperateInfo
+}
+--------------------------------------------------------------------------------------------
+-- 2.2.6. 관리주차장 실시간 주차정보 응답
+ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+ParkingC2CRealtimeInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FRealtimeInfo
+}
+--------------------------------------------------------------------------------------------
+-- 2.2.7. 관리주차장 실시간 주차정보 갱신
+-- ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+-- ParkingC2CRealtimeInfo ::= SEQUENCE
+-- {
+--     parking-station-id      UTF8String,
+--     parking-station-info    ParkingC2FRealtimeInfo
+-- }
+--------------------------------------------------------------------------------------------
+ParkingC2CReservationRequestList ::= SEQUENCE OF ParkingC2CReservationRequest
+ParkingC2CReservationRequest ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FReservationRequest
+}
+--------------------------------------------------------------------------------------------
+ParkingC2CReservationResultList ::= SEQUENCE OF ParkingC2CReservationResult
+ParkingC2CReservationResult ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FReservationResult
+}
+--------------------------------------------------------------------------------------------
+-- 2.2.11. 관리주차장 돌발정보 응답
+ParkingC2CIncidentInfoList ::= SEQUENCE OF ParkingC2CIncidentInfo
+ParkingC2CIncidentInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-info    ParkingC2FIncidentInfo
+}
+--------------------------------------------------------------------------------------------
+-- 2.2.12. 관리주차장 돌발정보 갱신
+-- ParkingC2CIncidentInfoList ::= SEQUENCE OF ParkingC2CIncidentInfo
+-- ParkingC2CIncidentInfo ::= SEQUENCE
+-- {
+--     parking-station-id      UTF8String,
+--     parking-station-info    ParkingC2FIncidentInfo
+-- }
+--------------------------------------------------------------------------------------------
+-- 2.2.14. 관리주차장 연결상태정보 응답
+ParkingC2CLinkStatusInfoList ::= SEQUENCE OF ParkingC2CLinkStatusInfo
+ParkingC2CLinkStatusInfo ::= SEQUENCE
+{
+    parking-station-id      UTF8String,
+    parking-station-status  ENUMERATED
+    {
+        online,
+        offline
+    }
+}
+--------------------------------------------------------------------------------------------
+-- 2.2.15. 관리주차장 연결상태정보 갱신
+-- ParkingC2CLinkStatusInfo ::= SEQUENCE
+-- {
+--     parking-station-id      UTF8String,
+--     parking-station-status  ENUMERATED
+--     {
+--         online,
+--         offline
+--     }
+-- }
+--------------------------------------------------------------------------------------------
+-- 문서에는 없어서 다른 문서에서 찾아 신규로 생성함
+--------------------------------------------------------------------------------------------
+ParkingDiscountRate  ::= SEQUENCE
+{
+    small-car                       INTEGER(0..100),
+    handicapped                     INTEGER(0..100),
+    driving-system-car              INTEGER(0..100),
+    emergency-car                   INTEGER(0..100),
+    a-man-of-merit                  INTEGER(0..100),
+    earnest-taxpayer                INTEGER(0..100),
+    excellent-volunteer-car         INTEGER(0..100),
+    self-carfree-participation-car  INTEGER(0..100),
+    transit-car                     INTEGER(0..100),
+    official-car                    INTEGER(0..100),
+    defoliation-aftereffect-car     INTEGER(0..100),
+    military-faithful-family-car    INTEGER(0..100),
+    low-emission-car                INTEGER(0..100),
+    rescue-efforts-certificate-car  INTEGER(0..100),
+    multi-child-car                 INTEGER(0..100),
+    for-others                      INTEGER(0..100)
+}
+DailyTimeStamp ::= SEQUENCE
+{
+    hour    INTEGER(0..23),
+    min     INTEGER(0..59),
+    sec     INTEGER(0..59)
+}
+ParkingLotsFloorList ::= SEQUENCE
+{
+    floor-number                UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-number-parkinglots    INTEGER(0..65535) OPTIONAL,
+    floor-section               UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-section-parkinglots   INTEGER(0..65535) OPTIONAL
+}
+--NMEACoord ::= SEQUENCE
+GlobalCoordinate ::= SEQUENCE
+{
+    latitude SEQUENCE
+    {
+        integerValue INTEGER,
+        fractionValue INTEGER,
+        fracSize INTEGER(0..10),
+        compass ENUMERATED
+        {
+            north,
+            south
+        }
+    },
+    longitude SEQUENCE
+    {
+        integerValue INTEGER,
+        fractionValue INTEGER,
+        fracSize INTEGER(0..10),
+        compass ENUMERATED
+        {
+            east,
+            west
+        }
+    },
+    optData OCTET STRING OPTIONAL
+}
+
+-- ASN1STEP: List of valid unreferenced and/or user-defined PDU numbers and associated PDU names:
+--        1  TypedParkingLots
+--        2  FloorParkingLots
+--        3  ParkingLotsFloor
+--        4  ParkingC2FIncidentInfoList
+--        5  ParkingC2FVehicleLocationRequest
+--        6  ParkingC2FVehicleLocationResponse
+--        7  ParkingC2CStaticInfoList
+--        8  ParkingC2COperateInfoList
+--        9  ParkingC2CRealtimeInfoList
+--       10  ParkingC2CReservationRequestList
+--       11  ParkingC2CReservationResultList
+--       12  ParkingC2CIncidentInfoList
+--       13  ParkingC2CLinkStatusInfoList
+-- =========================================================================================
+
+END

+ 700 - 0
src/main/resources/static/js/utils/Parking-2021v3.asn

@@ -0,0 +1,700 @@
+PARKING DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+-- [ITSK-00090_2021v3]_실시간 주차정보 수집·연계·제공 규격.pdf
+--------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------
+ParkingC2FStaticInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time                 UTF8String (SIZE(1..14)),
+    parking-station-id                  UTF8String (SIZE(1..22)),
+    pkfc-parkingC2FStaticinfo-Version   INTEGER(0..65535),
+    pkfc-ParkName-txt                   UTF8String (SIZE(1..40)),
+    pkfc-ParkAddress                    SEQUENCE
+    {
+        sido-name       UTF8String (SIZE(1..16)),
+        gugun-name      UTF8String (SIZE(1..16)),
+        eupmyon-name    UTF8String (SIZE(1..16)) OPTIONAL,
+        road-name       UTF8String (SIZE(1..16)),
+        bldg-num        UTF8String (SIZE(1..16)) OPTIONAL,
+        dongho-name     UTF8String (SIZE(1..16)) OPTIONAL,
+        addr-text       UTF8String (SIZE(1..32)) OPTIONAL
+    },
+    pkfc-Installation-Date  UTF8String (SIZE(1..8)),
+    pkfc-Abolition-Date     UTF8String (SIZE(1..8)) OPTIONAL,
+    pkfc-ParkLocation       SEQUENCE OF ParkingLocationInfo,
+    pkfc-Gateway-Code       ENUMERATED
+    {
+        gw-share    (0),
+        gw-division (1),
+        gw-ETC      (9)
+    },
+    pkfc-Type-Code ENUMERATED
+    {
+        type-parallel           (0),
+        type-rightangled        (1),
+        type-60degreesforward   (2),
+        type-45degreesforward   (3),
+        type-ETC                (9)
+    },
+    pkfc-ParkUsing-Code BIT STRING
+    {
+        self-parking        (0),
+        mechanical-parking  (1),
+        others              (2)
+    },
+    pkfc-ParkingLand-Level ENUMERATED
+    {
+        level1  (0),
+        level2  (1),
+        level3  (2),
+        level4  (3),
+        level5  (4),
+        etc     (9)
+    },
+    pkfc-GraphicObjectData SEQUENCE
+    {
+        graphic-Type ENUMERATED
+        {
+            bitmap  (0),
+            gif     (1),
+            jpg     (2), 
+            png     (3), 
+            other   (4)
+        },
+        graphic-Data            OCTET STRING,
+        graphic-AdditionalText  UTF8String (SIZE(1..50)) OPTIONAL
+    },
+    pkfc-SystemName-txt                 UTF8String (SIZE(1..40)),
+    pkfc-SystemInstallation-Date        UTF8String (SIZE(1..8)) OPTIONAL,
+    pkfc-RelationLaw                    UTF8String (SIZE(1..50)) OPTIONAL,
+    pkfc-ParkingLots-available-cartype  ENUMERATED
+    {
+        compact-car     (0),
+        midsize-car     (1),
+        full-sized-car  (2),
+        suv             (3),
+        van             (4),
+        truck           (5)
+--------------------------------------------------------------------------------------------
+--      SUV             (3),
+--      VAN             (4),
+--      Truck           (5)
+--------------------------------------------------------------------------------------------
+   } OPTIONAL,
+    pkfc-ParkingLots-total  INTEGER(0..65535),
+    pkfc-ParkingLots-floor  SEQUENCE OF FloorParkingLots OPTIONAL,
+    pkfc-ParkingLots-type   SEQUENCE OF TypedParkingLots OPTIONAL,
+    pkfc-CollectionDevice   ENUMERATED
+    {
+        unInstallation  (0),
+        installation    (1)
+    },
+    pkfc-Controller-quantity SEQUENCE OF ControllerQty OPTIONAL,
+    pkfc-CollectionDevice-total INTEGER(0..65535) OPTIONAL,
+    pkfc-CollectionDevice-Type ENUMERATED
+    {
+        type-image          (0),
+        type-geomagnetic    (1),
+        type-radar          (2),
+        type-loop           (3),
+        type-ultrasonic     (4),
+        type-etc            (9)
+    } OPTIONAL,
+    pkfc-CollectionDevice-quantity          SEQUENCE OF CollectionDeviceQty OPTIONAL,
+    pkfc-CollectionDeviceInstallation-Date  UTF8String (SIZE(1..8)) OPTIONAL,
+    pkfc-CCTV-installation ENUMERATED
+    {
+        unInstallation  (0),
+        installation    (1)
+    } OPTIONAL,
+    pkfc-CCTV-quantity INTEGER (0..65535) OPTIONAL
+}
+
+ParkingLocationInfo ::= SEQUENCE
+{
+    entranceName-txt    UTF8String (SIZE(1..40)),
+    coordinate          NMEACoord
+}
+
+NMEACoord ::= SEQUENCE
+{
+    latitude SEQUENCE
+    {
+        integerValue INTEGER,
+        fractionValue INTEGER,
+        fracSize INTEGER(0..10),
+        compass ENUMERATED
+        {
+            north,
+            south
+        }
+    },
+    longitude SEQUENCE
+    {
+        integerValue INTEGER,
+        fractionValue INTEGER,
+        fracSize INTEGER(0..10),
+        compass ENUMERATED
+        {
+            east,
+            west
+        }
+    },
+    optData OCTET STRING OPTIONAL
+}
+FloorParkingLots ::= SEQUENCE
+{
+    floor-number                UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-number-parkinglots    INTEGER(0..65535) OPTIONAL,
+    floor-section               UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-section-parkinglots   INTEGER(0..65535) OPTIONAL
+}
+TypedParkingLots ::= SEQUENCE
+{
+    lots-for-general        INTEGER(0..65535) OPTIONAL,
+    lots-for-small-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-freight-car    INTEGER(0..65535) OPTIONAL,
+    lots-for-emergency-car  INTEGER(0..65535) OPTIONAL,
+    lots-for-handicapped    INTEGER(0..65535) OPTIONAL,
+    lots-for-women          INTEGER(0..65535) OPTIONAL,
+    lots-for-others         INTEGER(0..65535) OPTIONAL
+}
+ControllerQty ::= SEQUENCE
+{
+    contoller-master    INTEGER(0..65535) OPTIONAL,
+    contoller-slave     INTEGER(0..65535) OPTIONAL
+}
+CollectionDeviceQty ::= SEQUENCE
+{
+    qty-image       INTEGER(0..65535) OPTIONAL,
+    qty-geomagnetic INTEGER(0..65535) OPTIONAL,
+    qty-radar       INTEGER(0..65535) OPTIONAL,
+    qty-loop        INTEGER(0..65535) OPTIONAL,
+    qty-ultrasonic  INTEGER(0..65535) OPTIONAL,
+    qty-etc         INTEGER(0..65535) OPTIONAL
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2CStaticInfoList ::= SEQUENCE OF ParkingC2CStaticInfo
+ParkingC2CStaticInfo ::= SEQUENCE
+{
+    parking-station-id          UTF8String (SIZE(1..22)),
+    parking-station-static-info ParkingC2FStaticInfo
+}
+--------------------------------------------------------------------------------------------
+
+ParkingC2FOperateInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time                 UTF8String (SIZE(1..14)),
+    parking-station-id                  UTF8String (SIZE(1..22)),
+    pkfc-parkingC2FOperateinfo-Version  INTEGER(0..65535),
+    pkfc-Operate-Name                   UTF8String (SIZE(1..20)),
+    pkfc-Operate-Department             UTF8String (SIZE(1..20)) OPTIONAL,
+    pkfc-Operate-Contact                SEQUENCE
+    {
+        pkfc-Operate-person     UTF8String (SIZE(1..20)) OPTIONAL,
+        pkfc-Operate-telephone  UTF8String (SIZE(1..20)),
+        pkfc-Operate-email      UTF8String (SIZE(1..40)) OPTIONAL
+    },
+    pkfc-Restrict-Code ENUMERATED
+    {
+        the-2-day-rotation-system   (0),
+        the-5-day-rotation-system   (1),
+        the-10-day-rotation-system  (2),
+        no-driving-on-a-day-system  (3),
+        restrict-others             (4),
+        restrict-none               (5)
+    },
+    pkfc-Operation-Schedule ParkingOperationSchedule,
+    pkfc-FreeOpen-Code ENUMERATED
+    {
+        no-free-open        (0),
+        free-after-close    (1)
+    } OPTIONAL,
+    pkfc-Charge-Method ENUMERATED
+    {
+        manned      (0),
+        unmanned    (1),
+        mixed       (2),
+        etc         (9)
+    } OPTIONAL,
+    pkfc-Charge-Code ENUMERATED
+    {
+        charge-free (0),
+        charge      (1),
+        complex     (2)
+    },
+    pkfc-Pay-Type BIT STRING
+    {
+        pay-cash                (0),
+        pay-creditCard          (1),
+        pay-transportaionCard   (2),
+        pay-HipassCard          (3),
+        pay-mobilePay           (4),
+        pay-FinTech             (5),
+        pay-MaaS                (6),
+        pay-etc1                (7),
+        pay-etc2                (8),
+        pay-etc3                (9)
+    },
+    pkfc-FreeCharge-BaseTime INTEGER(0..99999) OPTIONAL,
+    pkfc-Parking-Rate SEQUENCE
+    {
+        base-time       INTEGER(0..1440),
+        base-rate       INTEGER(0..99999),
+        additional-time INTEGER(0..1440),
+        additional-rate INTEGER(0..99999)
+    },
+    pkfc-Parking-FlatRate SEQUENCE
+    {
+        daily-apply-time    INTEGER(0..99999),
+        a-daily-rate        INTEGER(0..99999),
+        monthly-rate        INTEGER(0..999999)
+    } OPTIONAL,
+    pkfc-Holiday-Rate SEQUENCE
+    {
+        holiday-base-time       INTEGER(0..1440),
+        holiday-base-rate       INTEGER(0..99999),
+        holiday-additional-time INTEGER(0..1440),
+        holiday-additional-rate INTEGER(0..999999),
+        holiday-a-daily-rate    INTEGER(0..999999)
+    } OPTIONAL,
+    pkfc-Extra-Rate SEQUENCE
+    {
+        extra-base-time         INTEGER(0..99999),
+        extra-additional-time   INTEGER(0..99999),
+        extra-additional-rate   INTEGER(0..999999)
+    } OPTIONAL,
+    pkfc-Discount-Rates SEQUENCE
+    {
+        small-car                       INTEGER(0..100),
+        handicapped                     INTEGER(0..100),
+        driving-system-car              INTEGER(0..100),
+        emergency-car                   INTEGER(0..100),
+        a-man-of-merit                  INTEGER(0..100),
+        earnest-taxpayer                INTEGER(0..100),
+        excellent-volunteer-car         INTEGER(0..100),
+        self-carfree-participation-car  INTEGER(0..100),
+        transit-car                     INTEGER(0..100),
+        official-car                    INTEGER(0..100),
+        defoliation-aftereffect-car     INTEGER(0..100),
+        military-faithful-family-car    INTEGER(0..100),
+        low-emission-car                INTEGER(0..100),
+        rescue-efforts-certificate-car  INTEGER(0..100),
+        multi-child-car                 INTEGER(0..100),
+        for-others                      INTEGER(0..100)
+    } OPTIONAL,
+    pkfc-ReservationService-Code ENUMERATED
+    {
+        reservation-none    (0),
+        parkinglot          (1),
+        parkingarea         (2),
+        parkingspace        (3)
+    },
+    pkfc-Parking-additional UTF8String (SIZE(1..256)) OPTIONAL
+}
+
+DailyTimeStamp ::= SEQUENCE
+{
+    hour    INTEGER(0..23),
+    min     INTEGER(0..59),
+    sec     INTEGER(0..59)
+}
+
+ParkingOperationSchedule ::= SEQUENCE
+{
+    sunday      ParkingOperationInfo,
+    monday      ParkingOperationInfo,
+    tuesday     ParkingOperationInfo,
+    wednesday   ParkingOperationInfo,
+    thursday    ParkingOperationInfo,
+    friday      ParkingOperationInfo,
+    saturday    ParkingOperationInfo,
+    holiday     ParkingOperationInfo
+}
+
+ParkingOperationInfo ::= CHOICE
+{
+    operational     ParkingOperationData,
+    not-operational NULL
+}
+
+ParkingOperationData ::= SEQUENCE
+{
+    open-time   DailyTimeStamp,
+    close-time  DailyTimeStamp,
+    charging    ParkingOperationCharge
+}
+
+ParkingOperationCharge ::= ENUMERATED
+{
+    charge-free (0),
+    charge      (1),
+    complex     (2)
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2COperateInfoList ::= SEQUENCE OF ParkingC2COperateInfo
+ParkingC2COperateInfo ::= SEQUENCE
+{
+    parking-station-id              UTF8String (SIZE(1..22)),
+    parking-station-operate-info    ParkingC2FOperateInfo
+}
+--------------------------------------------------------------------------------------------
+
+ParkingspaceF2DRealTimeInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time UTF8String (SIZE(1..14)) OPTIONAL,
+    pkfc-CollectionDevice-information SEQUENCE
+    {
+        device-id INTEGER(0..65535) OPTIONAL,
+        devicetype ENUMERATED
+        {
+            type-image (0),
+            type-geomagnetic (1),
+            type-radar (2),
+            type-loop (3),
+            type-ultrasonic (4),
+            type-etc (9)
+        } OPTIONAL,
+
+        parkingspace-id INTEGER(0..65535) OPTIONAL,
+
+        typedparkinglots ENUMERATED
+        {
+            lots-for-general (0),
+            lots-for-small-car (1),
+            lots-for-freight-car (2),
+            lots-for-emergency-car (3),
+            lots-for-handicapped (4),
+            lots-for-women (5),
+            lots-for-others (6)
+            -- lots-for-others (6), 
+            -- …
+        } OPTIONAL,
+
+        parkingspaceoccupation ENUMERATED
+        {
+            possible (0),
+            impossible (1)
+        } OPTIONAL,
+
+        connection ENUMERATED
+        {
+            abnormal (0),
+            normal (1)
+        } OPTIONAL
+    }
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2FRealTimeInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time         UTF8String (SIZE(1..14)),
+    pkfc-DataCollection-Time    UTF8String (SIZE(1..14)),
+    parking-station-id          UTF8String (SIZE(1..22)),
+    pkfc-Congestiont-Status ENUMERATED
+    {
+        available   (0),
+        normal      (1),
+        delay       (2),
+        full        (3)
+    } OPTIONAL,
+    pkfc-Parkingspace-Realtime-info     ParkingspaceF2DRealTimeInfo,
+    pkfc-ParkingLots-total              INTEGER(0..65535),
+    pkfc-AvailableParkingLots-total     INTEGER(0..65535),
+    pkfc-ParkingLots-floor              SEQUENCE OF FloorParkingLots OPTIONAL,
+    pkfc-AvailableParkingLots-floor     ParkingLotsFloorList OPTIONAL,
+    pkfc-ParkingLots-typed              ParkingLotsTypedList OPTIONAL,
+    pkfc-AvailableParkingLots-typed     ParkingLotsTypedList OPTIONAL,
+    pkfc-AvailableReservation-Quantity  INTEGER(0..65535) OPTIONAL,
+    pkfc-Parking-additional             UTF8String (SIZE(1..256)) OPTIONAL
+}
+
+ParkingLotsFloorList ::= SEQUENCE
+{
+    floor-number                UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-number-parkinglots    INTEGER(0..65535) OPTIONAL,
+    floor-section               UTF8String (SIZE(1..10)) OPTIONAL,
+    floor-section-parkinglots   INTEGER(0..65535) OPTIONAL
+}
+
+ParkingLotsTypedList ::= SEQUENCE
+{
+    lots-for-general        INTEGER(0..65535) OPTIONAL,
+    lots-for-green-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-small-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-freight-car    INTEGER(0..65535) OPTIONAL,
+    lots-for-emergency-car  INTEGER(0..65535) OPTIONAL,
+    lots-for-handicapped    INTEGER(0..65535) OPTIONAL,
+    lots-for-elder-car      INTEGER(0..65535) OPTIONAL,
+    lots-for-women          INTEGER(0..65535) OPTIONAL,
+    lots-for-others         INTEGER(0..65535) OPTIONAL
+}
+
+--------------------------------------------------------------------------------------------
+-- 1.3.3.2. 관리주차장 실시간 정보 응답
+ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+ParkingC2CRealtimeInfo ::= SEQUENCE
+{
+    parking-station-id              UTF8String (SIZE(1..22)),
+    parking-station-realtime-info   ParkingC2FRealTimeInfo
+}
+
+--------------------------------------------------------------------------------------------
+-- 1.3.3.3. 관리주차장 실시간 정보 갱신
+-- ParkingC2CRealtimeInfoList ::= SEQUENCE OF ParkingC2CRealtimeInfo
+-- ParkingC2CRealtimeInfo ::= SEQUENCE
+-- {
+--     parking-station-id              UTF8String (SIZE(1..22)),
+--     parking-station-realtime-info   ParkingC2FRealTimeInfo
+-- }
+
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationRequestInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time     UTF8String (SIZE(1..14)),
+    parking-station-id      UTF8String (SIZE(1..22)),
+    pkfc-Parking-additional UTF8String (SIZE(1..256)) OPTIONAL,
+    pkfc-Reservation-Code CHOICE
+    {
+        reservation-new     ReservationData,
+        reservation-update  ReservationUpdate,
+        reservation-cancel  ReservationUpdate
+    }
+}
+
+ReservationData ::= SEQUENCE
+{
+pkfc-resve-in-no            UTF8String (SIZE(1..32)),
+pkfc-resve-customer-info    SEQUENCE
+{
+    reservation-plate-num   UTF8String (SIZE(1..10)),
+    reservation-car-type    ENUMERATED
+    {
+--------------------------------------------------------------------------------------------
+--      general(compact,mid)    (0),
+--      general(large)          (1),
+--------------------------------------------------------------------------------------------
+        general-compact-mid     (0),
+        general-large           (1),
+--------------------------------------------------------------------------------------------
+        small-car               (2),
+        green-car               (3),
+        handicapped             (4),
+        van                     (5),
+--------------------------------------------------------------------------------------------
+--      freight-car(mid)        (6),
+--      freight-car(large)      (7),
+--------------------------------------------------------------------------------------------
+        freight-car-mid         (6),
+        freight-car-large       (7),
+--------------------------------------------------------------------------------------------
+        others                  (8)
+    } OPTIONAL,
+    reservation-contact-name    UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-contact-email   UTF8String (SIZE(1..40)),
+    reservation-contact-num     UTF8String (SIZE(1..20)) OPTIONAL,
+    reservation-in-time         UTF8String (SIZE(1..14)),
+    reservation-out-time        UTF8String (SIZE(1..14)) OPTIONAL
+    }
+}
+
+ReservationUpdate ::= SEQUENCE
+{
+    pkfc-resve-in-no            UTF8String (SIZE(1..32)),
+    pkfc-resve-customer-info    SEQUENCE
+    {
+        reservation-plate-num-change    UTF8String (SIZE(1..10)) OPTIONAL,
+        reservation-car-type-change     ENUMERATED
+        {
+--------------------------------------------------------------------------------------------
+--          general(compact,mid)    (0),
+--          general(large)          (1),
+--------------------------------------------------------------------------------------------
+            general-compact-mid     (0),
+            general-large           (1),
+--------------------------------------------------------------------------------------------
+            small-car               (2),
+            green-car               (3),
+            handicapped             (4),
+            van                     (5),
+--------------------------------------------------------------------------------------------
+--         freight-car(mid)        (6),
+--         freight-car(large)      (7),
+--------------------------------------------------------------------------------------------
+            freight-car-mid         (6),
+            freight-car-large       (7),
+--------------------------------------------------------------------------------------------
+            others                  (8)
+        } OPTIONAL,
+        reservation-contact-name-change UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-contact-email       UTF8String (SIZE(1..40)) OPTIONAL,
+        reservation-contact-num-change  UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-in-time-change      UTF8String (SIZE(1..14)) OPTIONAL,
+        reservation-out-time-change     UTF8String (SIZE(1..14)) OPTIONAL
+    }
+}
+
+--------------------------------------------------------------------------------------------
+ParkingC2FReservationResultInfo ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time             UTF8String (SIZE(1..14)),
+    parking-station-id              UTF8String (SIZE(1..22)),
+    pkfc-Reservation-parkingspace   UTF8String (SIZE(1..20)) OPTIONAL,
+    pkfc-Reservation-Result         CHOICE
+    {
+        reservationNew-success          ReservationResult,
+        reservationUpdate-success       NULL,
+        reservationCancel-success       NULL,
+    ---------------------------------------------------------------------------------------
+    -- 문서에서 괄호 및 , 누락
+    ---------------------------------------------------------------------------------------
+        reservationReject-Reason-txt    UTF8String (SIZE(1..256))
+    },
+    ---------------------------------------------------------------------------------------
+    pkfc-Reservation-complete-Result    ENUMERATED
+    {
+        complete        (0),
+        cancellation    (1)
+    }
+}
+
+ReservationResult ::= SEQUENCE
+{
+    pkfc-resve-in-no            UTF8String (SIZE(1..32)),
+    pkfc-resve-customer-info    SEQUENCE
+    {
+        reservation-plate-num   UTF8String (SIZE(1..10)),
+        reservation-car-type    ENUMERATED
+        {
+--------------------------------------------------------------------------------------------
+--          general(compact,mid)    (0),
+--          general(large)          (1),
+--------------------------------------------------------------------------------------------
+            general-compact-mid     (0),
+            general-large           (1),
+--------------------------------------------------------------------------------------------
+            small-car               (2),
+            green-car               (3),
+            handicapped             (4),
+            van                     (5),
+--------------------------------------------------------------------------------------------
+--          freight-car(mid)        (6),
+--          freight-car(large)      (7),
+--------------------------------------------------------------------------------------------
+            freight-car-mid         (6),
+            freight-car-large       (7),
+--------------------------------------------------------------------------------------------
+            others                  (8)
+        } OPTIONAL,
+        reservation-contact-name    UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-contact-email   UTF8String (SIZE(1..40)),
+        reservation-contact-num     UTF8String (SIZE(1..20)) OPTIONAL,
+        reservation-in-time         UTF8String (SIZE(1..14)),
+        reservation-out-time        UTF8String (SIZE(1..14)) OPTIONAL
+    }
+}
+--------------------------------------------------------------------------------------------
+-- 1.4.2.1. 관리주차장 예약 요청
+ParkingC2CReservationRequestInfoList ::= SEQUENCE OF ParkingC2CReservationRequestInfo
+ParkingC2CReservationRequestInfo ::= SEQUENCE
+{
+    parking-station-id                          UTF8String (SIZE(1..22)),
+    parking-station-reservation-request-info    ParkingC2FReservationRequestInfo
+}
+--------------------------------------------------------------------------------------------
+-- 1.4.2.2. 관리주차장 예약 응답
+ParkingC2CReservationResultInfoList ::= SEQUENCE OF ParkingC2CReservationResultInfo
+ParkingC2CReservationResultInfo ::= SEQUENCE
+{
+    parking-station-id                      UTF8String (SIZE(1..22)),
+    parking-station-reservation-result-info ParkingC2FReservationResultInfo
+}
+--------------------------------------------------------------------------------------------
+-- 1.5.1.1. 이용자 차량 위치정보 요청(통합시스템 → 개별시스템)
+-- PakingC2FVehicleLocationInfoRequest ::= SEQUENCE
+ParkingC2FVehicleLocationInfoRequest ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time UTF8String (SIZE(1..14)),
+    parking-station-id  UTF8String (SIZE(1..22)),
+    pkfc-Plate-Number   UTF8String (SIZE(1..20))
+}
+--------------------------------------------------------------------------------------------
+ParkingC2FVehicleLocationInfoResult ::= SEQUENCE
+{
+    pkfc-MsgCreate-Time UTF8String (SIZE(1..14)),
+    parking-station-id  UTF8String (SIZE(1..22)),
+    pkfc-Plate-Number   UTF8String (SIZE(1..20)),
+    pkfc-userLocation   UserLocation
+}
+UserLocation ::= SEQUENCE
+{
+    floor-number    UTF8String (SIZE(1..10)),
+    floor-section   UTF8String (SIZE(1..10))
+}
+--------------------------------------------------------------------------------------------
+-- 1.5.2.1. 관리주차장 이용자 차량 위치 정보 요청
+ParkingC2CVehicleLocationInfoRequestList ::= SEQUENCE OF ParkingC2CVehicleLocationInfoRequest
+ParkingC2CVehicleLocationInfoRequest ::= SEQUENCE
+{
+    parking-station-id                              UTF8String (SIZE(1..22)),
+    parking-station-vehiclelocation-request-info    ParkingC2FVehicleLocationInfoRequest
+}
+--------------------------------------------------------------------------------------------
+-- 1.5.2.2. 관리주차장 이용자 차량 위치 정보 응답
+-- 1.4.2.2. 관리주차장 예약 응답 과 동일함.
+-- ParkingC2CReservationResultInfoList ::= SEQUENCE OF ParkingC2CReservationResultInfo
+-- ParkingC2CReservationResultInfo ::= SEQUENCE
+-- {
+--     parking-station-id                          UTF8String (SIZE(1..22)),
+--     parking-station-vehiclelocation-result-info ParkingC2FVehicleLocationInfoResult
+-- }
+--------------------------------------------------------------------------------------------
+-- 1.6.1.2. 관리주차장 연결 상태 정보 응답
+ParkingC2CLinkStatusInfoList ::= SEQUENCE
+{
+    parkingCenterId             UTF8String (SIZE(1..12)),
+    parkingC2CLinkStatusInfo    SEQUENCE OF ParkingStaionC2FLinkStatusInfo
+}
+ParkingStaionC2FLinkStatusInfo ::= SEQUENCE
+{
+    parking-station-id          UTF8String,
+    parking-station-link-status ENUMERATED
+    {
+        offline (0),
+        online  (1)
+    }
+}
+--------------------------------------------------------------------------------------------
+-- 1.6.1.3. 관리주차장 연결 상태 정보 갱신
+-- ParkingC2CLinkStatusInfoList ::= SEQUENCE
+-- {
+--     parkingCenterId             UTF8String (SIZE(1..12)),
+--     parkingC2CLinkStatusInfo    SEQUENCE OF ParkingStaionC2FLinkStatusInfo
+-- }
+-- ParkingStaionC2FLinkStatusInfo ::= SEQUENCE
+-- {
+--     parking-station-id          UTF8String,
+--     parking-station-link-status ENUMERATED
+--     {
+--         offline (0),
+--         online  (1)
+--     }
+-- }
+
+-- ASN1STEP: List of valid unreferenced and/or user-defined PDU numbers and associated PDU names:
+--        1  ParkingC2CStaticInfoList
+--        2  ParkingC2COperateInfoList
+--        3  ParkingC2CRealtimeInfoList
+--        4  ParkingC2CReservationRequestInfoList
+--        5  ParkingC2CReservationResultInfoList
+--        6  ParkingC2FVehicleLocationInfoResult
+--        7  ParkingC2CVehicleLocationInfoRequestList
+--        8  ParkingC2CLinkStatusInfoList
+-- =========================================================================================
+
+END

+ 180 - 0
src/main/resources/static/login.css

@@ -0,0 +1,180 @@
+body,
+html {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+    background: white;
+    min-width: 1920px;
+}
+.fa-lock:before {
+    content: "\f023";
+}
+.fa-unlock-alt:before {
+    content: "\f13e";
+}
+.flex-container {
+    position: relative;
+    display: flex;
+    justify-content: center;
+    background: white;
+    align-items: center;
+    justify-items: center;
+    min-height: 100vh;
+}
+
+.flex-container > form {
+    position: relative;
+    display: flex;
+    justify-content: center;
+    align-items: flex-end;
+    height: 398px;
+    border: 1px solid #eeeeee;
+    background: url(./loginPage.png);
+    background-size: 900px;
+    background-repeat: no-repeat;
+    box-shadow: 4px 4px 3px 3px #eeeeee;
+    background-repeat: no-repeat;
+    flex-direction: column;
+    width: 900px;
+}
+
+.title-line {
+    position: relative;
+    right: 32px;
+    height: 100px;
+    line-height: 100px;
+    color: #06068f;
+    font-size: 30px;
+    font-weight: bold;
+}
+/*.under-line{
+	position: relative;
+	width: 566px;
+	height: 1px;
+	border-bottom: 1px solid #d3d3d3;
+	right: 94px;
+}
+*/
+.under-line {
+    position: relative;
+    width: 494px;
+    height: 1px;
+    border-bottom: 1px solid #d3d3d3;
+    right: 29px;
+}
+
+/* .logoImage{
+	background-image: url("/image/MainLogo.png");
+	background-repeat:  no-repeat;
+	width: 216px;
+    height: 80px;
+    position: absolute;
+    right: 819px;
+    top: 200px;
+} */
+
+.logoImage {
+    background-image: url(./MainLogo.png);
+    background-repeat: no-repeat;
+    width: 216px;
+    height: 80px;
+    position: absolute;
+    right: 578px;
+    top: 137px;
+    background-size: 200px 65px;
+}
+/* 
+.input-box{
+	position: relative;
+	width: 577px;
+	right: 84px;
+	text-align: center;
+	top: 50px;
+}
+ */
+.input-box {
+    position: relative;
+    width: 526px;
+    right: -3px;
+    text-align: center;
+    top: 50px;
+}
+/* .input-box > div:nth-child(1){
+	position: relative;
+	width: 450px;
+	height: 50px;
+	line-height: 50px;
+	float: left;
+	font-weight: bold;
+	text-align: left;
+} */
+
+.input-box > div:nth-child(1) {
+    position: relative;
+    width: 381px;
+    height: 50px;
+    line-height: 50px;
+    float: left;
+    font-weight: bold;
+    text-align: left;
+}
+
+.input-box > div:nth-child(3) {
+    position: relative;
+    float: left;
+    width: 100px;
+    height: 90px;
+    left: 10px;
+    font-weight: bold;
+    top: -45px;
+    font-size: 20px;
+    color: white;
+    background: #1e65c5;
+    line-height: 83px;
+    border: 1px solid #1e65c5;
+    border-radius: 5px;
+}
+.input-box > div:nth-child(3):hover {
+    cursor: pointer;
+}
+.input-box > div:nth-child(3) > span {
+    height: 27px;
+    position: absolute;
+    top: 23px;
+    left: 11px;
+}
+
+/* .input-box > div:nth-child(2) {
+	position: relative;
+	float: left;
+	width: 450px;
+	height: 50px;
+	line-height: 50px;
+	text-align: left;
+	font-weight: bold;
+} */
+
+.input-box > div:nth-child(2) {
+    position: relative;
+    float: left;
+    width: 381px;
+    height: 50px;
+    line-height: 50px;
+    text-align: left;
+    font-weight: bold;
+}
+
+.input-box > div:nth-child(1) > input {
+    position: relative;
+    left: 20px;
+    width: 298px;
+    height: 30px;
+}
+
+.input-box > div:nth-child(2) > input {
+    position: relative;
+    left: 5px;
+    width: 298px;
+    height: 30px;
+}

+ 37 - 0
src/main/resources/static/login.html

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="UTF-8" />
+        <title>Log-In</title>
+        <!-- <script src="https://kit.fontawesome.com/c818c46fe5.js" crossorigin="anonymous"></script> -->
+        <link rel="stylesheet" href="./font-awesome.min.css" />
+        <script src="/libs/jquery/jquery-3.6.0.min.js"></script>
+        <link rel="stylesheet" href="./login.css" />
+        <script type="text/javascript" src="./login.js"></script>
+    </head>
+    <body>
+        <div class="flex-container">
+            <form action="/login.do" method="POST">
+                <span class="logoImage"></span>
+                <div class="title-line">용인시 ITS 통합운영단말 로그인</div>
+                <div class="under-line"></div>
+                <div class="input-box">
+                    <div>
+                        아이디
+                        <input type="text" name="user_id" />
+                    </div>
+                    <div>
+                        비밀번호
+                        <input type="password" name="pwd" />
+                    </div>
+                    <div>
+                        <i class="fa fa-lock" style="position: relative; font-size: 40px" aria-hidden="true"></i>
+                        <i class="fa fa-unlock-alt" style="position: relative; top: 15px; font-size: 40px; display: none" aria-hidden="true"></i>
+                        <span>들어가기</span>
+                    </div>
+                    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
+                </div>
+            </form>
+        </div>
+    </body>
+</html>

+ 60 - 0
src/main/resources/static/login.js

@@ -0,0 +1,60 @@
+$(function () {
+    const id = $("input[name = 'user_id']");
+    const pwd = $("input[name = 'pwd']");
+    const logBtn = $(".input-box > div:nth-child(3)");
+    function init() {
+        logBtn.on("click", () => {
+            loginCheck();
+        });
+
+        id.on("keydown", (e) => {
+            if (e.key === "Enter") {
+                loginCheck();
+            }
+        });
+
+        pwd.on("keydown", (e) => {
+            if (e.key === "Enter") {
+                loginCheck();
+            }
+        });
+
+        logBtn.on("mouseenter", () => {
+            $(".input-box > div:nth-child(3)> i:nth-child(1)").css("display", "none");
+            $(".input-box > div:nth-child(3)> i:nth-child(2)").css("display", "block");
+            logBtn.css({
+                background: "#124c9b",
+                border: "1px solid #124c9b",
+            });
+        });
+        logBtn.on("mouseleave", () => {
+            $(".input-box > div:nth-child(3)> i:nth-child(1)").css({ display: "block", top: "15px" });
+            $(".input-box > div:nth-child(3)> i:nth-child(2)").css("display", "none");
+            logBtn.css({
+                background: "#1e65c5",
+                border: "1px solid #1e65c5",
+            });
+        });
+    }
+
+    init();
+
+    function nullChecker(checkItem) {
+        return checkItem || null;
+    }
+    function loginCheck() {
+        let idVal = $.trim(id.val());
+        let pwdVal = $.trim(pwd.val());
+        if (!nullChecker(idVal)) {
+            alert("id를 입력해주세요");
+            id.focus();
+            return false;
+        }
+        if (!nullChecker(pwdVal)) {
+            alert("비밀번호를 입력해주세요");
+            pwd.focus();
+            return false;
+        }
+        $("form").submit();
+    }
+});

二进制
src/main/resources/static/loginPage.png