diff --git a/adm/admin.head.php b/adm/admin.head.php index 90b07d8d7..9c35b557c 100644 --- a/adm/admin.head.php +++ b/adm/admin.head.php @@ -3,9 +3,23 @@ if (!defined('_GNUBOARD_')) exit; $begin_time = get_microtime(); +$files = glob(G5_ADMIN_PATH.'/css/admin_extend_*'); +if (is_array($files)) { + foreach ((array) $files as $k=>$css_file) { + + $fileinfo = pathinfo($css_file); + $ext = $fileinfo['extension']; + + if( $ext !== 'css' ) continue; + + $css_file = str_replace(G5_ADMIN_PATH, G5_ADMIN_URL, $css_file); + add_stylesheet('', $k); + } +} + include_once(G5_PATH.'/head.sub.php'); -function print_menu1($key, $no) +function print_menu1($key, $no='') { global $menu; @@ -14,11 +28,11 @@ function print_menu1($key, $no) return $str; } -function print_menu2($key, $no) +function print_menu2($key, $no='') { - global $menu, $auth_menu, $is_admin, $auth, $g5; + global $menu, $auth_menu, $is_admin, $auth, $g5, $sub_menu; - $str .= " -
- - +
+ + + 이모티콘 추가
diff --git a/adm/sms_admin/history_list.php b/adm/sms_admin/history_list.php index bf6d1afd0..d3edc13e9 100644 --- a/adm/sms_admin/history_list.php +++ b/adm/sms_admin/history_list.php @@ -72,8 +72,8 @@ include_once(G5_ADMIN_PATH.'/admin.head.php'); ?> - - + + 예약":'';?> @@ -81,8 +81,8 @@ include_once(G5_ADMIN_PATH.'/admin.head.php'); - - 수정 + + 수정 diff --git a/adm/sms_admin/history_num.php b/adm/sms_admin/history_num.php index a2de1b2b3..78af3f36e 100644 --- a/adm/sms_admin/history_num.php +++ b/adm/sms_admin/history_num.php @@ -1,5 +1,5 @@ 예약":'';?> - - - 수정 + + + 수정 diff --git a/adm/sms_admin/history_view.php b/adm/sms_admin/history_view.php index c745b7058..2fd9d1b0c 100644 --- a/adm/sms_admin/history_view.php +++ b/adm/sms_admin/history_view.php @@ -84,12 +84,12 @@ function all_send()
- 전송건수 - 성공건수 - 실패건수 - 전송일시 - 예약일시 - 회신번호 + 전송건수 + 성공건수 + 실패건수 + 전송일시 + 예약일시 + 회신번호

전송내용

@@ -101,7 +101,7 @@ function all_send()

전송실패 문자 재전송 내역

-
+
@@ -133,8 +133,8 @@ function all_send() - @@ -230,16 +230,16 @@ function all_send() - - diff --git a/adm/sms_admin/member_update.php b/adm/sms_admin/member_update.php index 667919971..cf90a404e 100644 --- a/adm/sms_admin/member_update.php +++ b/adm/sms_admin/member_update.php @@ -26,8 +26,8 @@ include_once(G5_ADMIN_PATH.'/admin.head.php');
-
- +
+
diff --git a/adm/sms_admin/num_book.php b/adm/sms_admin/num_book.php index 39c1182e8..7bf189d2c 100644 --- a/adm/sms_admin/num_book.php +++ b/adm/sms_admin/num_book.php @@ -99,12 +99,12 @@ function no_hp_click(val)
- 회원정보 최근 업데이트 - 총 건수 - 회원 - 비회원 - 수신 - 거부 + 업데이트 + 건수 + 회원 + 비회원 + 수신 + 거부
@@ -133,9 +133,7 @@ function no_hp_click(val) - + @@ -191,23 +189,23 @@ function no_hp_click(val) -
- 수정 + + 수정
+ 결과코드 :
로그 :
메모 :
+ - 내역 + 내역 - 내역 + 내역
수신' : '거부'?> - 수정 - 보내기 - 내역 + + 수정 + 보내기 + 내역
- -
- - - - - +
+ + + + + + 번호추가
+
+ 건수 +
+
+
- -
-
- 건수 : +
+
@@ -131,7 +134,7 @@ function num_group_submit(f) - 보기 + 보기 @@ -166,7 +169,7 @@ function num_group_submit(f) - 보기 + 보기 @@ -174,10 +177,10 @@ function num_group_submit(f)
-
- - - +
+ + +
diff --git a/adm/sms_admin/sms_write.php b/adm/sms_admin/sms_write.php index 1016f1d5e..4654a3a6d 100644 --- a/adm/sms_admin/sms_write.php +++ b/adm/sms_admin/sms_write.php @@ -125,10 +125,10 @@ if ($config['cf_sms_use'] == 'icode') { // 아이코드 사용
- -
- - + +
+ +
@@ -182,9 +182,9 @@ if ($config['cf_sms_use'] == 'icode') { // 아이코드 사용

휴대폰번호 목록

diff --git a/adm/theme.php b/adm/theme.php index 57d4862f0..32eb294eb 100644 --- a/adm/theme.php +++ b/adm/theme.php @@ -26,8 +26,10 @@ include_once('./admin.head.php'); ?> +
+ 설치된 테마 -

설치된 테마 :

+
0) { ?>
    diff --git a/adm/theme_detail.php b/adm/theme_detail.php index 61d897acb..a0018f707 100644 --- a/adm/theme_detail.php +++ b/adm/theme_detail.php @@ -35,9 +35,10 @@ if($info['license_uri']) { ?>
    -
    -
    -

    +

    +
    +
    +

    @@ -52,8 +53,10 @@ if($info['license_uri']) {
    Version
    -

    +
    + 미리보기 +
    diff --git a/adm/thumbnail_file_delete.php b/adm/thumbnail_file_delete.php index 3b5ea0bd5..47f40c918 100644 --- a/adm/thumbnail_file_delete.php +++ b/adm/thumbnail_file_delete.php @@ -19,6 +19,10 @@ include_once('./admin.head.php'); $directory = array(); $dl = array('file', 'editor'); +if( defined('G5_YOUNGCART_VER') ){ + $dl[] = 'item'; +} + foreach($dl as $val) { if($handle = opendir(G5_DATA_PATH.'/'.$val)) { while(false !== ($entry = readdir($handle))) { diff --git a/adm/visit.sub.php b/adm/visit.sub.php index def2df342..742e8e7ae 100644 --- a/adm/visit.sub.php +++ b/adm/visit.sub.php @@ -12,7 +12,7 @@ $qstr = "fr_date=".$fr_date."&to_date=".$to_date; $query_string = $qstr ? '?'.$qstr : ''; ?> -
    +
    기간별검색 diff --git a/adm/visit_browser.php b/adm/visit_browser.php index aca685012..15cc0c297 100644 --- a/adm/visit_browser.php +++ b/adm/visit_browser.php @@ -78,7 +78,7 @@ while ($row=sql_fetch_array($result)) {
    - + diff --git a/adm/visit_date.php b/adm/visit_date.php index 29aab179e..967f4e8e9 100644 --- a/adm/visit_date.php +++ b/adm/visit_date.php @@ -66,7 +66,7 @@ for ($i=0; $row=sql_fetch_array($result); $i++) {
    - + diff --git a/adm/visit_delete.php b/adm/visit_delete.php index 20811f647..99fe62e49 100644 --- a/adm/visit_delete.php +++ b/adm/visit_delete.php @@ -19,7 +19,7 @@ $now_year = (int)substr(G5_TIME_YMD, 0, 4); 접속자 로그를 삭제할 년도와 방법을 선택해주십시오.
- +
-
+
diff --git a/adm/visit_device.php b/adm/visit_device.php index 76aaffd39..df2362bcd 100644 --- a/adm/visit_device.php +++ b/adm/visit_device.php @@ -82,7 +82,7 @@ while ($row=sql_fetch_array($result)) {
- + diff --git a/adm/visit_domain.php b/adm/visit_domain.php index da7d2db55..348a87c63 100644 --- a/adm/visit_domain.php +++ b/adm/visit_domain.php @@ -86,7 +86,7 @@ while ($row=sql_fetch_array($result)) {
- + %">
- + %">
- + diff --git a/adm/visit_os.php b/adm/visit_os.php index 5e6c86022..183604ab5 100644 --- a/adm/visit_os.php +++ b/adm/visit_os.php @@ -82,7 +82,7 @@ while ($row=sql_fetch_array($result)) {
- + diff --git a/adm/visit_search.php b/adm/visit_search.php index cf61a8611..67e0f9188 100644 --- a/adm/visit_search.php +++ b/adm/visit_search.php @@ -104,7 +104,7 @@ $listall = '처음'; //페이지 처 ?> - + ' : ''; ?> diff --git a/adm/visit_week.php b/adm/visit_week.php index 1842feed8..5ebccac2d 100644 --- a/adm/visit_week.php +++ b/adm/visit_week.php @@ -62,7 +62,7 @@ for ($i=0; $row=sql_fetch_array($result); $i++) {
- + diff --git a/adm/visit_year.php b/adm/visit_year.php index 4bd0f0d9f..1d42e1512 100644 --- a/adm/visit_year.php +++ b/adm/visit_year.php @@ -67,7 +67,7 @@ for ($i=0; $row=sql_fetch_array($result); $i++) { - + diff --git a/adm/write_count.php b/adm/write_count.php index ddcab74bc..6729e6fd8 100644 --- a/adm/write_count.php +++ b/adm/write_count.php @@ -129,7 +129,7 @@ switch ($day) {
+
+ + +
+ -
+

+ 경로는 그누보드5 설치 루트를 기준으로 그누보드4의 config.php 파일의 상대경로입니다.
+ 예를 들어 그누보드4를 웹루트에 설치하셨고 그누보드5를 g5라는 하위 폴더에 설치하셨다면 입력하실 경로는 ../config.php 입니다. +

- -
- - -
- - -
-
- -
-
-
- -
-

- 이 프로그램은 그누보드5 설치 후 바로 실행하셔야만 합니다.
- 만약 그누보드5 사이트를 운영 중에 이 프로그램을 실행하시면 DB 데이터가 망실되거나 데이터의 오류가 발생할 수 있습니다.
- 또한 중복해서 실행하실 경우에도 DB 데이터의 오류가 발생할 수 있으니 반드시 한번만 실행해 주십시오. -

-

프로그램을 실행하시려면 그누보드4의 config.php 파일 경로를 입력하신 후 확인을 클릭해 주십시오.

- -
- -
- - - -
-
- -

- 경로는 그누보드5 설치 루트를 기준으로 그누보드4의 config.php 파일의 상대경로입니다.
- 예를 들어 그누보드4를 웹루트에 설치하셨고 그누보드5를 g5라는 하위 폴더에 설치하셨다면 입력하실 경로는 ../config.php 입니다. -

- -
- - - -
-
- - - -
- - -
-
<?php echo G5_VERSION ?>
-
-

- Copyright © 소유하신 도메인. All rights reserved.
- 상단으로 -

-
\ No newline at end of file diff --git a/g4_import_run.php b/g4_import_run.php index fa101017f..259832777 100644 --- a/g4_import_run.php +++ b/g4_import_run.php @@ -3,17 +3,9 @@ include_once('./_common.php'); ob_end_clean(); -include_once(G5_LIB_PATH.'/connect.lib.php'); -include_once(G5_LIB_PATH.'/outlogin.lib.php'); - set_time_limit ( 0 ); ini_set('memory_limit', '50M'); -$g5['title'] = '그누보드4 DB 데이터 이전'; -include_once(G5_PATH.'/'.G5_THEME_DIR.'/basic/head.sub.php'); - -echo ''; - if(empty($_POST)) alert('올바른 방법으로 이용해 주십시오.', G5_URL); @@ -41,6 +33,9 @@ if(!is_file($g4_config_file)) alert('입력하신 경로에 config.php 파일이 존재하지 않습니다.'); $is_euckr = false; + +$g5['title'] = '그누보드4 DB 데이터 이전'; +include_once(G5_PATH.'/head.php'); ?> - + } - + $sql_common .= $comma . " $key = '".addslashes($val)."' "; -
- - - - -
- + $comma = ','; + } -
+ sql_query(" INSERT INTO {$g5['board_table']} SET $sql_common "); - + // 게시판 테이블 생성 + $bo_table = $row['bo_table']; + $file = file(G5_ADMIN_PATH.'/sql_write.sql'); + $sql = implode($file, "\n"); + + $create_table = $g5['write_prefix'] . $bo_table; + + $source = array('/__TABLE_NAME__/', '/;/'); + $target = array($create_table, ''); + $sql = preg_replace($source, $target, $sql); + + // 게시글 복사 + if(sql_query($sql, FALSE)) { + $write_table = $g4['write_prefix'].$bo_table; + $columns2 = sql_field_names($create_table); + + $sql3 = " select * from $write_table "; + $result3 = sql_query($sql3); + + for($k=0; $row3=sql_fetch_array($result3); $k++) { + if($is_euckr) + $row3 = array_map('iconv_utf8', $row3); + + $comma3 = ''; + $sql_common3 = ''; + + foreach($row3 as $key=>$val) { + if(!in_array($key, $columns2)) + continue; + + $sql_common3 .= $comma3 . " $key = '".addslashes($val)."' "; + + $comma3 = ','; + } + + // 첨부파일개수 + $wr_id = $row3['wr_id']; + $sql4 = " select count(*) as cnt from {$g4['board_file_table']} where bo_table = '$bo_table' and wr_id = '$wr_id' "; + $row4 = sql_fetch($sql4); + + $sql_common3 .= " , wr_file = '{$row4['cnt']}' "; + + sql_query(" INSERT INTO $create_table SET $sql_common3 "); + } + + echo '
  • '.str_replace(G5_TABLE_PREFIX.'write_', '', $create_table).' 게시글 복사
  • '; + } +} + +unset($columns); +unset($fiels); + +// 그외 테이블 복사 +$tables = array('board_file', 'board_new', 'board_good', 'mail', 'memo', 'group_member', 'auth', 'popular', 'poll', 'poll_etc', 'scrap'); + +foreach($tables as $table) { + $columns = sql_field_names($g5[$table.'_table']); + + $src_table = $g4[$table.'_table']; + $dst_table = $g5[$table.'_table']; + $sql = " select * from $src_table "; + $result = sql_query($sql); + for($i=0; $row=sql_fetch_array($result); $i++) { + if($is_euckr) + $row = array_map('iconv_utf8', $row); + + $comma = ''; + $sql_common = ''; + + foreach($row as $key=>$val) { + if(!in_array($key, $columns)) + continue; + + $sql_common .= $comma . " $key = '".addslashes($val)."' "; + + $comma = ','; + } + + $result2 = sql_query(" INSERT INTO $dst_table SET $sql_common ", false); + + if(!$result2) + continue; + } + + echo '
  • '.$table.' table 복사
  • '.PHP_EOL; +} + +unset($columns); +unset($fiels); + +echo ''.PHP_EOL; + +echo '
    그누보드4 DB 데이터 이전 완료
    '.PHP_EOL; + +// 실행완료 세션에 기록 +set_session('tables_copied', 'done'); +?> - - -
    - - -
    -
    - -
    -
    -
    - -
    -
      - $val) { - if($key == 'mb_no') - continue; - - if(!in_array($key, $columns)) - continue; - - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - sql_query(" INSERT INTO {$g5['member_table']} SET $sql_common "); - } - - echo '
    1. member table 복사
    2. '.PHP_EOL; - unset($columns); - unset($fiels); - - // point table 복사 - $sql = " select * from {$g4['point_table']} "; - $result = sql_query($sql); - for($i=0; $row=sql_fetch_array($result); $i++) { - if($is_euckr) - $row = array_map('iconv_utf8', $row); - - $comma = ''; - $sql_common = ''; - - foreach($row as $key=>$val) { - if($key == 'po_id') - continue; - - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - sql_query(" INSERT INTO {$g5['point_table']} SET $sql_common "); - } - echo '
    3. point table 복사
    4. '.PHP_EOL; - - // login table 복사 - $sql = " select * from {$g4['login_table']} "; - $result = sql_query($sql); - for($i=0; $row=sql_fetch_array($result); $i++) { - if($is_euckr) - $row = array_map('iconv_utf8', $row); - - // 중복체크 - $sql2 = " select count(*) as cnt from {$g5['login_table']} where lo_ip = '{$row['lo_ip']}' "; - $row2 = sql_fetch($sql2); - if($row2['cnt']) - continue; - - $comma = ''; - $sql_common = ''; - - foreach($row as $key=>$val) { - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - sql_query(" INSERT INTO {$g5['login_table']} SET $sql_common "); - } - echo '
    5. login table 복사
    6. '.PHP_EOL; - - // visit table 복사 - $sql = " select * from {$g4['visit_table']} "; - $result = sql_query($sql); - - // g5_visit 테이블 초기화 - sql_query(" delete from {$g5['visit_table']} "); - - for($i=0; $row=sql_fetch_array($result); $i++) { - if($is_euckr) - $row = array_map('iconv_utf8', $row); - - // 중복체크 - /* - $sql2 = " select count(*) as cnt from {$g5['visit_table']} where vi_ip = '{$row['vi_ip']}' and vi_date = '{$row['vi_date']}' "; - $row2 = sql_fetch($sql2); - if($row2['cnt']) - continue; - */ - - $comma = ''; - $sql_common = ''; - - foreach($row as $key=>$val) { - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - sql_query(" INSERT INTO {$g5['visit_table']} SET $sql_common "); - } - echo '
    7. visit table 복사
    8. '.PHP_EOL; - - // visit sum table 복사 - $sql = " select * from {$g4['visit_sum_table']} "; - $result = sql_query($sql); - - // g5_visit_sub 테이블 초기화 - sql_query(" delete from {$g5['visit_sum_table']} "); - - for($i=0; $row=sql_fetch_array($result); $i++) { - if($is_euckr) - $row = array_map('iconv_utf8', $row); - - // 중복체크 - /* - $sql2 = " select count(*) as cnt from {$g5['visit_sum_table']} where vs_date = '{$row['vs_date']}' "; - $row2 = sql_fetch($sql2); - if($row2['cnt']) - continue; - */ - - $comma = ''; - $sql_common = ''; - - foreach($row as $key=>$val) { - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - sql_query(" INSERT INTO {$g5['visit_sum_table']} SET $sql_common "); - } - echo '
    9. visit sum table 복사
    10. '.PHP_EOL; - - // group table 복사 - $columns = sql_field_names($g5['group_table']); - - $sql = " select * from {$g4['group_table']} "; - $result = sql_query($sql); - for($i=0; $row=sql_fetch_array($result); $i++) { - if($is_euckr) - $row = array_map('iconv_utf8', $row); - - // 중복체크 - $sql2 = " select count(*) as cnt from {$g5['group_table']} where gr_id = '{$row['gr_id']}' "; - $row2 = sql_fetch($sql2); - if($row2['cnt']) - continue; - - $comma = ''; - $sql_common = ''; - - foreach($row as $key=>$val) { - if(!in_array($key, $columns)) - continue; - - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - sql_query(" INSERT INTO {$g5['group_table']} SET $sql_common "); - } - - echo '
    11. group table 복사
    12. '.PHP_EOL; - unset($columns); - unset($fiels); - - // board 복사 - $columns = sql_field_names($g5['board_table']); - - $sql = " select * from {$g4['board_table']} "; - $result = sql_query($sql); - for($i=0; $row=sql_fetch_array($result); $i++) { - if($is_euckr) - $row = array_map('iconv_utf8', $row); - - // 중복체크 - $sql2 = " select count(*) as cnt from {$g5['board_table']} where bo_table = '{$row['bo_table']}' "; - $row2 = sql_fetch($sql2); - if($row2['cnt']) - continue; - - $comma = ''; - $sql_common = ''; - - // 모바일 스킨 디렉토리 - if( ! isset($row['bo_mobile_skin']) ){ - $row['bo_mobile_skin'] = 'basic'; - } - - // 모바일 제목 길이 - if( ! isset($row['bo_mobile_subject_len']) ){ - $row['bo_mobile_subject_len'] = '30'; - } - - // 모바일 페이지당 목록 수 - if( ! isset($row['bo_mobile_page_rows']) ){ - $row['bo_mobile_page_rows'] = '15'; - } - - // 갤러리 이미지 폭 ( 리스트 ) - if( ! isset($row['bo_gallery_width']) ){ - $row['bo_gallery_width'] = '174'; - } - - // 갤러리 이미지 높이 ( 리스트 ) - if( ! isset($row['bo_gallery_height']) ){ - $row['bo_gallery_height'] = '124'; - } - - // 모바일 갤러리 이미지 폭 ( 리스트 ) - if( ! isset($row['bo_mobile_gallery_width']) ){ - $row['bo_mobile_gallery_width'] = '125'; - } - - // 모바일 갤러리 이미지 높이 ( 리스트 ) - if( ! isset($row['bo_mobile_gallery_height']) ){ - $row['bo_mobile_gallery_height'] = '100'; - } - - foreach($row as $key=>$val) { - if(!in_array($key, $columns)) - continue; - - if($key === 'bo_notice'){ - $val = str_replace("\n", ",", $val); - - if( substr($val, -1) === ',' ){ - $val = substr($val, 0, -1); - } - } - - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - sql_query(" INSERT INTO {$g5['board_table']} SET $sql_common "); - - // 게시판 테이블 생성 - $bo_table = $row['bo_table']; - $file = file(G5_ADMIN_PATH.'/sql_write.sql'); - $sql = implode($file, "\n"); - - $create_table = $g5['write_prefix'] . $bo_table; - - $source = array('/__TABLE_NAME__/', '/;/'); - $target = array($create_table, ''); - $sql = preg_replace($source, $target, $sql); - - // 게시글 복사 - if(sql_query($sql, FALSE)) { - $write_table = $g4['write_prefix'].$bo_table; - $columns2 = sql_field_names($create_table); - - $sql3 = " select * from $write_table "; - $result3 = sql_query($sql3); - - for($k=0; $row3=sql_fetch_array($result3); $k++) { - if($is_euckr) - $row3 = array_map('iconv_utf8', $row3); - - $comma3 = ''; - $sql_common3 = ''; - - foreach($row3 as $key=>$val) { - if(!in_array($key, $columns2)) - continue; - - $sql_common3 .= $comma3 . " $key = '".addslashes($val)."' "; - - $comma3 = ','; - } - - // 첨부파일개수 - $wr_id = $row3['wr_id']; - $sql4 = " select count(*) as cnt from {$g4['board_file_table']} where bo_table = '$bo_table' and wr_id = '$wr_id' "; - $row4 = sql_fetch($sql4); - - $sql_common3 .= " , wr_file = '{$row4['cnt']}' "; - - sql_query(" INSERT INTO $create_table SET $sql_common3 "); - } - - echo '
    13. '.str_replace(G5_TABLE_PREFIX.'write_', '', $create_table).' 게시글 복사
    14. '; - } - } - - unset($columns); - unset($fiels); - - // 그외 테이블 복사 - $tables = array('board_file', 'board_new', 'board_good', 'mail', 'memo', 'group_member', 'auth', 'popular', 'poll', 'poll_etc', 'scrap'); - - foreach($tables as $table) { - $columns = sql_field_names($g5[$table.'_table']); - - $src_table = $g4[$table.'_table']; - $dst_table = $g5[$table.'_table']; - $sql = " select * from $src_table "; - $result = sql_query($sql); - for($i=0; $row=sql_fetch_array($result); $i++) { - if($is_euckr) - $row = array_map('iconv_utf8', $row); - - $comma = ''; - $sql_common = ''; - - foreach($row as $key=>$val) { - if(!in_array($key, $columns)) - continue; - - $sql_common .= $comma . " $key = '".addslashes($val)."' "; - - $comma = ','; - } - - $result2 = sql_query(" INSERT INTO $dst_table SET $sql_common ", false); - - if(!$result2) - continue; - } - - echo '
    15. '.$table.' table 복사
    16. '.PHP_EOL; - } - - unset($columns); - unset($fiels); - - echo '
    '.PHP_EOL; - - echo '
    그누보드4 DB 데이터 이전 완료
    '.PHP_EOL; - - // 실행완료 세션에 기록 - set_session('tables_copied', 'done'); - ?> -
    - -
    -
    - - - -
    - - -
    -
    <?php echo G5_VERSION ?>
    -
    -

    - Copyright © 소유하신 도메인. All rights reserved.
    - 상단으로 -

    -
    -
    - - \ No newline at end of file diff --git a/head.php b/head.php index ea90c579d..47bbaab67 100644 --- a/head.php +++ b/head.php @@ -31,134 +31,202 @@ include_once(G5_LIB_PATH.'/popular.lib.php'); include G5_BBS_PATH.'/newwin.inc.php'; // 팝업레이어 } ?> +
    + + +
    + +
    +
    + 사이트 내 전체검색 +
    + + + + + +
    -
    - 사이트 내 전체검색 -
    - - - - - -
    + - // 검색에 많은 부하가 걸리는 경우 이 주석을 제거하세요. - var cnt = 0; - for (var i=0; i 1) { - alert("빠른 검색을 위하여 검색어에 공백은 한개만 입력할 수 있습니다."); - f.stx.select(); - f.stx.focus(); - return false; - } - - return true; - } - -
    - -
    - - - - +
    + +
    - -
    - -
    - + + +
    -
    - - -
    +
    +
    -
    \ No newline at end of file +

    + diff --git a/head.sub.php b/head.sub.php index dc5664636..020900ea2 100644 --- a/head.sub.php +++ b/head.sub.php @@ -82,6 +82,8 @@ var g5_admin_url = ""; + + '.PHP_EOL; // overflow scroll 감지 @@ -90,7 +92,7 @@ if(!defined('G5_IS_ADMIN')) echo $config['cf_add_script']; ?> - +>

    최신글

    + +
    - 'mobile' "; -if(!$is_admin) - $sql .= " and a.bo_use_cert = '' "; -$sql .= " order by b.gr_order, a.bo_order "; -$result = sql_query($sql); -for ($i=0; $row=sql_fetch_array($result); $i++) { - if ($i%2==1) $lt_style = "margin-left:20px"; - else $lt_style = ""; -?> -
    + + 'mobile' "; + if(!$is_admin) + $sql .= " and a.bo_use_cert = '' "; + $sql .= " and a.bo_table not in ('notice', 'gallery') "; //공지사항과 갤러리 게시판은 제외 + $sql .= " order by b.gr_order, a.bo_order "; + $result = sql_query($sql); + for ($i=0; $row=sql_fetch_array($result); $i++) { + if ($i%2==1) $lt_style = "margin-left:2%"; + else $lt_style = ""; + ?> +
    - - + + + +
    + +
    + + + +
  • DB설정 완료
  • @@ -226,6 +322,7 @@ $dir_arr = array ( $data_path.'/file', $data_path.'/log', $data_path.'/member', + $data_path.'/member_image', $data_path.'/session', $data_path.'/content', $data_path.'/faq', @@ -285,6 +382,7 @@ fwrite($f, "\$g5['faq_table'] = G5_TABLE_PREFIX.'faq'; // 자주하시는 질문 fwrite($f, "\$g5['faq_master_table'] = G5_TABLE_PREFIX.'faq_master'; // 자주하시는 질문 마스터 테이블\n"); fwrite($f, "\$g5['new_win_table'] = G5_TABLE_PREFIX.'new_win'; // 새창 테이블\n"); fwrite($f, "\$g5['menu_table'] = G5_TABLE_PREFIX.'menu'; // 메뉴관리 테이블\n"); +fwrite($f, "\$g5['social_profile_table'] = G5_TABLE_PREFIX.'member_social_profiles'; // 소셜 로그인 테이블\n"); fwrite($f, "?>"); fclose($f); diff --git a/js/common.js b/js/common.js index 02ce71a7b..6a1bd75a1 100644 --- a/js/common.js +++ b/js/common.js @@ -540,7 +540,7 @@ $(function() { /** * 텍스트 리사이즈 **/ -function font_resize(id, rmv_class, add_class) +function font_resize(id, rmv_class, add_class, othis) { var $el = $("#"+id); @@ -548,6 +548,10 @@ function font_resize(id, rmv_class, add_class) set_cookie("ck_font_resize_rmv_class", rmv_class, 1, g5_cookie_domain); set_cookie("ck_font_resize_add_class", add_class, 1, g5_cookie_domain); + + if(typeof othis !== "undefined"){ + $(othis).addClass('select').siblings().removeClass('select'); + } } /** diff --git a/js/font-awesome/HELP-US-OUT.txt b/js/font-awesome/HELP-US-OUT.txt new file mode 100644 index 000000000..83d083dd7 --- /dev/null +++ b/js/font-awesome/HELP-US-OUT.txt @@ -0,0 +1,7 @@ +I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project, +Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome, +comprehensive icon sets or copy and paste your own. + +Please. Check it out. + +-Dave Gandy diff --git a/js/font-awesome/css/font-awesome.css b/js/font-awesome/css/font-awesome.css new file mode 100644 index 000000000..ee906a819 --- /dev/null +++ b/js/font-awesome/css/font-awesome.css @@ -0,0 +1,2337 @@ +/*! + * 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 PATH + * -------------------------- */ +@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; +} +/* makes the font 33% larger relative to the icon container */ +.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: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .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: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.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; +} diff --git a/js/font-awesome/css/font-awesome.min.css b/js/font-awesome/css/font-awesome.min.css new file mode 100644 index 000000000..540440ce8 --- /dev/null +++ b/js/font-awesome/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * 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:.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:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.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} diff --git a/js/font-awesome/fonts/FontAwesome.otf b/js/font-awesome/fonts/FontAwesome.otf new file mode 100644 index 000000000..401ec0f36 Binary files /dev/null and b/js/font-awesome/fonts/FontAwesome.otf differ diff --git a/js/font-awesome/fonts/fontawesome-webfont.eot b/js/font-awesome/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/js/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/js/font-awesome/fonts/fontawesome-webfont.svg b/js/font-awesome/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/js/font-awesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/font-awesome/fonts/fontawesome-webfont.ttf b/js/font-awesome/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/js/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/js/font-awesome/fonts/fontawesome-webfont.woff b/js/font-awesome/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/js/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/js/font-awesome/fonts/fontawesome-webfont.woff2 b/js/font-awesome/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/js/font-awesome/fonts/fontawesome-webfont.woff2 differ diff --git a/js/font-awesome/less/animated.less b/js/font-awesome/less/animated.less new file mode 100644 index 000000000..66ad52a5b --- /dev/null +++ b/js/font-awesome/less/animated.less @@ -0,0 +1,34 @@ +// Animated Icons +// -------------------------- + +.@{fa-css-prefix}-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} + +.@{fa-css-prefix}-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); + } +} diff --git a/js/font-awesome/less/bordered-pulled.less b/js/font-awesome/less/bordered-pulled.less new file mode 100644 index 000000000..f1c8ad75f --- /dev/null +++ b/js/font-awesome/less/bordered-pulled.less @@ -0,0 +1,25 @@ +// Bordered & Pulled +// ------------------------- + +.@{fa-css-prefix}-border { + padding: .2em .25em .15em; + border: solid .08em @fa-border-color; + border-radius: .1em; +} + +.@{fa-css-prefix}-pull-left { float: left; } +.@{fa-css-prefix}-pull-right { float: right; } + +.@{fa-css-prefix} { + &.@{fa-css-prefix}-pull-left { margin-right: .3em; } + &.@{fa-css-prefix}-pull-right { margin-left: .3em; } +} + +/* Deprecated as of 4.4.0 */ +.pull-right { float: right; } +.pull-left { float: left; } + +.@{fa-css-prefix} { + &.pull-left { margin-right: .3em; } + &.pull-right { margin-left: .3em; } +} diff --git a/js/font-awesome/less/core.less b/js/font-awesome/less/core.less new file mode 100644 index 000000000..c577ac84a --- /dev/null +++ b/js/font-awesome/less/core.less @@ -0,0 +1,12 @@ +// Base Class Definition +// ------------------------- + +.@{fa-css-prefix} { + display: inline-block; + font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + +} diff --git a/js/font-awesome/less/fixed-width.less b/js/font-awesome/less/fixed-width.less new file mode 100644 index 000000000..110289f2f --- /dev/null +++ b/js/font-awesome/less/fixed-width.less @@ -0,0 +1,6 @@ +// Fixed Width Icons +// ------------------------- +.@{fa-css-prefix}-fw { + width: (18em / 14); + text-align: center; +} diff --git a/js/font-awesome/less/font-awesome.less b/js/font-awesome/less/font-awesome.less new file mode 100644 index 000000000..c3677def3 --- /dev/null +++ b/js/font-awesome/less/font-awesome.less @@ -0,0 +1,18 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ + +@import "variables.less"; +@import "mixins.less"; +@import "path.less"; +@import "core.less"; +@import "larger.less"; +@import "fixed-width.less"; +@import "list.less"; +@import "bordered-pulled.less"; +@import "animated.less"; +@import "rotated-flipped.less"; +@import "stacked.less"; +@import "icons.less"; +@import "screen-reader.less"; diff --git a/js/font-awesome/less/icons.less b/js/font-awesome/less/icons.less new file mode 100644 index 000000000..159d60042 --- /dev/null +++ b/js/font-awesome/less/icons.less @@ -0,0 +1,789 @@ +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ + +.@{fa-css-prefix}-glass:before { content: @fa-var-glass; } +.@{fa-css-prefix}-music:before { content: @fa-var-music; } +.@{fa-css-prefix}-search:before { content: @fa-var-search; } +.@{fa-css-prefix}-envelope-o:before { content: @fa-var-envelope-o; } +.@{fa-css-prefix}-heart:before { content: @fa-var-heart; } +.@{fa-css-prefix}-star:before { content: @fa-var-star; } +.@{fa-css-prefix}-star-o:before { content: @fa-var-star-o; } +.@{fa-css-prefix}-user:before { content: @fa-var-user; } +.@{fa-css-prefix}-film:before { content: @fa-var-film; } +.@{fa-css-prefix}-th-large:before { content: @fa-var-th-large; } +.@{fa-css-prefix}-th:before { content: @fa-var-th; } +.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; } +.@{fa-css-prefix}-check:before { content: @fa-var-check; } +.@{fa-css-prefix}-remove:before, +.@{fa-css-prefix}-close:before, +.@{fa-css-prefix}-times:before { content: @fa-var-times; } +.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; } +.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; } +.@{fa-css-prefix}-power-off:before { content: @fa-var-power-off; } +.@{fa-css-prefix}-signal:before { content: @fa-var-signal; } +.@{fa-css-prefix}-gear:before, +.@{fa-css-prefix}-cog:before { content: @fa-var-cog; } +.@{fa-css-prefix}-trash-o:before { content: @fa-var-trash-o; } +.@{fa-css-prefix}-home:before { content: @fa-var-home; } +.@{fa-css-prefix}-file-o:before { content: @fa-var-file-o; } +.@{fa-css-prefix}-clock-o:before { content: @fa-var-clock-o; } +.@{fa-css-prefix}-road:before { content: @fa-var-road; } +.@{fa-css-prefix}-download:before { content: @fa-var-download; } +.@{fa-css-prefix}-arrow-circle-o-down:before { content: @fa-var-arrow-circle-o-down; } +.@{fa-css-prefix}-arrow-circle-o-up:before { content: @fa-var-arrow-circle-o-up; } +.@{fa-css-prefix}-inbox:before { content: @fa-var-inbox; } +.@{fa-css-prefix}-play-circle-o:before { content: @fa-var-play-circle-o; } +.@{fa-css-prefix}-rotate-right:before, +.@{fa-css-prefix}-repeat:before { content: @fa-var-repeat; } +.@{fa-css-prefix}-refresh:before { content: @fa-var-refresh; } +.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; } +.@{fa-css-prefix}-lock:before { content: @fa-var-lock; } +.@{fa-css-prefix}-flag:before { content: @fa-var-flag; } +.@{fa-css-prefix}-headphones:before { content: @fa-var-headphones; } +.@{fa-css-prefix}-volume-off:before { content: @fa-var-volume-off; } +.@{fa-css-prefix}-volume-down:before { content: @fa-var-volume-down; } +.@{fa-css-prefix}-volume-up:before { content: @fa-var-volume-up; } +.@{fa-css-prefix}-qrcode:before { content: @fa-var-qrcode; } +.@{fa-css-prefix}-barcode:before { content: @fa-var-barcode; } +.@{fa-css-prefix}-tag:before { content: @fa-var-tag; } +.@{fa-css-prefix}-tags:before { content: @fa-var-tags; } +.@{fa-css-prefix}-book:before { content: @fa-var-book; } +.@{fa-css-prefix}-bookmark:before { content: @fa-var-bookmark; } +.@{fa-css-prefix}-print:before { content: @fa-var-print; } +.@{fa-css-prefix}-camera:before { content: @fa-var-camera; } +.@{fa-css-prefix}-font:before { content: @fa-var-font; } +.@{fa-css-prefix}-bold:before { content: @fa-var-bold; } +.@{fa-css-prefix}-italic:before { content: @fa-var-italic; } +.@{fa-css-prefix}-text-height:before { content: @fa-var-text-height; } +.@{fa-css-prefix}-text-width:before { content: @fa-var-text-width; } +.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; } +.@{fa-css-prefix}-align-center:before { content: @fa-var-align-center; } +.@{fa-css-prefix}-align-right:before { content: @fa-var-align-right; } +.@{fa-css-prefix}-align-justify:before { content: @fa-var-align-justify; } +.@{fa-css-prefix}-list:before { content: @fa-var-list; } +.@{fa-css-prefix}-dedent:before, +.@{fa-css-prefix}-outdent:before { content: @fa-var-outdent; } +.@{fa-css-prefix}-indent:before { content: @fa-var-indent; } +.@{fa-css-prefix}-video-camera:before { content: @fa-var-video-camera; } +.@{fa-css-prefix}-photo:before, +.@{fa-css-prefix}-image:before, +.@{fa-css-prefix}-picture-o:before { content: @fa-var-picture-o; } +.@{fa-css-prefix}-pencil:before { content: @fa-var-pencil; } +.@{fa-css-prefix}-map-marker:before { content: @fa-var-map-marker; } +.@{fa-css-prefix}-adjust:before { content: @fa-var-adjust; } +.@{fa-css-prefix}-tint:before { content: @fa-var-tint; } +.@{fa-css-prefix}-edit:before, +.@{fa-css-prefix}-pencil-square-o:before { content: @fa-var-pencil-square-o; } +.@{fa-css-prefix}-share-square-o:before { content: @fa-var-share-square-o; } +.@{fa-css-prefix}-check-square-o:before { content: @fa-var-check-square-o; } +.@{fa-css-prefix}-arrows:before { content: @fa-var-arrows; } +.@{fa-css-prefix}-step-backward:before { content: @fa-var-step-backward; } +.@{fa-css-prefix}-fast-backward:before { content: @fa-var-fast-backward; } +.@{fa-css-prefix}-backward:before { content: @fa-var-backward; } +.@{fa-css-prefix}-play:before { content: @fa-var-play; } +.@{fa-css-prefix}-pause:before { content: @fa-var-pause; } +.@{fa-css-prefix}-stop:before { content: @fa-var-stop; } +.@{fa-css-prefix}-forward:before { content: @fa-var-forward; } +.@{fa-css-prefix}-fast-forward:before { content: @fa-var-fast-forward; } +.@{fa-css-prefix}-step-forward:before { content: @fa-var-step-forward; } +.@{fa-css-prefix}-eject:before { content: @fa-var-eject; } +.@{fa-css-prefix}-chevron-left:before { content: @fa-var-chevron-left; } +.@{fa-css-prefix}-chevron-right:before { content: @fa-var-chevron-right; } +.@{fa-css-prefix}-plus-circle:before { content: @fa-var-plus-circle; } +.@{fa-css-prefix}-minus-circle:before { content: @fa-var-minus-circle; } +.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; } +.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; } +.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; } +.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; } +.@{fa-css-prefix}-crosshairs:before { content: @fa-var-crosshairs; } +.@{fa-css-prefix}-times-circle-o:before { content: @fa-var-times-circle-o; } +.@{fa-css-prefix}-check-circle-o:before { content: @fa-var-check-circle-o; } +.@{fa-css-prefix}-ban:before { content: @fa-var-ban; } +.@{fa-css-prefix}-arrow-left:before { content: @fa-var-arrow-left; } +.@{fa-css-prefix}-arrow-right:before { content: @fa-var-arrow-right; } +.@{fa-css-prefix}-arrow-up:before { content: @fa-var-arrow-up; } +.@{fa-css-prefix}-arrow-down:before { content: @fa-var-arrow-down; } +.@{fa-css-prefix}-mail-forward:before, +.@{fa-css-prefix}-share:before { content: @fa-var-share; } +.@{fa-css-prefix}-expand:before { content: @fa-var-expand; } +.@{fa-css-prefix}-compress:before { content: @fa-var-compress; } +.@{fa-css-prefix}-plus:before { content: @fa-var-plus; } +.@{fa-css-prefix}-minus:before { content: @fa-var-minus; } +.@{fa-css-prefix}-asterisk:before { content: @fa-var-asterisk; } +.@{fa-css-prefix}-exclamation-circle:before { content: @fa-var-exclamation-circle; } +.@{fa-css-prefix}-gift:before { content: @fa-var-gift; } +.@{fa-css-prefix}-leaf:before { content: @fa-var-leaf; } +.@{fa-css-prefix}-fire:before { content: @fa-var-fire; } +.@{fa-css-prefix}-eye:before { content: @fa-var-eye; } +.@{fa-css-prefix}-eye-slash:before { content: @fa-var-eye-slash; } +.@{fa-css-prefix}-warning:before, +.@{fa-css-prefix}-exclamation-triangle:before { content: @fa-var-exclamation-triangle; } +.@{fa-css-prefix}-plane:before { content: @fa-var-plane; } +.@{fa-css-prefix}-calendar:before { content: @fa-var-calendar; } +.@{fa-css-prefix}-random:before { content: @fa-var-random; } +.@{fa-css-prefix}-comment:before { content: @fa-var-comment; } +.@{fa-css-prefix}-magnet:before { content: @fa-var-magnet; } +.@{fa-css-prefix}-chevron-up:before { content: @fa-var-chevron-up; } +.@{fa-css-prefix}-chevron-down:before { content: @fa-var-chevron-down; } +.@{fa-css-prefix}-retweet:before { content: @fa-var-retweet; } +.@{fa-css-prefix}-shopping-cart:before { content: @fa-var-shopping-cart; } +.@{fa-css-prefix}-folder:before { content: @fa-var-folder; } +.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; } +.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; } +.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; } +.@{fa-css-prefix}-bar-chart-o:before, +.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; } +.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; } +.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; } +.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; } +.@{fa-css-prefix}-key:before { content: @fa-var-key; } +.@{fa-css-prefix}-gears:before, +.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; } +.@{fa-css-prefix}-comments:before { content: @fa-var-comments; } +.@{fa-css-prefix}-thumbs-o-up:before { content: @fa-var-thumbs-o-up; } +.@{fa-css-prefix}-thumbs-o-down:before { content: @fa-var-thumbs-o-down; } +.@{fa-css-prefix}-star-half:before { content: @fa-var-star-half; } +.@{fa-css-prefix}-heart-o:before { content: @fa-var-heart-o; } +.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; } +.@{fa-css-prefix}-linkedin-square:before { content: @fa-var-linkedin-square; } +.@{fa-css-prefix}-thumb-tack:before { content: @fa-var-thumb-tack; } +.@{fa-css-prefix}-external-link:before { content: @fa-var-external-link; } +.@{fa-css-prefix}-sign-in:before { content: @fa-var-sign-in; } +.@{fa-css-prefix}-trophy:before { content: @fa-var-trophy; } +.@{fa-css-prefix}-github-square:before { content: @fa-var-github-square; } +.@{fa-css-prefix}-upload:before { content: @fa-var-upload; } +.@{fa-css-prefix}-lemon-o:before { content: @fa-var-lemon-o; } +.@{fa-css-prefix}-phone:before { content: @fa-var-phone; } +.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; } +.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; } +.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; } +.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; } +.@{fa-css-prefix}-facebook-f:before, +.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; } +.@{fa-css-prefix}-github:before { content: @fa-var-github; } +.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; } +.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; } +.@{fa-css-prefix}-feed:before, +.@{fa-css-prefix}-rss:before { content: @fa-var-rss; } +.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; } +.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; } +.@{fa-css-prefix}-bell:before { content: @fa-var-bell; } +.@{fa-css-prefix}-certificate:before { content: @fa-var-certificate; } +.@{fa-css-prefix}-hand-o-right:before { content: @fa-var-hand-o-right; } +.@{fa-css-prefix}-hand-o-left:before { content: @fa-var-hand-o-left; } +.@{fa-css-prefix}-hand-o-up:before { content: @fa-var-hand-o-up; } +.@{fa-css-prefix}-hand-o-down:before { content: @fa-var-hand-o-down; } +.@{fa-css-prefix}-arrow-circle-left:before { content: @fa-var-arrow-circle-left; } +.@{fa-css-prefix}-arrow-circle-right:before { content: @fa-var-arrow-circle-right; } +.@{fa-css-prefix}-arrow-circle-up:before { content: @fa-var-arrow-circle-up; } +.@{fa-css-prefix}-arrow-circle-down:before { content: @fa-var-arrow-circle-down; } +.@{fa-css-prefix}-globe:before { content: @fa-var-globe; } +.@{fa-css-prefix}-wrench:before { content: @fa-var-wrench; } +.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; } +.@{fa-css-prefix}-filter:before { content: @fa-var-filter; } +.@{fa-css-prefix}-briefcase:before { content: @fa-var-briefcase; } +.@{fa-css-prefix}-arrows-alt:before { content: @fa-var-arrows-alt; } +.@{fa-css-prefix}-group:before, +.@{fa-css-prefix}-users:before { content: @fa-var-users; } +.@{fa-css-prefix}-chain:before, +.@{fa-css-prefix}-link:before { content: @fa-var-link; } +.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; } +.@{fa-css-prefix}-flask:before { content: @fa-var-flask; } +.@{fa-css-prefix}-cut:before, +.@{fa-css-prefix}-scissors:before { content: @fa-var-scissors; } +.@{fa-css-prefix}-copy:before, +.@{fa-css-prefix}-files-o:before { content: @fa-var-files-o; } +.@{fa-css-prefix}-paperclip:before { content: @fa-var-paperclip; } +.@{fa-css-prefix}-save:before, +.@{fa-css-prefix}-floppy-o:before { content: @fa-var-floppy-o; } +.@{fa-css-prefix}-square:before { content: @fa-var-square; } +.@{fa-css-prefix}-navicon:before, +.@{fa-css-prefix}-reorder:before, +.@{fa-css-prefix}-bars:before { content: @fa-var-bars; } +.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; } +.@{fa-css-prefix}-list-ol:before { content: @fa-var-list-ol; } +.@{fa-css-prefix}-strikethrough:before { content: @fa-var-strikethrough; } +.@{fa-css-prefix}-underline:before { content: @fa-var-underline; } +.@{fa-css-prefix}-table:before { content: @fa-var-table; } +.@{fa-css-prefix}-magic:before { content: @fa-var-magic; } +.@{fa-css-prefix}-truck:before { content: @fa-var-truck; } +.@{fa-css-prefix}-pinterest:before { content: @fa-var-pinterest; } +.@{fa-css-prefix}-pinterest-square:before { content: @fa-var-pinterest-square; } +.@{fa-css-prefix}-google-plus-square:before { content: @fa-var-google-plus-square; } +.@{fa-css-prefix}-google-plus:before { content: @fa-var-google-plus; } +.@{fa-css-prefix}-money:before { content: @fa-var-money; } +.@{fa-css-prefix}-caret-down:before { content: @fa-var-caret-down; } +.@{fa-css-prefix}-caret-up:before { content: @fa-var-caret-up; } +.@{fa-css-prefix}-caret-left:before { content: @fa-var-caret-left; } +.@{fa-css-prefix}-caret-right:before { content: @fa-var-caret-right; } +.@{fa-css-prefix}-columns:before { content: @fa-var-columns; } +.@{fa-css-prefix}-unsorted:before, +.@{fa-css-prefix}-sort:before { content: @fa-var-sort; } +.@{fa-css-prefix}-sort-down:before, +.@{fa-css-prefix}-sort-desc:before { content: @fa-var-sort-desc; } +.@{fa-css-prefix}-sort-up:before, +.@{fa-css-prefix}-sort-asc:before { content: @fa-var-sort-asc; } +.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; } +.@{fa-css-prefix}-linkedin:before { content: @fa-var-linkedin; } +.@{fa-css-prefix}-rotate-left:before, +.@{fa-css-prefix}-undo:before { content: @fa-var-undo; } +.@{fa-css-prefix}-legal:before, +.@{fa-css-prefix}-gavel:before { content: @fa-var-gavel; } +.@{fa-css-prefix}-dashboard:before, +.@{fa-css-prefix}-tachometer:before { content: @fa-var-tachometer; } +.@{fa-css-prefix}-comment-o:before { content: @fa-var-comment-o; } +.@{fa-css-prefix}-comments-o:before { content: @fa-var-comments-o; } +.@{fa-css-prefix}-flash:before, +.@{fa-css-prefix}-bolt:before { content: @fa-var-bolt; } +.@{fa-css-prefix}-sitemap:before { content: @fa-var-sitemap; } +.@{fa-css-prefix}-umbrella:before { content: @fa-var-umbrella; } +.@{fa-css-prefix}-paste:before, +.@{fa-css-prefix}-clipboard:before { content: @fa-var-clipboard; } +.@{fa-css-prefix}-lightbulb-o:before { content: @fa-var-lightbulb-o; } +.@{fa-css-prefix}-exchange:before { content: @fa-var-exchange; } +.@{fa-css-prefix}-cloud-download:before { content: @fa-var-cloud-download; } +.@{fa-css-prefix}-cloud-upload:before { content: @fa-var-cloud-upload; } +.@{fa-css-prefix}-user-md:before { content: @fa-var-user-md; } +.@{fa-css-prefix}-stethoscope:before { content: @fa-var-stethoscope; } +.@{fa-css-prefix}-suitcase:before { content: @fa-var-suitcase; } +.@{fa-css-prefix}-bell-o:before { content: @fa-var-bell-o; } +.@{fa-css-prefix}-coffee:before { content: @fa-var-coffee; } +.@{fa-css-prefix}-cutlery:before { content: @fa-var-cutlery; } +.@{fa-css-prefix}-file-text-o:before { content: @fa-var-file-text-o; } +.@{fa-css-prefix}-building-o:before { content: @fa-var-building-o; } +.@{fa-css-prefix}-hospital-o:before { content: @fa-var-hospital-o; } +.@{fa-css-prefix}-ambulance:before { content: @fa-var-ambulance; } +.@{fa-css-prefix}-medkit:before { content: @fa-var-medkit; } +.@{fa-css-prefix}-fighter-jet:before { content: @fa-var-fighter-jet; } +.@{fa-css-prefix}-beer:before { content: @fa-var-beer; } +.@{fa-css-prefix}-h-square:before { content: @fa-var-h-square; } +.@{fa-css-prefix}-plus-square:before { content: @fa-var-plus-square; } +.@{fa-css-prefix}-angle-double-left:before { content: @fa-var-angle-double-left; } +.@{fa-css-prefix}-angle-double-right:before { content: @fa-var-angle-double-right; } +.@{fa-css-prefix}-angle-double-up:before { content: @fa-var-angle-double-up; } +.@{fa-css-prefix}-angle-double-down:before { content: @fa-var-angle-double-down; } +.@{fa-css-prefix}-angle-left:before { content: @fa-var-angle-left; } +.@{fa-css-prefix}-angle-right:before { content: @fa-var-angle-right; } +.@{fa-css-prefix}-angle-up:before { content: @fa-var-angle-up; } +.@{fa-css-prefix}-angle-down:before { content: @fa-var-angle-down; } +.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; } +.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; } +.@{fa-css-prefix}-tablet:before { content: @fa-var-tablet; } +.@{fa-css-prefix}-mobile-phone:before, +.@{fa-css-prefix}-mobile:before { content: @fa-var-mobile; } +.@{fa-css-prefix}-circle-o:before { content: @fa-var-circle-o; } +.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; } +.@{fa-css-prefix}-quote-right:before { content: @fa-var-quote-right; } +.@{fa-css-prefix}-spinner:before { content: @fa-var-spinner; } +.@{fa-css-prefix}-circle:before { content: @fa-var-circle; } +.@{fa-css-prefix}-mail-reply:before, +.@{fa-css-prefix}-reply:before { content: @fa-var-reply; } +.@{fa-css-prefix}-github-alt:before { content: @fa-var-github-alt; } +.@{fa-css-prefix}-folder-o:before { content: @fa-var-folder-o; } +.@{fa-css-prefix}-folder-open-o:before { content: @fa-var-folder-open-o; } +.@{fa-css-prefix}-smile-o:before { content: @fa-var-smile-o; } +.@{fa-css-prefix}-frown-o:before { content: @fa-var-frown-o; } +.@{fa-css-prefix}-meh-o:before { content: @fa-var-meh-o; } +.@{fa-css-prefix}-gamepad:before { content: @fa-var-gamepad; } +.@{fa-css-prefix}-keyboard-o:before { content: @fa-var-keyboard-o; } +.@{fa-css-prefix}-flag-o:before { content: @fa-var-flag-o; } +.@{fa-css-prefix}-flag-checkered:before { content: @fa-var-flag-checkered; } +.@{fa-css-prefix}-terminal:before { content: @fa-var-terminal; } +.@{fa-css-prefix}-code:before { content: @fa-var-code; } +.@{fa-css-prefix}-mail-reply-all:before, +.@{fa-css-prefix}-reply-all:before { content: @fa-var-reply-all; } +.@{fa-css-prefix}-star-half-empty:before, +.@{fa-css-prefix}-star-half-full:before, +.@{fa-css-prefix}-star-half-o:before { content: @fa-var-star-half-o; } +.@{fa-css-prefix}-location-arrow:before { content: @fa-var-location-arrow; } +.@{fa-css-prefix}-crop:before { content: @fa-var-crop; } +.@{fa-css-prefix}-code-fork:before { content: @fa-var-code-fork; } +.@{fa-css-prefix}-unlink:before, +.@{fa-css-prefix}-chain-broken:before { content: @fa-var-chain-broken; } +.@{fa-css-prefix}-question:before { content: @fa-var-question; } +.@{fa-css-prefix}-info:before { content: @fa-var-info; } +.@{fa-css-prefix}-exclamation:before { content: @fa-var-exclamation; } +.@{fa-css-prefix}-superscript:before { content: @fa-var-superscript; } +.@{fa-css-prefix}-subscript:before { content: @fa-var-subscript; } +.@{fa-css-prefix}-eraser:before { content: @fa-var-eraser; } +.@{fa-css-prefix}-puzzle-piece:before { content: @fa-var-puzzle-piece; } +.@{fa-css-prefix}-microphone:before { content: @fa-var-microphone; } +.@{fa-css-prefix}-microphone-slash:before { content: @fa-var-microphone-slash; } +.@{fa-css-prefix}-shield:before { content: @fa-var-shield; } +.@{fa-css-prefix}-calendar-o:before { content: @fa-var-calendar-o; } +.@{fa-css-prefix}-fire-extinguisher:before { content: @fa-var-fire-extinguisher; } +.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; } +.@{fa-css-prefix}-maxcdn:before { content: @fa-var-maxcdn; } +.@{fa-css-prefix}-chevron-circle-left:before { content: @fa-var-chevron-circle-left; } +.@{fa-css-prefix}-chevron-circle-right:before { content: @fa-var-chevron-circle-right; } +.@{fa-css-prefix}-chevron-circle-up:before { content: @fa-var-chevron-circle-up; } +.@{fa-css-prefix}-chevron-circle-down:before { content: @fa-var-chevron-circle-down; } +.@{fa-css-prefix}-html5:before { content: @fa-var-html5; } +.@{fa-css-prefix}-css3:before { content: @fa-var-css3; } +.@{fa-css-prefix}-anchor:before { content: @fa-var-anchor; } +.@{fa-css-prefix}-unlock-alt:before { content: @fa-var-unlock-alt; } +.@{fa-css-prefix}-bullseye:before { content: @fa-var-bullseye; } +.@{fa-css-prefix}-ellipsis-h:before { content: @fa-var-ellipsis-h; } +.@{fa-css-prefix}-ellipsis-v:before { content: @fa-var-ellipsis-v; } +.@{fa-css-prefix}-rss-square:before { content: @fa-var-rss-square; } +.@{fa-css-prefix}-play-circle:before { content: @fa-var-play-circle; } +.@{fa-css-prefix}-ticket:before { content: @fa-var-ticket; } +.@{fa-css-prefix}-minus-square:before { content: @fa-var-minus-square; } +.@{fa-css-prefix}-minus-square-o:before { content: @fa-var-minus-square-o; } +.@{fa-css-prefix}-level-up:before { content: @fa-var-level-up; } +.@{fa-css-prefix}-level-down:before { content: @fa-var-level-down; } +.@{fa-css-prefix}-check-square:before { content: @fa-var-check-square; } +.@{fa-css-prefix}-pencil-square:before { content: @fa-var-pencil-square; } +.@{fa-css-prefix}-external-link-square:before { content: @fa-var-external-link-square; } +.@{fa-css-prefix}-share-square:before { content: @fa-var-share-square; } +.@{fa-css-prefix}-compass:before { content: @fa-var-compass; } +.@{fa-css-prefix}-toggle-down:before, +.@{fa-css-prefix}-caret-square-o-down:before { content: @fa-var-caret-square-o-down; } +.@{fa-css-prefix}-toggle-up:before, +.@{fa-css-prefix}-caret-square-o-up:before { content: @fa-var-caret-square-o-up; } +.@{fa-css-prefix}-toggle-right:before, +.@{fa-css-prefix}-caret-square-o-right:before { content: @fa-var-caret-square-o-right; } +.@{fa-css-prefix}-euro:before, +.@{fa-css-prefix}-eur:before { content: @fa-var-eur; } +.@{fa-css-prefix}-gbp:before { content: @fa-var-gbp; } +.@{fa-css-prefix}-dollar:before, +.@{fa-css-prefix}-usd:before { content: @fa-var-usd; } +.@{fa-css-prefix}-rupee:before, +.@{fa-css-prefix}-inr:before { content: @fa-var-inr; } +.@{fa-css-prefix}-cny:before, +.@{fa-css-prefix}-rmb:before, +.@{fa-css-prefix}-yen:before, +.@{fa-css-prefix}-jpy:before { content: @fa-var-jpy; } +.@{fa-css-prefix}-ruble:before, +.@{fa-css-prefix}-rouble:before, +.@{fa-css-prefix}-rub:before { content: @fa-var-rub; } +.@{fa-css-prefix}-won:before, +.@{fa-css-prefix}-krw:before { content: @fa-var-krw; } +.@{fa-css-prefix}-bitcoin:before, +.@{fa-css-prefix}-btc:before { content: @fa-var-btc; } +.@{fa-css-prefix}-file:before { content: @fa-var-file; } +.@{fa-css-prefix}-file-text:before { content: @fa-var-file-text; } +.@{fa-css-prefix}-sort-alpha-asc:before { content: @fa-var-sort-alpha-asc; } +.@{fa-css-prefix}-sort-alpha-desc:before { content: @fa-var-sort-alpha-desc; } +.@{fa-css-prefix}-sort-amount-asc:before { content: @fa-var-sort-amount-asc; } +.@{fa-css-prefix}-sort-amount-desc:before { content: @fa-var-sort-amount-desc; } +.@{fa-css-prefix}-sort-numeric-asc:before { content: @fa-var-sort-numeric-asc; } +.@{fa-css-prefix}-sort-numeric-desc:before { content: @fa-var-sort-numeric-desc; } +.@{fa-css-prefix}-thumbs-up:before { content: @fa-var-thumbs-up; } +.@{fa-css-prefix}-thumbs-down:before { content: @fa-var-thumbs-down; } +.@{fa-css-prefix}-youtube-square:before { content: @fa-var-youtube-square; } +.@{fa-css-prefix}-youtube:before { content: @fa-var-youtube; } +.@{fa-css-prefix}-xing:before { content: @fa-var-xing; } +.@{fa-css-prefix}-xing-square:before { content: @fa-var-xing-square; } +.@{fa-css-prefix}-youtube-play:before { content: @fa-var-youtube-play; } +.@{fa-css-prefix}-dropbox:before { content: @fa-var-dropbox; } +.@{fa-css-prefix}-stack-overflow:before { content: @fa-var-stack-overflow; } +.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; } +.@{fa-css-prefix}-flickr:before { content: @fa-var-flickr; } +.@{fa-css-prefix}-adn:before { content: @fa-var-adn; } +.@{fa-css-prefix}-bitbucket:before { content: @fa-var-bitbucket; } +.@{fa-css-prefix}-bitbucket-square:before { content: @fa-var-bitbucket-square; } +.@{fa-css-prefix}-tumblr:before { content: @fa-var-tumblr; } +.@{fa-css-prefix}-tumblr-square:before { content: @fa-var-tumblr-square; } +.@{fa-css-prefix}-long-arrow-down:before { content: @fa-var-long-arrow-down; } +.@{fa-css-prefix}-long-arrow-up:before { content: @fa-var-long-arrow-up; } +.@{fa-css-prefix}-long-arrow-left:before { content: @fa-var-long-arrow-left; } +.@{fa-css-prefix}-long-arrow-right:before { content: @fa-var-long-arrow-right; } +.@{fa-css-prefix}-apple:before { content: @fa-var-apple; } +.@{fa-css-prefix}-windows:before { content: @fa-var-windows; } +.@{fa-css-prefix}-android:before { content: @fa-var-android; } +.@{fa-css-prefix}-linux:before { content: @fa-var-linux; } +.@{fa-css-prefix}-dribbble:before { content: @fa-var-dribbble; } +.@{fa-css-prefix}-skype:before { content: @fa-var-skype; } +.@{fa-css-prefix}-foursquare:before { content: @fa-var-foursquare; } +.@{fa-css-prefix}-trello:before { content: @fa-var-trello; } +.@{fa-css-prefix}-female:before { content: @fa-var-female; } +.@{fa-css-prefix}-male:before { content: @fa-var-male; } +.@{fa-css-prefix}-gittip:before, +.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; } +.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; } +.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; } +.@{fa-css-prefix}-archive:before { content: @fa-var-archive; } +.@{fa-css-prefix}-bug:before { content: @fa-var-bug; } +.@{fa-css-prefix}-vk:before { content: @fa-var-vk; } +.@{fa-css-prefix}-weibo:before { content: @fa-var-weibo; } +.@{fa-css-prefix}-renren:before { content: @fa-var-renren; } +.@{fa-css-prefix}-pagelines:before { content: @fa-var-pagelines; } +.@{fa-css-prefix}-stack-exchange:before { content: @fa-var-stack-exchange; } +.@{fa-css-prefix}-arrow-circle-o-right:before { content: @fa-var-arrow-circle-o-right; } +.@{fa-css-prefix}-arrow-circle-o-left:before { content: @fa-var-arrow-circle-o-left; } +.@{fa-css-prefix}-toggle-left:before, +.@{fa-css-prefix}-caret-square-o-left:before { content: @fa-var-caret-square-o-left; } +.@{fa-css-prefix}-dot-circle-o:before { content: @fa-var-dot-circle-o; } +.@{fa-css-prefix}-wheelchair:before { content: @fa-var-wheelchair; } +.@{fa-css-prefix}-vimeo-square:before { content: @fa-var-vimeo-square; } +.@{fa-css-prefix}-turkish-lira:before, +.@{fa-css-prefix}-try:before { content: @fa-var-try; } +.@{fa-css-prefix}-plus-square-o:before { content: @fa-var-plus-square-o; } +.@{fa-css-prefix}-space-shuttle:before { content: @fa-var-space-shuttle; } +.@{fa-css-prefix}-slack:before { content: @fa-var-slack; } +.@{fa-css-prefix}-envelope-square:before { content: @fa-var-envelope-square; } +.@{fa-css-prefix}-wordpress:before { content: @fa-var-wordpress; } +.@{fa-css-prefix}-openid:before { content: @fa-var-openid; } +.@{fa-css-prefix}-institution:before, +.@{fa-css-prefix}-bank:before, +.@{fa-css-prefix}-university:before { content: @fa-var-university; } +.@{fa-css-prefix}-mortar-board:before, +.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; } +.@{fa-css-prefix}-yahoo:before { content: @fa-var-yahoo; } +.@{fa-css-prefix}-google:before { content: @fa-var-google; } +.@{fa-css-prefix}-reddit:before { content: @fa-var-reddit; } +.@{fa-css-prefix}-reddit-square:before { content: @fa-var-reddit-square; } +.@{fa-css-prefix}-stumbleupon-circle:before { content: @fa-var-stumbleupon-circle; } +.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; } +.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; } +.@{fa-css-prefix}-digg:before { content: @fa-var-digg; } +.@{fa-css-prefix}-pied-piper-pp:before { content: @fa-var-pied-piper-pp; } +.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; } +.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; } +.@{fa-css-prefix}-joomla:before { content: @fa-var-joomla; } +.@{fa-css-prefix}-language:before { content: @fa-var-language; } +.@{fa-css-prefix}-fax:before { content: @fa-var-fax; } +.@{fa-css-prefix}-building:before { content: @fa-var-building; } +.@{fa-css-prefix}-child:before { content: @fa-var-child; } +.@{fa-css-prefix}-paw:before { content: @fa-var-paw; } +.@{fa-css-prefix}-spoon:before { content: @fa-var-spoon; } +.@{fa-css-prefix}-cube:before { content: @fa-var-cube; } +.@{fa-css-prefix}-cubes:before { content: @fa-var-cubes; } +.@{fa-css-prefix}-behance:before { content: @fa-var-behance; } +.@{fa-css-prefix}-behance-square:before { content: @fa-var-behance-square; } +.@{fa-css-prefix}-steam:before { content: @fa-var-steam; } +.@{fa-css-prefix}-steam-square:before { content: @fa-var-steam-square; } +.@{fa-css-prefix}-recycle:before { content: @fa-var-recycle; } +.@{fa-css-prefix}-automobile:before, +.@{fa-css-prefix}-car:before { content: @fa-var-car; } +.@{fa-css-prefix}-cab:before, +.@{fa-css-prefix}-taxi:before { content: @fa-var-taxi; } +.@{fa-css-prefix}-tree:before { content: @fa-var-tree; } +.@{fa-css-prefix}-spotify:before { content: @fa-var-spotify; } +.@{fa-css-prefix}-deviantart:before { content: @fa-var-deviantart; } +.@{fa-css-prefix}-soundcloud:before { content: @fa-var-soundcloud; } +.@{fa-css-prefix}-database:before { content: @fa-var-database; } +.@{fa-css-prefix}-file-pdf-o:before { content: @fa-var-file-pdf-o; } +.@{fa-css-prefix}-file-word-o:before { content: @fa-var-file-word-o; } +.@{fa-css-prefix}-file-excel-o:before { content: @fa-var-file-excel-o; } +.@{fa-css-prefix}-file-powerpoint-o:before { content: @fa-var-file-powerpoint-o; } +.@{fa-css-prefix}-file-photo-o:before, +.@{fa-css-prefix}-file-picture-o:before, +.@{fa-css-prefix}-file-image-o:before { content: @fa-var-file-image-o; } +.@{fa-css-prefix}-file-zip-o:before, +.@{fa-css-prefix}-file-archive-o:before { content: @fa-var-file-archive-o; } +.@{fa-css-prefix}-file-sound-o:before, +.@{fa-css-prefix}-file-audio-o:before { content: @fa-var-file-audio-o; } +.@{fa-css-prefix}-file-movie-o:before, +.@{fa-css-prefix}-file-video-o:before { content: @fa-var-file-video-o; } +.@{fa-css-prefix}-file-code-o:before { content: @fa-var-file-code-o; } +.@{fa-css-prefix}-vine:before { content: @fa-var-vine; } +.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; } +.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; } +.@{fa-css-prefix}-life-bouy:before, +.@{fa-css-prefix}-life-buoy:before, +.@{fa-css-prefix}-life-saver:before, +.@{fa-css-prefix}-support:before, +.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; } +.@{fa-css-prefix}-circle-o-notch:before { content: @fa-var-circle-o-notch; } +.@{fa-css-prefix}-ra:before, +.@{fa-css-prefix}-resistance:before, +.@{fa-css-prefix}-rebel:before { content: @fa-var-rebel; } +.@{fa-css-prefix}-ge:before, +.@{fa-css-prefix}-empire:before { content: @fa-var-empire; } +.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; } +.@{fa-css-prefix}-git:before { content: @fa-var-git; } +.@{fa-css-prefix}-y-combinator-square:before, +.@{fa-css-prefix}-yc-square:before, +.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; } +.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; } +.@{fa-css-prefix}-qq:before { content: @fa-var-qq; } +.@{fa-css-prefix}-wechat:before, +.@{fa-css-prefix}-weixin:before { content: @fa-var-weixin; } +.@{fa-css-prefix}-send:before, +.@{fa-css-prefix}-paper-plane:before { content: @fa-var-paper-plane; } +.@{fa-css-prefix}-send-o:before, +.@{fa-css-prefix}-paper-plane-o:before { content: @fa-var-paper-plane-o; } +.@{fa-css-prefix}-history:before { content: @fa-var-history; } +.@{fa-css-prefix}-circle-thin:before { content: @fa-var-circle-thin; } +.@{fa-css-prefix}-header:before { content: @fa-var-header; } +.@{fa-css-prefix}-paragraph:before { content: @fa-var-paragraph; } +.@{fa-css-prefix}-sliders:before { content: @fa-var-sliders; } +.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; } +.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; } +.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; } +.@{fa-css-prefix}-soccer-ball-o:before, +.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; } +.@{fa-css-prefix}-tty:before { content: @fa-var-tty; } +.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; } +.@{fa-css-prefix}-plug:before { content: @fa-var-plug; } +.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; } +.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; } +.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; } +.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; } +.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; } +.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; } +.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; } +.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; } +.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; } +.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; } +.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; } +.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; } +.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; } +.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; } +.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; } +.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; } +.@{fa-css-prefix}-trash:before { content: @fa-var-trash; } +.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; } +.@{fa-css-prefix}-at:before { content: @fa-var-at; } +.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; } +.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; } +.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; } +.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; } +.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; } +.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; } +.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; } +.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; } +.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; } +.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; } +.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; } +.@{fa-css-prefix}-bus:before { content: @fa-var-bus; } +.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; } +.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; } +.@{fa-css-prefix}-cc:before { content: @fa-var-cc; } +.@{fa-css-prefix}-shekel:before, +.@{fa-css-prefix}-sheqel:before, +.@{fa-css-prefix}-ils:before { content: @fa-var-ils; } +.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; } +.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; } +.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; } +.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; } +.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; } +.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; } +.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; } +.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; } +.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; } +.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; } +.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; } +.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; } +.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; } +.@{fa-css-prefix}-ship:before { content: @fa-var-ship; } +.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; } +.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; } +.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; } +.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; } +.@{fa-css-prefix}-venus:before { content: @fa-var-venus; } +.@{fa-css-prefix}-mars:before { content: @fa-var-mars; } +.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; } +.@{fa-css-prefix}-intersex:before, +.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; } +.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; } +.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; } +.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; } +.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; } +.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; } +.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; } +.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; } +.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; } +.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; } +.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; } +.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; } +.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; } +.@{fa-css-prefix}-server:before { content: @fa-var-server; } +.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; } +.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; } +.@{fa-css-prefix}-hotel:before, +.@{fa-css-prefix}-bed:before { content: @fa-var-bed; } +.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; } +.@{fa-css-prefix}-train:before { content: @fa-var-train; } +.@{fa-css-prefix}-subway:before { content: @fa-var-subway; } +.@{fa-css-prefix}-medium:before { content: @fa-var-medium; } +.@{fa-css-prefix}-yc:before, +.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; } +.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; } +.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; } +.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; } +.@{fa-css-prefix}-battery-4:before, +.@{fa-css-prefix}-battery:before, +.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; } +.@{fa-css-prefix}-battery-3:before, +.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; } +.@{fa-css-prefix}-battery-2:before, +.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; } +.@{fa-css-prefix}-battery-1:before, +.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; } +.@{fa-css-prefix}-battery-0:before, +.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; } +.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; } +.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; } +.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; } +.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; } +.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; } +.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; } +.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; } +.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; } +.@{fa-css-prefix}-clone:before { content: @fa-var-clone; } +.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; } +.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; } +.@{fa-css-prefix}-hourglass-1:before, +.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; } +.@{fa-css-prefix}-hourglass-2:before, +.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; } +.@{fa-css-prefix}-hourglass-3:before, +.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; } +.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; } +.@{fa-css-prefix}-hand-grab-o:before, +.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; } +.@{fa-css-prefix}-hand-stop-o:before, +.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; } +.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; } +.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; } +.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; } +.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; } +.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; } +.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; } +.@{fa-css-prefix}-registered:before { content: @fa-var-registered; } +.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; } +.@{fa-css-prefix}-gg:before { content: @fa-var-gg; } +.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; } +.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; } +.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; } +.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; } +.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; } +.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; } +.@{fa-css-prefix}-safari:before { content: @fa-var-safari; } +.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; } +.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; } +.@{fa-css-prefix}-opera:before { content: @fa-var-opera; } +.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; } +.@{fa-css-prefix}-tv:before, +.@{fa-css-prefix}-television:before { content: @fa-var-television; } +.@{fa-css-prefix}-contao:before { content: @fa-var-contao; } +.@{fa-css-prefix}-500px:before { content: @fa-var-500px; } +.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; } +.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; } +.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; } +.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; } +.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; } +.@{fa-css-prefix}-industry:before { content: @fa-var-industry; } +.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; } +.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; } +.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; } +.@{fa-css-prefix}-map:before { content: @fa-var-map; } +.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; } +.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; } +.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; } +.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; } +.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; } +.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; } +.@{fa-css-prefix}-reddit-alien:before { content: @fa-var-reddit-alien; } +.@{fa-css-prefix}-edge:before { content: @fa-var-edge; } +.@{fa-css-prefix}-credit-card-alt:before { content: @fa-var-credit-card-alt; } +.@{fa-css-prefix}-codiepie:before { content: @fa-var-codiepie; } +.@{fa-css-prefix}-modx:before { content: @fa-var-modx; } +.@{fa-css-prefix}-fort-awesome:before { content: @fa-var-fort-awesome; } +.@{fa-css-prefix}-usb:before { content: @fa-var-usb; } +.@{fa-css-prefix}-product-hunt:before { content: @fa-var-product-hunt; } +.@{fa-css-prefix}-mixcloud:before { content: @fa-var-mixcloud; } +.@{fa-css-prefix}-scribd:before { content: @fa-var-scribd; } +.@{fa-css-prefix}-pause-circle:before { content: @fa-var-pause-circle; } +.@{fa-css-prefix}-pause-circle-o:before { content: @fa-var-pause-circle-o; } +.@{fa-css-prefix}-stop-circle:before { content: @fa-var-stop-circle; } +.@{fa-css-prefix}-stop-circle-o:before { content: @fa-var-stop-circle-o; } +.@{fa-css-prefix}-shopping-bag:before { content: @fa-var-shopping-bag; } +.@{fa-css-prefix}-shopping-basket:before { content: @fa-var-shopping-basket; } +.@{fa-css-prefix}-hashtag:before { content: @fa-var-hashtag; } +.@{fa-css-prefix}-bluetooth:before { content: @fa-var-bluetooth; } +.@{fa-css-prefix}-bluetooth-b:before { content: @fa-var-bluetooth-b; } +.@{fa-css-prefix}-percent:before { content: @fa-var-percent; } +.@{fa-css-prefix}-gitlab:before { content: @fa-var-gitlab; } +.@{fa-css-prefix}-wpbeginner:before { content: @fa-var-wpbeginner; } +.@{fa-css-prefix}-wpforms:before { content: @fa-var-wpforms; } +.@{fa-css-prefix}-envira:before { content: @fa-var-envira; } +.@{fa-css-prefix}-universal-access:before { content: @fa-var-universal-access; } +.@{fa-css-prefix}-wheelchair-alt:before { content: @fa-var-wheelchair-alt; } +.@{fa-css-prefix}-question-circle-o:before { content: @fa-var-question-circle-o; } +.@{fa-css-prefix}-blind:before { content: @fa-var-blind; } +.@{fa-css-prefix}-audio-description:before { content: @fa-var-audio-description; } +.@{fa-css-prefix}-volume-control-phone:before { content: @fa-var-volume-control-phone; } +.@{fa-css-prefix}-braille:before { content: @fa-var-braille; } +.@{fa-css-prefix}-assistive-listening-systems:before { content: @fa-var-assistive-listening-systems; } +.@{fa-css-prefix}-asl-interpreting:before, +.@{fa-css-prefix}-american-sign-language-interpreting:before { content: @fa-var-american-sign-language-interpreting; } +.@{fa-css-prefix}-deafness:before, +.@{fa-css-prefix}-hard-of-hearing:before, +.@{fa-css-prefix}-deaf:before { content: @fa-var-deaf; } +.@{fa-css-prefix}-glide:before { content: @fa-var-glide; } +.@{fa-css-prefix}-glide-g:before { content: @fa-var-glide-g; } +.@{fa-css-prefix}-signing:before, +.@{fa-css-prefix}-sign-language:before { content: @fa-var-sign-language; } +.@{fa-css-prefix}-low-vision:before { content: @fa-var-low-vision; } +.@{fa-css-prefix}-viadeo:before { content: @fa-var-viadeo; } +.@{fa-css-prefix}-viadeo-square:before { content: @fa-var-viadeo-square; } +.@{fa-css-prefix}-snapchat:before { content: @fa-var-snapchat; } +.@{fa-css-prefix}-snapchat-ghost:before { content: @fa-var-snapchat-ghost; } +.@{fa-css-prefix}-snapchat-square:before { content: @fa-var-snapchat-square; } +.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; } +.@{fa-css-prefix}-first-order:before { content: @fa-var-first-order; } +.@{fa-css-prefix}-yoast:before { content: @fa-var-yoast; } +.@{fa-css-prefix}-themeisle:before { content: @fa-var-themeisle; } +.@{fa-css-prefix}-google-plus-circle:before, +.@{fa-css-prefix}-google-plus-official:before { content: @fa-var-google-plus-official; } +.@{fa-css-prefix}-fa:before, +.@{fa-css-prefix}-font-awesome:before { content: @fa-var-font-awesome; } +.@{fa-css-prefix}-handshake-o:before { content: @fa-var-handshake-o; } +.@{fa-css-prefix}-envelope-open:before { content: @fa-var-envelope-open; } +.@{fa-css-prefix}-envelope-open-o:before { content: @fa-var-envelope-open-o; } +.@{fa-css-prefix}-linode:before { content: @fa-var-linode; } +.@{fa-css-prefix}-address-book:before { content: @fa-var-address-book; } +.@{fa-css-prefix}-address-book-o:before { content: @fa-var-address-book-o; } +.@{fa-css-prefix}-vcard:before, +.@{fa-css-prefix}-address-card:before { content: @fa-var-address-card; } +.@{fa-css-prefix}-vcard-o:before, +.@{fa-css-prefix}-address-card-o:before { content: @fa-var-address-card-o; } +.@{fa-css-prefix}-user-circle:before { content: @fa-var-user-circle; } +.@{fa-css-prefix}-user-circle-o:before { content: @fa-var-user-circle-o; } +.@{fa-css-prefix}-user-o:before { content: @fa-var-user-o; } +.@{fa-css-prefix}-id-badge:before { content: @fa-var-id-badge; } +.@{fa-css-prefix}-drivers-license:before, +.@{fa-css-prefix}-id-card:before { content: @fa-var-id-card; } +.@{fa-css-prefix}-drivers-license-o:before, +.@{fa-css-prefix}-id-card-o:before { content: @fa-var-id-card-o; } +.@{fa-css-prefix}-quora:before { content: @fa-var-quora; } +.@{fa-css-prefix}-free-code-camp:before { content: @fa-var-free-code-camp; } +.@{fa-css-prefix}-telegram:before { content: @fa-var-telegram; } +.@{fa-css-prefix}-thermometer-4:before, +.@{fa-css-prefix}-thermometer:before, +.@{fa-css-prefix}-thermometer-full:before { content: @fa-var-thermometer-full; } +.@{fa-css-prefix}-thermometer-3:before, +.@{fa-css-prefix}-thermometer-three-quarters:before { content: @fa-var-thermometer-three-quarters; } +.@{fa-css-prefix}-thermometer-2:before, +.@{fa-css-prefix}-thermometer-half:before { content: @fa-var-thermometer-half; } +.@{fa-css-prefix}-thermometer-1:before, +.@{fa-css-prefix}-thermometer-quarter:before { content: @fa-var-thermometer-quarter; } +.@{fa-css-prefix}-thermometer-0:before, +.@{fa-css-prefix}-thermometer-empty:before { content: @fa-var-thermometer-empty; } +.@{fa-css-prefix}-shower:before { content: @fa-var-shower; } +.@{fa-css-prefix}-bathtub:before, +.@{fa-css-prefix}-s15:before, +.@{fa-css-prefix}-bath:before { content: @fa-var-bath; } +.@{fa-css-prefix}-podcast:before { content: @fa-var-podcast; } +.@{fa-css-prefix}-window-maximize:before { content: @fa-var-window-maximize; } +.@{fa-css-prefix}-window-minimize:before { content: @fa-var-window-minimize; } +.@{fa-css-prefix}-window-restore:before { content: @fa-var-window-restore; } +.@{fa-css-prefix}-times-rectangle:before, +.@{fa-css-prefix}-window-close:before { content: @fa-var-window-close; } +.@{fa-css-prefix}-times-rectangle-o:before, +.@{fa-css-prefix}-window-close-o:before { content: @fa-var-window-close-o; } +.@{fa-css-prefix}-bandcamp:before { content: @fa-var-bandcamp; } +.@{fa-css-prefix}-grav:before { content: @fa-var-grav; } +.@{fa-css-prefix}-etsy:before { content: @fa-var-etsy; } +.@{fa-css-prefix}-imdb:before { content: @fa-var-imdb; } +.@{fa-css-prefix}-ravelry:before { content: @fa-var-ravelry; } +.@{fa-css-prefix}-eercast:before { content: @fa-var-eercast; } +.@{fa-css-prefix}-microchip:before { content: @fa-var-microchip; } +.@{fa-css-prefix}-snowflake-o:before { content: @fa-var-snowflake-o; } +.@{fa-css-prefix}-superpowers:before { content: @fa-var-superpowers; } +.@{fa-css-prefix}-wpexplorer:before { content: @fa-var-wpexplorer; } +.@{fa-css-prefix}-meetup:before { content: @fa-var-meetup; } diff --git a/js/font-awesome/less/larger.less b/js/font-awesome/less/larger.less new file mode 100644 index 000000000..c9d646770 --- /dev/null +++ b/js/font-awesome/less/larger.less @@ -0,0 +1,13 @@ +// Icon Sizes +// ------------------------- + +/* makes the font 33% larger relative to the icon container */ +.@{fa-css-prefix}-lg { + font-size: (4em / 3); + line-height: (3em / 4); + vertical-align: -15%; +} +.@{fa-css-prefix}-2x { font-size: 2em; } +.@{fa-css-prefix}-3x { font-size: 3em; } +.@{fa-css-prefix}-4x { font-size: 4em; } +.@{fa-css-prefix}-5x { font-size: 5em; } diff --git a/js/font-awesome/less/list.less b/js/font-awesome/less/list.less new file mode 100644 index 000000000..0b440382f --- /dev/null +++ b/js/font-awesome/less/list.less @@ -0,0 +1,19 @@ +// List Icons +// ------------------------- + +.@{fa-css-prefix}-ul { + padding-left: 0; + margin-left: @fa-li-width; + list-style-type: none; + > li { position: relative; } +} +.@{fa-css-prefix}-li { + position: absolute; + left: -@fa-li-width; + width: @fa-li-width; + top: (2em / 14); + text-align: center; + &.@{fa-css-prefix}-lg { + left: (-@fa-li-width + (4em / 14)); + } +} diff --git a/js/font-awesome/less/mixins.less b/js/font-awesome/less/mixins.less new file mode 100644 index 000000000..beef231d0 --- /dev/null +++ b/js/font-awesome/less/mixins.less @@ -0,0 +1,60 @@ +// Mixins +// -------------------------- + +.fa-icon() { + display: inline-block; + font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + +} + +.fa-icon-rotate(@degrees, @rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; + -webkit-transform: rotate(@degrees); + -ms-transform: rotate(@degrees); + transform: rotate(@degrees); +} + +.fa-icon-flip(@horiz, @vert, @rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; + -webkit-transform: scale(@horiz, @vert); + -ms-transform: scale(@horiz, @vert); + transform: scale(@horiz, @vert); +} + + +// Only display content to screen readers. A la Bootstrap 4. +// +// See: http://a11yproject.com/posts/how-to-hide-content/ + +.sr-only() { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0,0,0,0); + border: 0; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +.sr-only-focusable() { + &:active, + &:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; + } +} diff --git a/js/font-awesome/less/path.less b/js/font-awesome/less/path.less new file mode 100644 index 000000000..835be41f8 --- /dev/null +++ b/js/font-awesome/less/path.less @@ -0,0 +1,15 @@ +/* FONT PATH + * -------------------------- */ + +@font-face { + font-family: 'FontAwesome'; + src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); + src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), + url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), + url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), + url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), + url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); + // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts + font-weight: normal; + font-style: normal; +} diff --git a/js/font-awesome/less/rotated-flipped.less b/js/font-awesome/less/rotated-flipped.less new file mode 100644 index 000000000..f6ba81475 --- /dev/null +++ b/js/font-awesome/less/rotated-flipped.less @@ -0,0 +1,20 @@ +// Rotated & Flipped Icons +// ------------------------- + +.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } +.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } +.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } + +.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } +.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root .@{fa-css-prefix}-rotate-90, +:root .@{fa-css-prefix}-rotate-180, +:root .@{fa-css-prefix}-rotate-270, +:root .@{fa-css-prefix}-flip-horizontal, +:root .@{fa-css-prefix}-flip-vertical { + filter: none; +} diff --git a/js/font-awesome/less/screen-reader.less b/js/font-awesome/less/screen-reader.less new file mode 100644 index 000000000..11c188196 --- /dev/null +++ b/js/font-awesome/less/screen-reader.less @@ -0,0 +1,5 @@ +// Screen Readers +// ------------------------- + +.sr-only { .sr-only(); } +.sr-only-focusable { .sr-only-focusable(); } diff --git a/js/font-awesome/less/stacked.less b/js/font-awesome/less/stacked.less new file mode 100644 index 000000000..fc53fb0e7 --- /dev/null +++ b/js/font-awesome/less/stacked.less @@ -0,0 +1,20 @@ +// Stacked Icons +// ------------------------- + +.@{fa-css-prefix}-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.@{fa-css-prefix}-stack-1x { line-height: inherit; } +.@{fa-css-prefix}-stack-2x { font-size: 2em; } +.@{fa-css-prefix}-inverse { color: @fa-inverse; } diff --git a/js/font-awesome/less/variables.less b/js/font-awesome/less/variables.less new file mode 100644 index 000000000..7ddbbc011 --- /dev/null +++ b/js/font-awesome/less/variables.less @@ -0,0 +1,800 @@ +// Variables +// -------------------------- + +@fa-font-path: "../fonts"; +@fa-font-size-base: 14px; +@fa-line-height-base: 1; +//@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.7.0/fonts"; // for referencing Bootstrap CDN font files directly +@fa-css-prefix: fa; +@fa-version: "4.7.0"; +@fa-border-color: #eee; +@fa-inverse: #fff; +@fa-li-width: (30em / 14); + +@fa-var-500px: "\f26e"; +@fa-var-address-book: "\f2b9"; +@fa-var-address-book-o: "\f2ba"; +@fa-var-address-card: "\f2bb"; +@fa-var-address-card-o: "\f2bc"; +@fa-var-adjust: "\f042"; +@fa-var-adn: "\f170"; +@fa-var-align-center: "\f037"; +@fa-var-align-justify: "\f039"; +@fa-var-align-left: "\f036"; +@fa-var-align-right: "\f038"; +@fa-var-amazon: "\f270"; +@fa-var-ambulance: "\f0f9"; +@fa-var-american-sign-language-interpreting: "\f2a3"; +@fa-var-anchor: "\f13d"; +@fa-var-android: "\f17b"; +@fa-var-angellist: "\f209"; +@fa-var-angle-double-down: "\f103"; +@fa-var-angle-double-left: "\f100"; +@fa-var-angle-double-right: "\f101"; +@fa-var-angle-double-up: "\f102"; +@fa-var-angle-down: "\f107"; +@fa-var-angle-left: "\f104"; +@fa-var-angle-right: "\f105"; +@fa-var-angle-up: "\f106"; +@fa-var-apple: "\f179"; +@fa-var-archive: "\f187"; +@fa-var-area-chart: "\f1fe"; +@fa-var-arrow-circle-down: "\f0ab"; +@fa-var-arrow-circle-left: "\f0a8"; +@fa-var-arrow-circle-o-down: "\f01a"; +@fa-var-arrow-circle-o-left: "\f190"; +@fa-var-arrow-circle-o-right: "\f18e"; +@fa-var-arrow-circle-o-up: "\f01b"; +@fa-var-arrow-circle-right: "\f0a9"; +@fa-var-arrow-circle-up: "\f0aa"; +@fa-var-arrow-down: "\f063"; +@fa-var-arrow-left: "\f060"; +@fa-var-arrow-right: "\f061"; +@fa-var-arrow-up: "\f062"; +@fa-var-arrows: "\f047"; +@fa-var-arrows-alt: "\f0b2"; +@fa-var-arrows-h: "\f07e"; +@fa-var-arrows-v: "\f07d"; +@fa-var-asl-interpreting: "\f2a3"; +@fa-var-assistive-listening-systems: "\f2a2"; +@fa-var-asterisk: "\f069"; +@fa-var-at: "\f1fa"; +@fa-var-audio-description: "\f29e"; +@fa-var-automobile: "\f1b9"; +@fa-var-backward: "\f04a"; +@fa-var-balance-scale: "\f24e"; +@fa-var-ban: "\f05e"; +@fa-var-bandcamp: "\f2d5"; +@fa-var-bank: "\f19c"; +@fa-var-bar-chart: "\f080"; +@fa-var-bar-chart-o: "\f080"; +@fa-var-barcode: "\f02a"; +@fa-var-bars: "\f0c9"; +@fa-var-bath: "\f2cd"; +@fa-var-bathtub: "\f2cd"; +@fa-var-battery: "\f240"; +@fa-var-battery-0: "\f244"; +@fa-var-battery-1: "\f243"; +@fa-var-battery-2: "\f242"; +@fa-var-battery-3: "\f241"; +@fa-var-battery-4: "\f240"; +@fa-var-battery-empty: "\f244"; +@fa-var-battery-full: "\f240"; +@fa-var-battery-half: "\f242"; +@fa-var-battery-quarter: "\f243"; +@fa-var-battery-three-quarters: "\f241"; +@fa-var-bed: "\f236"; +@fa-var-beer: "\f0fc"; +@fa-var-behance: "\f1b4"; +@fa-var-behance-square: "\f1b5"; +@fa-var-bell: "\f0f3"; +@fa-var-bell-o: "\f0a2"; +@fa-var-bell-slash: "\f1f6"; +@fa-var-bell-slash-o: "\f1f7"; +@fa-var-bicycle: "\f206"; +@fa-var-binoculars: "\f1e5"; +@fa-var-birthday-cake: "\f1fd"; +@fa-var-bitbucket: "\f171"; +@fa-var-bitbucket-square: "\f172"; +@fa-var-bitcoin: "\f15a"; +@fa-var-black-tie: "\f27e"; +@fa-var-blind: "\f29d"; +@fa-var-bluetooth: "\f293"; +@fa-var-bluetooth-b: "\f294"; +@fa-var-bold: "\f032"; +@fa-var-bolt: "\f0e7"; +@fa-var-bomb: "\f1e2"; +@fa-var-book: "\f02d"; +@fa-var-bookmark: "\f02e"; +@fa-var-bookmark-o: "\f097"; +@fa-var-braille: "\f2a1"; +@fa-var-briefcase: "\f0b1"; +@fa-var-btc: "\f15a"; +@fa-var-bug: "\f188"; +@fa-var-building: "\f1ad"; +@fa-var-building-o: "\f0f7"; +@fa-var-bullhorn: "\f0a1"; +@fa-var-bullseye: "\f140"; +@fa-var-bus: "\f207"; +@fa-var-buysellads: "\f20d"; +@fa-var-cab: "\f1ba"; +@fa-var-calculator: "\f1ec"; +@fa-var-calendar: "\f073"; +@fa-var-calendar-check-o: "\f274"; +@fa-var-calendar-minus-o: "\f272"; +@fa-var-calendar-o: "\f133"; +@fa-var-calendar-plus-o: "\f271"; +@fa-var-calendar-times-o: "\f273"; +@fa-var-camera: "\f030"; +@fa-var-camera-retro: "\f083"; +@fa-var-car: "\f1b9"; +@fa-var-caret-down: "\f0d7"; +@fa-var-caret-left: "\f0d9"; +@fa-var-caret-right: "\f0da"; +@fa-var-caret-square-o-down: "\f150"; +@fa-var-caret-square-o-left: "\f191"; +@fa-var-caret-square-o-right: "\f152"; +@fa-var-caret-square-o-up: "\f151"; +@fa-var-caret-up: "\f0d8"; +@fa-var-cart-arrow-down: "\f218"; +@fa-var-cart-plus: "\f217"; +@fa-var-cc: "\f20a"; +@fa-var-cc-amex: "\f1f3"; +@fa-var-cc-diners-club: "\f24c"; +@fa-var-cc-discover: "\f1f2"; +@fa-var-cc-jcb: "\f24b"; +@fa-var-cc-mastercard: "\f1f1"; +@fa-var-cc-paypal: "\f1f4"; +@fa-var-cc-stripe: "\f1f5"; +@fa-var-cc-visa: "\f1f0"; +@fa-var-certificate: "\f0a3"; +@fa-var-chain: "\f0c1"; +@fa-var-chain-broken: "\f127"; +@fa-var-check: "\f00c"; +@fa-var-check-circle: "\f058"; +@fa-var-check-circle-o: "\f05d"; +@fa-var-check-square: "\f14a"; +@fa-var-check-square-o: "\f046"; +@fa-var-chevron-circle-down: "\f13a"; +@fa-var-chevron-circle-left: "\f137"; +@fa-var-chevron-circle-right: "\f138"; +@fa-var-chevron-circle-up: "\f139"; +@fa-var-chevron-down: "\f078"; +@fa-var-chevron-left: "\f053"; +@fa-var-chevron-right: "\f054"; +@fa-var-chevron-up: "\f077"; +@fa-var-child: "\f1ae"; +@fa-var-chrome: "\f268"; +@fa-var-circle: "\f111"; +@fa-var-circle-o: "\f10c"; +@fa-var-circle-o-notch: "\f1ce"; +@fa-var-circle-thin: "\f1db"; +@fa-var-clipboard: "\f0ea"; +@fa-var-clock-o: "\f017"; +@fa-var-clone: "\f24d"; +@fa-var-close: "\f00d"; +@fa-var-cloud: "\f0c2"; +@fa-var-cloud-download: "\f0ed"; +@fa-var-cloud-upload: "\f0ee"; +@fa-var-cny: "\f157"; +@fa-var-code: "\f121"; +@fa-var-code-fork: "\f126"; +@fa-var-codepen: "\f1cb"; +@fa-var-codiepie: "\f284"; +@fa-var-coffee: "\f0f4"; +@fa-var-cog: "\f013"; +@fa-var-cogs: "\f085"; +@fa-var-columns: "\f0db"; +@fa-var-comment: "\f075"; +@fa-var-comment-o: "\f0e5"; +@fa-var-commenting: "\f27a"; +@fa-var-commenting-o: "\f27b"; +@fa-var-comments: "\f086"; +@fa-var-comments-o: "\f0e6"; +@fa-var-compass: "\f14e"; +@fa-var-compress: "\f066"; +@fa-var-connectdevelop: "\f20e"; +@fa-var-contao: "\f26d"; +@fa-var-copy: "\f0c5"; +@fa-var-copyright: "\f1f9"; +@fa-var-creative-commons: "\f25e"; +@fa-var-credit-card: "\f09d"; +@fa-var-credit-card-alt: "\f283"; +@fa-var-crop: "\f125"; +@fa-var-crosshairs: "\f05b"; +@fa-var-css3: "\f13c"; +@fa-var-cube: "\f1b2"; +@fa-var-cubes: "\f1b3"; +@fa-var-cut: "\f0c4"; +@fa-var-cutlery: "\f0f5"; +@fa-var-dashboard: "\f0e4"; +@fa-var-dashcube: "\f210"; +@fa-var-database: "\f1c0"; +@fa-var-deaf: "\f2a4"; +@fa-var-deafness: "\f2a4"; +@fa-var-dedent: "\f03b"; +@fa-var-delicious: "\f1a5"; +@fa-var-desktop: "\f108"; +@fa-var-deviantart: "\f1bd"; +@fa-var-diamond: "\f219"; +@fa-var-digg: "\f1a6"; +@fa-var-dollar: "\f155"; +@fa-var-dot-circle-o: "\f192"; +@fa-var-download: "\f019"; +@fa-var-dribbble: "\f17d"; +@fa-var-drivers-license: "\f2c2"; +@fa-var-drivers-license-o: "\f2c3"; +@fa-var-dropbox: "\f16b"; +@fa-var-drupal: "\f1a9"; +@fa-var-edge: "\f282"; +@fa-var-edit: "\f044"; +@fa-var-eercast: "\f2da"; +@fa-var-eject: "\f052"; +@fa-var-ellipsis-h: "\f141"; +@fa-var-ellipsis-v: "\f142"; +@fa-var-empire: "\f1d1"; +@fa-var-envelope: "\f0e0"; +@fa-var-envelope-o: "\f003"; +@fa-var-envelope-open: "\f2b6"; +@fa-var-envelope-open-o: "\f2b7"; +@fa-var-envelope-square: "\f199"; +@fa-var-envira: "\f299"; +@fa-var-eraser: "\f12d"; +@fa-var-etsy: "\f2d7"; +@fa-var-eur: "\f153"; +@fa-var-euro: "\f153"; +@fa-var-exchange: "\f0ec"; +@fa-var-exclamation: "\f12a"; +@fa-var-exclamation-circle: "\f06a"; +@fa-var-exclamation-triangle: "\f071"; +@fa-var-expand: "\f065"; +@fa-var-expeditedssl: "\f23e"; +@fa-var-external-link: "\f08e"; +@fa-var-external-link-square: "\f14c"; +@fa-var-eye: "\f06e"; +@fa-var-eye-slash: "\f070"; +@fa-var-eyedropper: "\f1fb"; +@fa-var-fa: "\f2b4"; +@fa-var-facebook: "\f09a"; +@fa-var-facebook-f: "\f09a"; +@fa-var-facebook-official: "\f230"; +@fa-var-facebook-square: "\f082"; +@fa-var-fast-backward: "\f049"; +@fa-var-fast-forward: "\f050"; +@fa-var-fax: "\f1ac"; +@fa-var-feed: "\f09e"; +@fa-var-female: "\f182"; +@fa-var-fighter-jet: "\f0fb"; +@fa-var-file: "\f15b"; +@fa-var-file-archive-o: "\f1c6"; +@fa-var-file-audio-o: "\f1c7"; +@fa-var-file-code-o: "\f1c9"; +@fa-var-file-excel-o: "\f1c3"; +@fa-var-file-image-o: "\f1c5"; +@fa-var-file-movie-o: "\f1c8"; +@fa-var-file-o: "\f016"; +@fa-var-file-pdf-o: "\f1c1"; +@fa-var-file-photo-o: "\f1c5"; +@fa-var-file-picture-o: "\f1c5"; +@fa-var-file-powerpoint-o: "\f1c4"; +@fa-var-file-sound-o: "\f1c7"; +@fa-var-file-text: "\f15c"; +@fa-var-file-text-o: "\f0f6"; +@fa-var-file-video-o: "\f1c8"; +@fa-var-file-word-o: "\f1c2"; +@fa-var-file-zip-o: "\f1c6"; +@fa-var-files-o: "\f0c5"; +@fa-var-film: "\f008"; +@fa-var-filter: "\f0b0"; +@fa-var-fire: "\f06d"; +@fa-var-fire-extinguisher: "\f134"; +@fa-var-firefox: "\f269"; +@fa-var-first-order: "\f2b0"; +@fa-var-flag: "\f024"; +@fa-var-flag-checkered: "\f11e"; +@fa-var-flag-o: "\f11d"; +@fa-var-flash: "\f0e7"; +@fa-var-flask: "\f0c3"; +@fa-var-flickr: "\f16e"; +@fa-var-floppy-o: "\f0c7"; +@fa-var-folder: "\f07b"; +@fa-var-folder-o: "\f114"; +@fa-var-folder-open: "\f07c"; +@fa-var-folder-open-o: "\f115"; +@fa-var-font: "\f031"; +@fa-var-font-awesome: "\f2b4"; +@fa-var-fonticons: "\f280"; +@fa-var-fort-awesome: "\f286"; +@fa-var-forumbee: "\f211"; +@fa-var-forward: "\f04e"; +@fa-var-foursquare: "\f180"; +@fa-var-free-code-camp: "\f2c5"; +@fa-var-frown-o: "\f119"; +@fa-var-futbol-o: "\f1e3"; +@fa-var-gamepad: "\f11b"; +@fa-var-gavel: "\f0e3"; +@fa-var-gbp: "\f154"; +@fa-var-ge: "\f1d1"; +@fa-var-gear: "\f013"; +@fa-var-gears: "\f085"; +@fa-var-genderless: "\f22d"; +@fa-var-get-pocket: "\f265"; +@fa-var-gg: "\f260"; +@fa-var-gg-circle: "\f261"; +@fa-var-gift: "\f06b"; +@fa-var-git: "\f1d3"; +@fa-var-git-square: "\f1d2"; +@fa-var-github: "\f09b"; +@fa-var-github-alt: "\f113"; +@fa-var-github-square: "\f092"; +@fa-var-gitlab: "\f296"; +@fa-var-gittip: "\f184"; +@fa-var-glass: "\f000"; +@fa-var-glide: "\f2a5"; +@fa-var-glide-g: "\f2a6"; +@fa-var-globe: "\f0ac"; +@fa-var-google: "\f1a0"; +@fa-var-google-plus: "\f0d5"; +@fa-var-google-plus-circle: "\f2b3"; +@fa-var-google-plus-official: "\f2b3"; +@fa-var-google-plus-square: "\f0d4"; +@fa-var-google-wallet: "\f1ee"; +@fa-var-graduation-cap: "\f19d"; +@fa-var-gratipay: "\f184"; +@fa-var-grav: "\f2d6"; +@fa-var-group: "\f0c0"; +@fa-var-h-square: "\f0fd"; +@fa-var-hacker-news: "\f1d4"; +@fa-var-hand-grab-o: "\f255"; +@fa-var-hand-lizard-o: "\f258"; +@fa-var-hand-o-down: "\f0a7"; +@fa-var-hand-o-left: "\f0a5"; +@fa-var-hand-o-right: "\f0a4"; +@fa-var-hand-o-up: "\f0a6"; +@fa-var-hand-paper-o: "\f256"; +@fa-var-hand-peace-o: "\f25b"; +@fa-var-hand-pointer-o: "\f25a"; +@fa-var-hand-rock-o: "\f255"; +@fa-var-hand-scissors-o: "\f257"; +@fa-var-hand-spock-o: "\f259"; +@fa-var-hand-stop-o: "\f256"; +@fa-var-handshake-o: "\f2b5"; +@fa-var-hard-of-hearing: "\f2a4"; +@fa-var-hashtag: "\f292"; +@fa-var-hdd-o: "\f0a0"; +@fa-var-header: "\f1dc"; +@fa-var-headphones: "\f025"; +@fa-var-heart: "\f004"; +@fa-var-heart-o: "\f08a"; +@fa-var-heartbeat: "\f21e"; +@fa-var-history: "\f1da"; +@fa-var-home: "\f015"; +@fa-var-hospital-o: "\f0f8"; +@fa-var-hotel: "\f236"; +@fa-var-hourglass: "\f254"; +@fa-var-hourglass-1: "\f251"; +@fa-var-hourglass-2: "\f252"; +@fa-var-hourglass-3: "\f253"; +@fa-var-hourglass-end: "\f253"; +@fa-var-hourglass-half: "\f252"; +@fa-var-hourglass-o: "\f250"; +@fa-var-hourglass-start: "\f251"; +@fa-var-houzz: "\f27c"; +@fa-var-html5: "\f13b"; +@fa-var-i-cursor: "\f246"; +@fa-var-id-badge: "\f2c1"; +@fa-var-id-card: "\f2c2"; +@fa-var-id-card-o: "\f2c3"; +@fa-var-ils: "\f20b"; +@fa-var-image: "\f03e"; +@fa-var-imdb: "\f2d8"; +@fa-var-inbox: "\f01c"; +@fa-var-indent: "\f03c"; +@fa-var-industry: "\f275"; +@fa-var-info: "\f129"; +@fa-var-info-circle: "\f05a"; +@fa-var-inr: "\f156"; +@fa-var-instagram: "\f16d"; +@fa-var-institution: "\f19c"; +@fa-var-internet-explorer: "\f26b"; +@fa-var-intersex: "\f224"; +@fa-var-ioxhost: "\f208"; +@fa-var-italic: "\f033"; +@fa-var-joomla: "\f1aa"; +@fa-var-jpy: "\f157"; +@fa-var-jsfiddle: "\f1cc"; +@fa-var-key: "\f084"; +@fa-var-keyboard-o: "\f11c"; +@fa-var-krw: "\f159"; +@fa-var-language: "\f1ab"; +@fa-var-laptop: "\f109"; +@fa-var-lastfm: "\f202"; +@fa-var-lastfm-square: "\f203"; +@fa-var-leaf: "\f06c"; +@fa-var-leanpub: "\f212"; +@fa-var-legal: "\f0e3"; +@fa-var-lemon-o: "\f094"; +@fa-var-level-down: "\f149"; +@fa-var-level-up: "\f148"; +@fa-var-life-bouy: "\f1cd"; +@fa-var-life-buoy: "\f1cd"; +@fa-var-life-ring: "\f1cd"; +@fa-var-life-saver: "\f1cd"; +@fa-var-lightbulb-o: "\f0eb"; +@fa-var-line-chart: "\f201"; +@fa-var-link: "\f0c1"; +@fa-var-linkedin: "\f0e1"; +@fa-var-linkedin-square: "\f08c"; +@fa-var-linode: "\f2b8"; +@fa-var-linux: "\f17c"; +@fa-var-list: "\f03a"; +@fa-var-list-alt: "\f022"; +@fa-var-list-ol: "\f0cb"; +@fa-var-list-ul: "\f0ca"; +@fa-var-location-arrow: "\f124"; +@fa-var-lock: "\f023"; +@fa-var-long-arrow-down: "\f175"; +@fa-var-long-arrow-left: "\f177"; +@fa-var-long-arrow-right: "\f178"; +@fa-var-long-arrow-up: "\f176"; +@fa-var-low-vision: "\f2a8"; +@fa-var-magic: "\f0d0"; +@fa-var-magnet: "\f076"; +@fa-var-mail-forward: "\f064"; +@fa-var-mail-reply: "\f112"; +@fa-var-mail-reply-all: "\f122"; +@fa-var-male: "\f183"; +@fa-var-map: "\f279"; +@fa-var-map-marker: "\f041"; +@fa-var-map-o: "\f278"; +@fa-var-map-pin: "\f276"; +@fa-var-map-signs: "\f277"; +@fa-var-mars: "\f222"; +@fa-var-mars-double: "\f227"; +@fa-var-mars-stroke: "\f229"; +@fa-var-mars-stroke-h: "\f22b"; +@fa-var-mars-stroke-v: "\f22a"; +@fa-var-maxcdn: "\f136"; +@fa-var-meanpath: "\f20c"; +@fa-var-medium: "\f23a"; +@fa-var-medkit: "\f0fa"; +@fa-var-meetup: "\f2e0"; +@fa-var-meh-o: "\f11a"; +@fa-var-mercury: "\f223"; +@fa-var-microchip: "\f2db"; +@fa-var-microphone: "\f130"; +@fa-var-microphone-slash: "\f131"; +@fa-var-minus: "\f068"; +@fa-var-minus-circle: "\f056"; +@fa-var-minus-square: "\f146"; +@fa-var-minus-square-o: "\f147"; +@fa-var-mixcloud: "\f289"; +@fa-var-mobile: "\f10b"; +@fa-var-mobile-phone: "\f10b"; +@fa-var-modx: "\f285"; +@fa-var-money: "\f0d6"; +@fa-var-moon-o: "\f186"; +@fa-var-mortar-board: "\f19d"; +@fa-var-motorcycle: "\f21c"; +@fa-var-mouse-pointer: "\f245"; +@fa-var-music: "\f001"; +@fa-var-navicon: "\f0c9"; +@fa-var-neuter: "\f22c"; +@fa-var-newspaper-o: "\f1ea"; +@fa-var-object-group: "\f247"; +@fa-var-object-ungroup: "\f248"; +@fa-var-odnoklassniki: "\f263"; +@fa-var-odnoklassniki-square: "\f264"; +@fa-var-opencart: "\f23d"; +@fa-var-openid: "\f19b"; +@fa-var-opera: "\f26a"; +@fa-var-optin-monster: "\f23c"; +@fa-var-outdent: "\f03b"; +@fa-var-pagelines: "\f18c"; +@fa-var-paint-brush: "\f1fc"; +@fa-var-paper-plane: "\f1d8"; +@fa-var-paper-plane-o: "\f1d9"; +@fa-var-paperclip: "\f0c6"; +@fa-var-paragraph: "\f1dd"; +@fa-var-paste: "\f0ea"; +@fa-var-pause: "\f04c"; +@fa-var-pause-circle: "\f28b"; +@fa-var-pause-circle-o: "\f28c"; +@fa-var-paw: "\f1b0"; +@fa-var-paypal: "\f1ed"; +@fa-var-pencil: "\f040"; +@fa-var-pencil-square: "\f14b"; +@fa-var-pencil-square-o: "\f044"; +@fa-var-percent: "\f295"; +@fa-var-phone: "\f095"; +@fa-var-phone-square: "\f098"; +@fa-var-photo: "\f03e"; +@fa-var-picture-o: "\f03e"; +@fa-var-pie-chart: "\f200"; +@fa-var-pied-piper: "\f2ae"; +@fa-var-pied-piper-alt: "\f1a8"; +@fa-var-pied-piper-pp: "\f1a7"; +@fa-var-pinterest: "\f0d2"; +@fa-var-pinterest-p: "\f231"; +@fa-var-pinterest-square: "\f0d3"; +@fa-var-plane: "\f072"; +@fa-var-play: "\f04b"; +@fa-var-play-circle: "\f144"; +@fa-var-play-circle-o: "\f01d"; +@fa-var-plug: "\f1e6"; +@fa-var-plus: "\f067"; +@fa-var-plus-circle: "\f055"; +@fa-var-plus-square: "\f0fe"; +@fa-var-plus-square-o: "\f196"; +@fa-var-podcast: "\f2ce"; +@fa-var-power-off: "\f011"; +@fa-var-print: "\f02f"; +@fa-var-product-hunt: "\f288"; +@fa-var-puzzle-piece: "\f12e"; +@fa-var-qq: "\f1d6"; +@fa-var-qrcode: "\f029"; +@fa-var-question: "\f128"; +@fa-var-question-circle: "\f059"; +@fa-var-question-circle-o: "\f29c"; +@fa-var-quora: "\f2c4"; +@fa-var-quote-left: "\f10d"; +@fa-var-quote-right: "\f10e"; +@fa-var-ra: "\f1d0"; +@fa-var-random: "\f074"; +@fa-var-ravelry: "\f2d9"; +@fa-var-rebel: "\f1d0"; +@fa-var-recycle: "\f1b8"; +@fa-var-reddit: "\f1a1"; +@fa-var-reddit-alien: "\f281"; +@fa-var-reddit-square: "\f1a2"; +@fa-var-refresh: "\f021"; +@fa-var-registered: "\f25d"; +@fa-var-remove: "\f00d"; +@fa-var-renren: "\f18b"; +@fa-var-reorder: "\f0c9"; +@fa-var-repeat: "\f01e"; +@fa-var-reply: "\f112"; +@fa-var-reply-all: "\f122"; +@fa-var-resistance: "\f1d0"; +@fa-var-retweet: "\f079"; +@fa-var-rmb: "\f157"; +@fa-var-road: "\f018"; +@fa-var-rocket: "\f135"; +@fa-var-rotate-left: "\f0e2"; +@fa-var-rotate-right: "\f01e"; +@fa-var-rouble: "\f158"; +@fa-var-rss: "\f09e"; +@fa-var-rss-square: "\f143"; +@fa-var-rub: "\f158"; +@fa-var-ruble: "\f158"; +@fa-var-rupee: "\f156"; +@fa-var-s15: "\f2cd"; +@fa-var-safari: "\f267"; +@fa-var-save: "\f0c7"; +@fa-var-scissors: "\f0c4"; +@fa-var-scribd: "\f28a"; +@fa-var-search: "\f002"; +@fa-var-search-minus: "\f010"; +@fa-var-search-plus: "\f00e"; +@fa-var-sellsy: "\f213"; +@fa-var-send: "\f1d8"; +@fa-var-send-o: "\f1d9"; +@fa-var-server: "\f233"; +@fa-var-share: "\f064"; +@fa-var-share-alt: "\f1e0"; +@fa-var-share-alt-square: "\f1e1"; +@fa-var-share-square: "\f14d"; +@fa-var-share-square-o: "\f045"; +@fa-var-shekel: "\f20b"; +@fa-var-sheqel: "\f20b"; +@fa-var-shield: "\f132"; +@fa-var-ship: "\f21a"; +@fa-var-shirtsinbulk: "\f214"; +@fa-var-shopping-bag: "\f290"; +@fa-var-shopping-basket: "\f291"; +@fa-var-shopping-cart: "\f07a"; +@fa-var-shower: "\f2cc"; +@fa-var-sign-in: "\f090"; +@fa-var-sign-language: "\f2a7"; +@fa-var-sign-out: "\f08b"; +@fa-var-signal: "\f012"; +@fa-var-signing: "\f2a7"; +@fa-var-simplybuilt: "\f215"; +@fa-var-sitemap: "\f0e8"; +@fa-var-skyatlas: "\f216"; +@fa-var-skype: "\f17e"; +@fa-var-slack: "\f198"; +@fa-var-sliders: "\f1de"; +@fa-var-slideshare: "\f1e7"; +@fa-var-smile-o: "\f118"; +@fa-var-snapchat: "\f2ab"; +@fa-var-snapchat-ghost: "\f2ac"; +@fa-var-snapchat-square: "\f2ad"; +@fa-var-snowflake-o: "\f2dc"; +@fa-var-soccer-ball-o: "\f1e3"; +@fa-var-sort: "\f0dc"; +@fa-var-sort-alpha-asc: "\f15d"; +@fa-var-sort-alpha-desc: "\f15e"; +@fa-var-sort-amount-asc: "\f160"; +@fa-var-sort-amount-desc: "\f161"; +@fa-var-sort-asc: "\f0de"; +@fa-var-sort-desc: "\f0dd"; +@fa-var-sort-down: "\f0dd"; +@fa-var-sort-numeric-asc: "\f162"; +@fa-var-sort-numeric-desc: "\f163"; +@fa-var-sort-up: "\f0de"; +@fa-var-soundcloud: "\f1be"; +@fa-var-space-shuttle: "\f197"; +@fa-var-spinner: "\f110"; +@fa-var-spoon: "\f1b1"; +@fa-var-spotify: "\f1bc"; +@fa-var-square: "\f0c8"; +@fa-var-square-o: "\f096"; +@fa-var-stack-exchange: "\f18d"; +@fa-var-stack-overflow: "\f16c"; +@fa-var-star: "\f005"; +@fa-var-star-half: "\f089"; +@fa-var-star-half-empty: "\f123"; +@fa-var-star-half-full: "\f123"; +@fa-var-star-half-o: "\f123"; +@fa-var-star-o: "\f006"; +@fa-var-steam: "\f1b6"; +@fa-var-steam-square: "\f1b7"; +@fa-var-step-backward: "\f048"; +@fa-var-step-forward: "\f051"; +@fa-var-stethoscope: "\f0f1"; +@fa-var-sticky-note: "\f249"; +@fa-var-sticky-note-o: "\f24a"; +@fa-var-stop: "\f04d"; +@fa-var-stop-circle: "\f28d"; +@fa-var-stop-circle-o: "\f28e"; +@fa-var-street-view: "\f21d"; +@fa-var-strikethrough: "\f0cc"; +@fa-var-stumbleupon: "\f1a4"; +@fa-var-stumbleupon-circle: "\f1a3"; +@fa-var-subscript: "\f12c"; +@fa-var-subway: "\f239"; +@fa-var-suitcase: "\f0f2"; +@fa-var-sun-o: "\f185"; +@fa-var-superpowers: "\f2dd"; +@fa-var-superscript: "\f12b"; +@fa-var-support: "\f1cd"; +@fa-var-table: "\f0ce"; +@fa-var-tablet: "\f10a"; +@fa-var-tachometer: "\f0e4"; +@fa-var-tag: "\f02b"; +@fa-var-tags: "\f02c"; +@fa-var-tasks: "\f0ae"; +@fa-var-taxi: "\f1ba"; +@fa-var-telegram: "\f2c6"; +@fa-var-television: "\f26c"; +@fa-var-tencent-weibo: "\f1d5"; +@fa-var-terminal: "\f120"; +@fa-var-text-height: "\f034"; +@fa-var-text-width: "\f035"; +@fa-var-th: "\f00a"; +@fa-var-th-large: "\f009"; +@fa-var-th-list: "\f00b"; +@fa-var-themeisle: "\f2b2"; +@fa-var-thermometer: "\f2c7"; +@fa-var-thermometer-0: "\f2cb"; +@fa-var-thermometer-1: "\f2ca"; +@fa-var-thermometer-2: "\f2c9"; +@fa-var-thermometer-3: "\f2c8"; +@fa-var-thermometer-4: "\f2c7"; +@fa-var-thermometer-empty: "\f2cb"; +@fa-var-thermometer-full: "\f2c7"; +@fa-var-thermometer-half: "\f2c9"; +@fa-var-thermometer-quarter: "\f2ca"; +@fa-var-thermometer-three-quarters: "\f2c8"; +@fa-var-thumb-tack: "\f08d"; +@fa-var-thumbs-down: "\f165"; +@fa-var-thumbs-o-down: "\f088"; +@fa-var-thumbs-o-up: "\f087"; +@fa-var-thumbs-up: "\f164"; +@fa-var-ticket: "\f145"; +@fa-var-times: "\f00d"; +@fa-var-times-circle: "\f057"; +@fa-var-times-circle-o: "\f05c"; +@fa-var-times-rectangle: "\f2d3"; +@fa-var-times-rectangle-o: "\f2d4"; +@fa-var-tint: "\f043"; +@fa-var-toggle-down: "\f150"; +@fa-var-toggle-left: "\f191"; +@fa-var-toggle-off: "\f204"; +@fa-var-toggle-on: "\f205"; +@fa-var-toggle-right: "\f152"; +@fa-var-toggle-up: "\f151"; +@fa-var-trademark: "\f25c"; +@fa-var-train: "\f238"; +@fa-var-transgender: "\f224"; +@fa-var-transgender-alt: "\f225"; +@fa-var-trash: "\f1f8"; +@fa-var-trash-o: "\f014"; +@fa-var-tree: "\f1bb"; +@fa-var-trello: "\f181"; +@fa-var-tripadvisor: "\f262"; +@fa-var-trophy: "\f091"; +@fa-var-truck: "\f0d1"; +@fa-var-try: "\f195"; +@fa-var-tty: "\f1e4"; +@fa-var-tumblr: "\f173"; +@fa-var-tumblr-square: "\f174"; +@fa-var-turkish-lira: "\f195"; +@fa-var-tv: "\f26c"; +@fa-var-twitch: "\f1e8"; +@fa-var-twitter: "\f099"; +@fa-var-twitter-square: "\f081"; +@fa-var-umbrella: "\f0e9"; +@fa-var-underline: "\f0cd"; +@fa-var-undo: "\f0e2"; +@fa-var-universal-access: "\f29a"; +@fa-var-university: "\f19c"; +@fa-var-unlink: "\f127"; +@fa-var-unlock: "\f09c"; +@fa-var-unlock-alt: "\f13e"; +@fa-var-unsorted: "\f0dc"; +@fa-var-upload: "\f093"; +@fa-var-usb: "\f287"; +@fa-var-usd: "\f155"; +@fa-var-user: "\f007"; +@fa-var-user-circle: "\f2bd"; +@fa-var-user-circle-o: "\f2be"; +@fa-var-user-md: "\f0f0"; +@fa-var-user-o: "\f2c0"; +@fa-var-user-plus: "\f234"; +@fa-var-user-secret: "\f21b"; +@fa-var-user-times: "\f235"; +@fa-var-users: "\f0c0"; +@fa-var-vcard: "\f2bb"; +@fa-var-vcard-o: "\f2bc"; +@fa-var-venus: "\f221"; +@fa-var-venus-double: "\f226"; +@fa-var-venus-mars: "\f228"; +@fa-var-viacoin: "\f237"; +@fa-var-viadeo: "\f2a9"; +@fa-var-viadeo-square: "\f2aa"; +@fa-var-video-camera: "\f03d"; +@fa-var-vimeo: "\f27d"; +@fa-var-vimeo-square: "\f194"; +@fa-var-vine: "\f1ca"; +@fa-var-vk: "\f189"; +@fa-var-volume-control-phone: "\f2a0"; +@fa-var-volume-down: "\f027"; +@fa-var-volume-off: "\f026"; +@fa-var-volume-up: "\f028"; +@fa-var-warning: "\f071"; +@fa-var-wechat: "\f1d7"; +@fa-var-weibo: "\f18a"; +@fa-var-weixin: "\f1d7"; +@fa-var-whatsapp: "\f232"; +@fa-var-wheelchair: "\f193"; +@fa-var-wheelchair-alt: "\f29b"; +@fa-var-wifi: "\f1eb"; +@fa-var-wikipedia-w: "\f266"; +@fa-var-window-close: "\f2d3"; +@fa-var-window-close-o: "\f2d4"; +@fa-var-window-maximize: "\f2d0"; +@fa-var-window-minimize: "\f2d1"; +@fa-var-window-restore: "\f2d2"; +@fa-var-windows: "\f17a"; +@fa-var-won: "\f159"; +@fa-var-wordpress: "\f19a"; +@fa-var-wpbeginner: "\f297"; +@fa-var-wpexplorer: "\f2de"; +@fa-var-wpforms: "\f298"; +@fa-var-wrench: "\f0ad"; +@fa-var-xing: "\f168"; +@fa-var-xing-square: "\f169"; +@fa-var-y-combinator: "\f23b"; +@fa-var-y-combinator-square: "\f1d4"; +@fa-var-yahoo: "\f19e"; +@fa-var-yc: "\f23b"; +@fa-var-yc-square: "\f1d4"; +@fa-var-yelp: "\f1e9"; +@fa-var-yen: "\f157"; +@fa-var-yoast: "\f2b1"; +@fa-var-youtube: "\f167"; +@fa-var-youtube-play: "\f16a"; +@fa-var-youtube-square: "\f166"; + diff --git a/js/font-awesome/scss/_animated.scss b/js/font-awesome/scss/_animated.scss new file mode 100644 index 000000000..8a020dbff --- /dev/null +++ b/js/font-awesome/scss/_animated.scss @@ -0,0 +1,34 @@ +// Spinning Icons +// -------------------------- + +.#{$fa-css-prefix}-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} + +.#{$fa-css-prefix}-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); + } +} diff --git a/js/font-awesome/scss/_bordered-pulled.scss b/js/font-awesome/scss/_bordered-pulled.scss new file mode 100644 index 000000000..d4b85a02f --- /dev/null +++ b/js/font-awesome/scss/_bordered-pulled.scss @@ -0,0 +1,25 @@ +// Bordered & Pulled +// ------------------------- + +.#{$fa-css-prefix}-border { + padding: .2em .25em .15em; + border: solid .08em $fa-border-color; + border-radius: .1em; +} + +.#{$fa-css-prefix}-pull-left { float: left; } +.#{$fa-css-prefix}-pull-right { float: right; } + +.#{$fa-css-prefix} { + &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } + &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } +} + +/* Deprecated as of 4.4.0 */ +.pull-right { float: right; } +.pull-left { float: left; } + +.#{$fa-css-prefix} { + &.pull-left { margin-right: .3em; } + &.pull-right { margin-left: .3em; } +} diff --git a/js/font-awesome/scss/_core.scss b/js/font-awesome/scss/_core.scss new file mode 100644 index 000000000..7425ef85f --- /dev/null +++ b/js/font-awesome/scss/_core.scss @@ -0,0 +1,12 @@ +// Base Class Definition +// ------------------------- + +.#{$fa-css-prefix} { + display: inline-block; + font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + +} diff --git a/js/font-awesome/scss/_fixed-width.scss b/js/font-awesome/scss/_fixed-width.scss new file mode 100644 index 000000000..b221c9813 --- /dev/null +++ b/js/font-awesome/scss/_fixed-width.scss @@ -0,0 +1,6 @@ +// Fixed Width Icons +// ------------------------- +.#{$fa-css-prefix}-fw { + width: (18em / 14); + text-align: center; +} diff --git a/js/font-awesome/scss/_icons.scss b/js/font-awesome/scss/_icons.scss new file mode 100644 index 000000000..e63e702c4 --- /dev/null +++ b/js/font-awesome/scss/_icons.scss @@ -0,0 +1,789 @@ +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ + +.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; } +.#{$fa-css-prefix}-music:before { content: $fa-var-music; } +.#{$fa-css-prefix}-search:before { content: $fa-var-search; } +.#{$fa-css-prefix}-envelope-o:before { content: $fa-var-envelope-o; } +.#{$fa-css-prefix}-heart:before { content: $fa-var-heart; } +.#{$fa-css-prefix}-star:before { content: $fa-var-star; } +.#{$fa-css-prefix}-star-o:before { content: $fa-var-star-o; } +.#{$fa-css-prefix}-user:before { content: $fa-var-user; } +.#{$fa-css-prefix}-film:before { content: $fa-var-film; } +.#{$fa-css-prefix}-th-large:before { content: $fa-var-th-large; } +.#{$fa-css-prefix}-th:before { content: $fa-var-th; } +.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; } +.#{$fa-css-prefix}-check:before { content: $fa-var-check; } +.#{$fa-css-prefix}-remove:before, +.#{$fa-css-prefix}-close:before, +.#{$fa-css-prefix}-times:before { content: $fa-var-times; } +.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; } +.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; } +.#{$fa-css-prefix}-power-off:before { content: $fa-var-power-off; } +.#{$fa-css-prefix}-signal:before { content: $fa-var-signal; } +.#{$fa-css-prefix}-gear:before, +.#{$fa-css-prefix}-cog:before { content: $fa-var-cog; } +.#{$fa-css-prefix}-trash-o:before { content: $fa-var-trash-o; } +.#{$fa-css-prefix}-home:before { content: $fa-var-home; } +.#{$fa-css-prefix}-file-o:before { content: $fa-var-file-o; } +.#{$fa-css-prefix}-clock-o:before { content: $fa-var-clock-o; } +.#{$fa-css-prefix}-road:before { content: $fa-var-road; } +.#{$fa-css-prefix}-download:before { content: $fa-var-download; } +.#{$fa-css-prefix}-arrow-circle-o-down:before { content: $fa-var-arrow-circle-o-down; } +.#{$fa-css-prefix}-arrow-circle-o-up:before { content: $fa-var-arrow-circle-o-up; } +.#{$fa-css-prefix}-inbox:before { content: $fa-var-inbox; } +.#{$fa-css-prefix}-play-circle-o:before { content: $fa-var-play-circle-o; } +.#{$fa-css-prefix}-rotate-right:before, +.#{$fa-css-prefix}-repeat:before { content: $fa-var-repeat; } +.#{$fa-css-prefix}-refresh:before { content: $fa-var-refresh; } +.#{$fa-css-prefix}-list-alt:before { content: $fa-var-list-alt; } +.#{$fa-css-prefix}-lock:before { content: $fa-var-lock; } +.#{$fa-css-prefix}-flag:before { content: $fa-var-flag; } +.#{$fa-css-prefix}-headphones:before { content: $fa-var-headphones; } +.#{$fa-css-prefix}-volume-off:before { content: $fa-var-volume-off; } +.#{$fa-css-prefix}-volume-down:before { content: $fa-var-volume-down; } +.#{$fa-css-prefix}-volume-up:before { content: $fa-var-volume-up; } +.#{$fa-css-prefix}-qrcode:before { content: $fa-var-qrcode; } +.#{$fa-css-prefix}-barcode:before { content: $fa-var-barcode; } +.#{$fa-css-prefix}-tag:before { content: $fa-var-tag; } +.#{$fa-css-prefix}-tags:before { content: $fa-var-tags; } +.#{$fa-css-prefix}-book:before { content: $fa-var-book; } +.#{$fa-css-prefix}-bookmark:before { content: $fa-var-bookmark; } +.#{$fa-css-prefix}-print:before { content: $fa-var-print; } +.#{$fa-css-prefix}-camera:before { content: $fa-var-camera; } +.#{$fa-css-prefix}-font:before { content: $fa-var-font; } +.#{$fa-css-prefix}-bold:before { content: $fa-var-bold; } +.#{$fa-css-prefix}-italic:before { content: $fa-var-italic; } +.#{$fa-css-prefix}-text-height:before { content: $fa-var-text-height; } +.#{$fa-css-prefix}-text-width:before { content: $fa-var-text-width; } +.#{$fa-css-prefix}-align-left:before { content: $fa-var-align-left; } +.#{$fa-css-prefix}-align-center:before { content: $fa-var-align-center; } +.#{$fa-css-prefix}-align-right:before { content: $fa-var-align-right; } +.#{$fa-css-prefix}-align-justify:before { content: $fa-var-align-justify; } +.#{$fa-css-prefix}-list:before { content: $fa-var-list; } +.#{$fa-css-prefix}-dedent:before, +.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; } +.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; } +.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; } +.#{$fa-css-prefix}-photo:before, +.#{$fa-css-prefix}-image:before, +.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; } +.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; } +.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; } +.#{$fa-css-prefix}-adjust:before { content: $fa-var-adjust; } +.#{$fa-css-prefix}-tint:before { content: $fa-var-tint; } +.#{$fa-css-prefix}-edit:before, +.#{$fa-css-prefix}-pencil-square-o:before { content: $fa-var-pencil-square-o; } +.#{$fa-css-prefix}-share-square-o:before { content: $fa-var-share-square-o; } +.#{$fa-css-prefix}-check-square-o:before { content: $fa-var-check-square-o; } +.#{$fa-css-prefix}-arrows:before { content: $fa-var-arrows; } +.#{$fa-css-prefix}-step-backward:before { content: $fa-var-step-backward; } +.#{$fa-css-prefix}-fast-backward:before { content: $fa-var-fast-backward; } +.#{$fa-css-prefix}-backward:before { content: $fa-var-backward; } +.#{$fa-css-prefix}-play:before { content: $fa-var-play; } +.#{$fa-css-prefix}-pause:before { content: $fa-var-pause; } +.#{$fa-css-prefix}-stop:before { content: $fa-var-stop; } +.#{$fa-css-prefix}-forward:before { content: $fa-var-forward; } +.#{$fa-css-prefix}-fast-forward:before { content: $fa-var-fast-forward; } +.#{$fa-css-prefix}-step-forward:before { content: $fa-var-step-forward; } +.#{$fa-css-prefix}-eject:before { content: $fa-var-eject; } +.#{$fa-css-prefix}-chevron-left:before { content: $fa-var-chevron-left; } +.#{$fa-css-prefix}-chevron-right:before { content: $fa-var-chevron-right; } +.#{$fa-css-prefix}-plus-circle:before { content: $fa-var-plus-circle; } +.#{$fa-css-prefix}-minus-circle:before { content: $fa-var-minus-circle; } +.#{$fa-css-prefix}-times-circle:before { content: $fa-var-times-circle; } +.#{$fa-css-prefix}-check-circle:before { content: $fa-var-check-circle; } +.#{$fa-css-prefix}-question-circle:before { content: $fa-var-question-circle; } +.#{$fa-css-prefix}-info-circle:before { content: $fa-var-info-circle; } +.#{$fa-css-prefix}-crosshairs:before { content: $fa-var-crosshairs; } +.#{$fa-css-prefix}-times-circle-o:before { content: $fa-var-times-circle-o; } +.#{$fa-css-prefix}-check-circle-o:before { content: $fa-var-check-circle-o; } +.#{$fa-css-prefix}-ban:before { content: $fa-var-ban; } +.#{$fa-css-prefix}-arrow-left:before { content: $fa-var-arrow-left; } +.#{$fa-css-prefix}-arrow-right:before { content: $fa-var-arrow-right; } +.#{$fa-css-prefix}-arrow-up:before { content: $fa-var-arrow-up; } +.#{$fa-css-prefix}-arrow-down:before { content: $fa-var-arrow-down; } +.#{$fa-css-prefix}-mail-forward:before, +.#{$fa-css-prefix}-share:before { content: $fa-var-share; } +.#{$fa-css-prefix}-expand:before { content: $fa-var-expand; } +.#{$fa-css-prefix}-compress:before { content: $fa-var-compress; } +.#{$fa-css-prefix}-plus:before { content: $fa-var-plus; } +.#{$fa-css-prefix}-minus:before { content: $fa-var-minus; } +.#{$fa-css-prefix}-asterisk:before { content: $fa-var-asterisk; } +.#{$fa-css-prefix}-exclamation-circle:before { content: $fa-var-exclamation-circle; } +.#{$fa-css-prefix}-gift:before { content: $fa-var-gift; } +.#{$fa-css-prefix}-leaf:before { content: $fa-var-leaf; } +.#{$fa-css-prefix}-fire:before { content: $fa-var-fire; } +.#{$fa-css-prefix}-eye:before { content: $fa-var-eye; } +.#{$fa-css-prefix}-eye-slash:before { content: $fa-var-eye-slash; } +.#{$fa-css-prefix}-warning:before, +.#{$fa-css-prefix}-exclamation-triangle:before { content: $fa-var-exclamation-triangle; } +.#{$fa-css-prefix}-plane:before { content: $fa-var-plane; } +.#{$fa-css-prefix}-calendar:before { content: $fa-var-calendar; } +.#{$fa-css-prefix}-random:before { content: $fa-var-random; } +.#{$fa-css-prefix}-comment:before { content: $fa-var-comment; } +.#{$fa-css-prefix}-magnet:before { content: $fa-var-magnet; } +.#{$fa-css-prefix}-chevron-up:before { content: $fa-var-chevron-up; } +.#{$fa-css-prefix}-chevron-down:before { content: $fa-var-chevron-down; } +.#{$fa-css-prefix}-retweet:before { content: $fa-var-retweet; } +.#{$fa-css-prefix}-shopping-cart:before { content: $fa-var-shopping-cart; } +.#{$fa-css-prefix}-folder:before { content: $fa-var-folder; } +.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; } +.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; } +.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; } +.#{$fa-css-prefix}-bar-chart-o:before, +.#{$fa-css-prefix}-bar-chart:before { content: $fa-var-bar-chart; } +.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; } +.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; } +.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; } +.#{$fa-css-prefix}-key:before { content: $fa-var-key; } +.#{$fa-css-prefix}-gears:before, +.#{$fa-css-prefix}-cogs:before { content: $fa-var-cogs; } +.#{$fa-css-prefix}-comments:before { content: $fa-var-comments; } +.#{$fa-css-prefix}-thumbs-o-up:before { content: $fa-var-thumbs-o-up; } +.#{$fa-css-prefix}-thumbs-o-down:before { content: $fa-var-thumbs-o-down; } +.#{$fa-css-prefix}-star-half:before { content: $fa-var-star-half; } +.#{$fa-css-prefix}-heart-o:before { content: $fa-var-heart-o; } +.#{$fa-css-prefix}-sign-out:before { content: $fa-var-sign-out; } +.#{$fa-css-prefix}-linkedin-square:before { content: $fa-var-linkedin-square; } +.#{$fa-css-prefix}-thumb-tack:before { content: $fa-var-thumb-tack; } +.#{$fa-css-prefix}-external-link:before { content: $fa-var-external-link; } +.#{$fa-css-prefix}-sign-in:before { content: $fa-var-sign-in; } +.#{$fa-css-prefix}-trophy:before { content: $fa-var-trophy; } +.#{$fa-css-prefix}-github-square:before { content: $fa-var-github-square; } +.#{$fa-css-prefix}-upload:before { content: $fa-var-upload; } +.#{$fa-css-prefix}-lemon-o:before { content: $fa-var-lemon-o; } +.#{$fa-css-prefix}-phone:before { content: $fa-var-phone; } +.#{$fa-css-prefix}-square-o:before { content: $fa-var-square-o; } +.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; } +.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; } +.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; } +.#{$fa-css-prefix}-facebook-f:before, +.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; } +.#{$fa-css-prefix}-github:before { content: $fa-var-github; } +.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; } +.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; } +.#{$fa-css-prefix}-feed:before, +.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; } +.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; } +.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; } +.#{$fa-css-prefix}-bell:before { content: $fa-var-bell; } +.#{$fa-css-prefix}-certificate:before { content: $fa-var-certificate; } +.#{$fa-css-prefix}-hand-o-right:before { content: $fa-var-hand-o-right; } +.#{$fa-css-prefix}-hand-o-left:before { content: $fa-var-hand-o-left; } +.#{$fa-css-prefix}-hand-o-up:before { content: $fa-var-hand-o-up; } +.#{$fa-css-prefix}-hand-o-down:before { content: $fa-var-hand-o-down; } +.#{$fa-css-prefix}-arrow-circle-left:before { content: $fa-var-arrow-circle-left; } +.#{$fa-css-prefix}-arrow-circle-right:before { content: $fa-var-arrow-circle-right; } +.#{$fa-css-prefix}-arrow-circle-up:before { content: $fa-var-arrow-circle-up; } +.#{$fa-css-prefix}-arrow-circle-down:before { content: $fa-var-arrow-circle-down; } +.#{$fa-css-prefix}-globe:before { content: $fa-var-globe; } +.#{$fa-css-prefix}-wrench:before { content: $fa-var-wrench; } +.#{$fa-css-prefix}-tasks:before { content: $fa-var-tasks; } +.#{$fa-css-prefix}-filter:before { content: $fa-var-filter; } +.#{$fa-css-prefix}-briefcase:before { content: $fa-var-briefcase; } +.#{$fa-css-prefix}-arrows-alt:before { content: $fa-var-arrows-alt; } +.#{$fa-css-prefix}-group:before, +.#{$fa-css-prefix}-users:before { content: $fa-var-users; } +.#{$fa-css-prefix}-chain:before, +.#{$fa-css-prefix}-link:before { content: $fa-var-link; } +.#{$fa-css-prefix}-cloud:before { content: $fa-var-cloud; } +.#{$fa-css-prefix}-flask:before { content: $fa-var-flask; } +.#{$fa-css-prefix}-cut:before, +.#{$fa-css-prefix}-scissors:before { content: $fa-var-scissors; } +.#{$fa-css-prefix}-copy:before, +.#{$fa-css-prefix}-files-o:before { content: $fa-var-files-o; } +.#{$fa-css-prefix}-paperclip:before { content: $fa-var-paperclip; } +.#{$fa-css-prefix}-save:before, +.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; } +.#{$fa-css-prefix}-square:before { content: $fa-var-square; } +.#{$fa-css-prefix}-navicon:before, +.#{$fa-css-prefix}-reorder:before, +.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; } +.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; } +.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; } +.#{$fa-css-prefix}-strikethrough:before { content: $fa-var-strikethrough; } +.#{$fa-css-prefix}-underline:before { content: $fa-var-underline; } +.#{$fa-css-prefix}-table:before { content: $fa-var-table; } +.#{$fa-css-prefix}-magic:before { content: $fa-var-magic; } +.#{$fa-css-prefix}-truck:before { content: $fa-var-truck; } +.#{$fa-css-prefix}-pinterest:before { content: $fa-var-pinterest; } +.#{$fa-css-prefix}-pinterest-square:before { content: $fa-var-pinterest-square; } +.#{$fa-css-prefix}-google-plus-square:before { content: $fa-var-google-plus-square; } +.#{$fa-css-prefix}-google-plus:before { content: $fa-var-google-plus; } +.#{$fa-css-prefix}-money:before { content: $fa-var-money; } +.#{$fa-css-prefix}-caret-down:before { content: $fa-var-caret-down; } +.#{$fa-css-prefix}-caret-up:before { content: $fa-var-caret-up; } +.#{$fa-css-prefix}-caret-left:before { content: $fa-var-caret-left; } +.#{$fa-css-prefix}-caret-right:before { content: $fa-var-caret-right; } +.#{$fa-css-prefix}-columns:before { content: $fa-var-columns; } +.#{$fa-css-prefix}-unsorted:before, +.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; } +.#{$fa-css-prefix}-sort-down:before, +.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; } +.#{$fa-css-prefix}-sort-up:before, +.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; } +.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; } +.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; } +.#{$fa-css-prefix}-rotate-left:before, +.#{$fa-css-prefix}-undo:before { content: $fa-var-undo; } +.#{$fa-css-prefix}-legal:before, +.#{$fa-css-prefix}-gavel:before { content: $fa-var-gavel; } +.#{$fa-css-prefix}-dashboard:before, +.#{$fa-css-prefix}-tachometer:before { content: $fa-var-tachometer; } +.#{$fa-css-prefix}-comment-o:before { content: $fa-var-comment-o; } +.#{$fa-css-prefix}-comments-o:before { content: $fa-var-comments-o; } +.#{$fa-css-prefix}-flash:before, +.#{$fa-css-prefix}-bolt:before { content: $fa-var-bolt; } +.#{$fa-css-prefix}-sitemap:before { content: $fa-var-sitemap; } +.#{$fa-css-prefix}-umbrella:before { content: $fa-var-umbrella; } +.#{$fa-css-prefix}-paste:before, +.#{$fa-css-prefix}-clipboard:before { content: $fa-var-clipboard; } +.#{$fa-css-prefix}-lightbulb-o:before { content: $fa-var-lightbulb-o; } +.#{$fa-css-prefix}-exchange:before { content: $fa-var-exchange; } +.#{$fa-css-prefix}-cloud-download:before { content: $fa-var-cloud-download; } +.#{$fa-css-prefix}-cloud-upload:before { content: $fa-var-cloud-upload; } +.#{$fa-css-prefix}-user-md:before { content: $fa-var-user-md; } +.#{$fa-css-prefix}-stethoscope:before { content: $fa-var-stethoscope; } +.#{$fa-css-prefix}-suitcase:before { content: $fa-var-suitcase; } +.#{$fa-css-prefix}-bell-o:before { content: $fa-var-bell-o; } +.#{$fa-css-prefix}-coffee:before { content: $fa-var-coffee; } +.#{$fa-css-prefix}-cutlery:before { content: $fa-var-cutlery; } +.#{$fa-css-prefix}-file-text-o:before { content: $fa-var-file-text-o; } +.#{$fa-css-prefix}-building-o:before { content: $fa-var-building-o; } +.#{$fa-css-prefix}-hospital-o:before { content: $fa-var-hospital-o; } +.#{$fa-css-prefix}-ambulance:before { content: $fa-var-ambulance; } +.#{$fa-css-prefix}-medkit:before { content: $fa-var-medkit; } +.#{$fa-css-prefix}-fighter-jet:before { content: $fa-var-fighter-jet; } +.#{$fa-css-prefix}-beer:before { content: $fa-var-beer; } +.#{$fa-css-prefix}-h-square:before { content: $fa-var-h-square; } +.#{$fa-css-prefix}-plus-square:before { content: $fa-var-plus-square; } +.#{$fa-css-prefix}-angle-double-left:before { content: $fa-var-angle-double-left; } +.#{$fa-css-prefix}-angle-double-right:before { content: $fa-var-angle-double-right; } +.#{$fa-css-prefix}-angle-double-up:before { content: $fa-var-angle-double-up; } +.#{$fa-css-prefix}-angle-double-down:before { content: $fa-var-angle-double-down; } +.#{$fa-css-prefix}-angle-left:before { content: $fa-var-angle-left; } +.#{$fa-css-prefix}-angle-right:before { content: $fa-var-angle-right; } +.#{$fa-css-prefix}-angle-up:before { content: $fa-var-angle-up; } +.#{$fa-css-prefix}-angle-down:before { content: $fa-var-angle-down; } +.#{$fa-css-prefix}-desktop:before { content: $fa-var-desktop; } +.#{$fa-css-prefix}-laptop:before { content: $fa-var-laptop; } +.#{$fa-css-prefix}-tablet:before { content: $fa-var-tablet; } +.#{$fa-css-prefix}-mobile-phone:before, +.#{$fa-css-prefix}-mobile:before { content: $fa-var-mobile; } +.#{$fa-css-prefix}-circle-o:before { content: $fa-var-circle-o; } +.#{$fa-css-prefix}-quote-left:before { content: $fa-var-quote-left; } +.#{$fa-css-prefix}-quote-right:before { content: $fa-var-quote-right; } +.#{$fa-css-prefix}-spinner:before { content: $fa-var-spinner; } +.#{$fa-css-prefix}-circle:before { content: $fa-var-circle; } +.#{$fa-css-prefix}-mail-reply:before, +.#{$fa-css-prefix}-reply:before { content: $fa-var-reply; } +.#{$fa-css-prefix}-github-alt:before { content: $fa-var-github-alt; } +.#{$fa-css-prefix}-folder-o:before { content: $fa-var-folder-o; } +.#{$fa-css-prefix}-folder-open-o:before { content: $fa-var-folder-open-o; } +.#{$fa-css-prefix}-smile-o:before { content: $fa-var-smile-o; } +.#{$fa-css-prefix}-frown-o:before { content: $fa-var-frown-o; } +.#{$fa-css-prefix}-meh-o:before { content: $fa-var-meh-o; } +.#{$fa-css-prefix}-gamepad:before { content: $fa-var-gamepad; } +.#{$fa-css-prefix}-keyboard-o:before { content: $fa-var-keyboard-o; } +.#{$fa-css-prefix}-flag-o:before { content: $fa-var-flag-o; } +.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; } +.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; } +.#{$fa-css-prefix}-code:before { content: $fa-var-code; } +.#{$fa-css-prefix}-mail-reply-all:before, +.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; } +.#{$fa-css-prefix}-star-half-empty:before, +.#{$fa-css-prefix}-star-half-full:before, +.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; } +.#{$fa-css-prefix}-location-arrow:before { content: $fa-var-location-arrow; } +.#{$fa-css-prefix}-crop:before { content: $fa-var-crop; } +.#{$fa-css-prefix}-code-fork:before { content: $fa-var-code-fork; } +.#{$fa-css-prefix}-unlink:before, +.#{$fa-css-prefix}-chain-broken:before { content: $fa-var-chain-broken; } +.#{$fa-css-prefix}-question:before { content: $fa-var-question; } +.#{$fa-css-prefix}-info:before { content: $fa-var-info; } +.#{$fa-css-prefix}-exclamation:before { content: $fa-var-exclamation; } +.#{$fa-css-prefix}-superscript:before { content: $fa-var-superscript; } +.#{$fa-css-prefix}-subscript:before { content: $fa-var-subscript; } +.#{$fa-css-prefix}-eraser:before { content: $fa-var-eraser; } +.#{$fa-css-prefix}-puzzle-piece:before { content: $fa-var-puzzle-piece; } +.#{$fa-css-prefix}-microphone:before { content: $fa-var-microphone; } +.#{$fa-css-prefix}-microphone-slash:before { content: $fa-var-microphone-slash; } +.#{$fa-css-prefix}-shield:before { content: $fa-var-shield; } +.#{$fa-css-prefix}-calendar-o:before { content: $fa-var-calendar-o; } +.#{$fa-css-prefix}-fire-extinguisher:before { content: $fa-var-fire-extinguisher; } +.#{$fa-css-prefix}-rocket:before { content: $fa-var-rocket; } +.#{$fa-css-prefix}-maxcdn:before { content: $fa-var-maxcdn; } +.#{$fa-css-prefix}-chevron-circle-left:before { content: $fa-var-chevron-circle-left; } +.#{$fa-css-prefix}-chevron-circle-right:before { content: $fa-var-chevron-circle-right; } +.#{$fa-css-prefix}-chevron-circle-up:before { content: $fa-var-chevron-circle-up; } +.#{$fa-css-prefix}-chevron-circle-down:before { content: $fa-var-chevron-circle-down; } +.#{$fa-css-prefix}-html5:before { content: $fa-var-html5; } +.#{$fa-css-prefix}-css3:before { content: $fa-var-css3; } +.#{$fa-css-prefix}-anchor:before { content: $fa-var-anchor; } +.#{$fa-css-prefix}-unlock-alt:before { content: $fa-var-unlock-alt; } +.#{$fa-css-prefix}-bullseye:before { content: $fa-var-bullseye; } +.#{$fa-css-prefix}-ellipsis-h:before { content: $fa-var-ellipsis-h; } +.#{$fa-css-prefix}-ellipsis-v:before { content: $fa-var-ellipsis-v; } +.#{$fa-css-prefix}-rss-square:before { content: $fa-var-rss-square; } +.#{$fa-css-prefix}-play-circle:before { content: $fa-var-play-circle; } +.#{$fa-css-prefix}-ticket:before { content: $fa-var-ticket; } +.#{$fa-css-prefix}-minus-square:before { content: $fa-var-minus-square; } +.#{$fa-css-prefix}-minus-square-o:before { content: $fa-var-minus-square-o; } +.#{$fa-css-prefix}-level-up:before { content: $fa-var-level-up; } +.#{$fa-css-prefix}-level-down:before { content: $fa-var-level-down; } +.#{$fa-css-prefix}-check-square:before { content: $fa-var-check-square; } +.#{$fa-css-prefix}-pencil-square:before { content: $fa-var-pencil-square; } +.#{$fa-css-prefix}-external-link-square:before { content: $fa-var-external-link-square; } +.#{$fa-css-prefix}-share-square:before { content: $fa-var-share-square; } +.#{$fa-css-prefix}-compass:before { content: $fa-var-compass; } +.#{$fa-css-prefix}-toggle-down:before, +.#{$fa-css-prefix}-caret-square-o-down:before { content: $fa-var-caret-square-o-down; } +.#{$fa-css-prefix}-toggle-up:before, +.#{$fa-css-prefix}-caret-square-o-up:before { content: $fa-var-caret-square-o-up; } +.#{$fa-css-prefix}-toggle-right:before, +.#{$fa-css-prefix}-caret-square-o-right:before { content: $fa-var-caret-square-o-right; } +.#{$fa-css-prefix}-euro:before, +.#{$fa-css-prefix}-eur:before { content: $fa-var-eur; } +.#{$fa-css-prefix}-gbp:before { content: $fa-var-gbp; } +.#{$fa-css-prefix}-dollar:before, +.#{$fa-css-prefix}-usd:before { content: $fa-var-usd; } +.#{$fa-css-prefix}-rupee:before, +.#{$fa-css-prefix}-inr:before { content: $fa-var-inr; } +.#{$fa-css-prefix}-cny:before, +.#{$fa-css-prefix}-rmb:before, +.#{$fa-css-prefix}-yen:before, +.#{$fa-css-prefix}-jpy:before { content: $fa-var-jpy; } +.#{$fa-css-prefix}-ruble:before, +.#{$fa-css-prefix}-rouble:before, +.#{$fa-css-prefix}-rub:before { content: $fa-var-rub; } +.#{$fa-css-prefix}-won:before, +.#{$fa-css-prefix}-krw:before { content: $fa-var-krw; } +.#{$fa-css-prefix}-bitcoin:before, +.#{$fa-css-prefix}-btc:before { content: $fa-var-btc; } +.#{$fa-css-prefix}-file:before { content: $fa-var-file; } +.#{$fa-css-prefix}-file-text:before { content: $fa-var-file-text; } +.#{$fa-css-prefix}-sort-alpha-asc:before { content: $fa-var-sort-alpha-asc; } +.#{$fa-css-prefix}-sort-alpha-desc:before { content: $fa-var-sort-alpha-desc; } +.#{$fa-css-prefix}-sort-amount-asc:before { content: $fa-var-sort-amount-asc; } +.#{$fa-css-prefix}-sort-amount-desc:before { content: $fa-var-sort-amount-desc; } +.#{$fa-css-prefix}-sort-numeric-asc:before { content: $fa-var-sort-numeric-asc; } +.#{$fa-css-prefix}-sort-numeric-desc:before { content: $fa-var-sort-numeric-desc; } +.#{$fa-css-prefix}-thumbs-up:before { content: $fa-var-thumbs-up; } +.#{$fa-css-prefix}-thumbs-down:before { content: $fa-var-thumbs-down; } +.#{$fa-css-prefix}-youtube-square:before { content: $fa-var-youtube-square; } +.#{$fa-css-prefix}-youtube:before { content: $fa-var-youtube; } +.#{$fa-css-prefix}-xing:before { content: $fa-var-xing; } +.#{$fa-css-prefix}-xing-square:before { content: $fa-var-xing-square; } +.#{$fa-css-prefix}-youtube-play:before { content: $fa-var-youtube-play; } +.#{$fa-css-prefix}-dropbox:before { content: $fa-var-dropbox; } +.#{$fa-css-prefix}-stack-overflow:before { content: $fa-var-stack-overflow; } +.#{$fa-css-prefix}-instagram:before { content: $fa-var-instagram; } +.#{$fa-css-prefix}-flickr:before { content: $fa-var-flickr; } +.#{$fa-css-prefix}-adn:before { content: $fa-var-adn; } +.#{$fa-css-prefix}-bitbucket:before { content: $fa-var-bitbucket; } +.#{$fa-css-prefix}-bitbucket-square:before { content: $fa-var-bitbucket-square; } +.#{$fa-css-prefix}-tumblr:before { content: $fa-var-tumblr; } +.#{$fa-css-prefix}-tumblr-square:before { content: $fa-var-tumblr-square; } +.#{$fa-css-prefix}-long-arrow-down:before { content: $fa-var-long-arrow-down; } +.#{$fa-css-prefix}-long-arrow-up:before { content: $fa-var-long-arrow-up; } +.#{$fa-css-prefix}-long-arrow-left:before { content: $fa-var-long-arrow-left; } +.#{$fa-css-prefix}-long-arrow-right:before { content: $fa-var-long-arrow-right; } +.#{$fa-css-prefix}-apple:before { content: $fa-var-apple; } +.#{$fa-css-prefix}-windows:before { content: $fa-var-windows; } +.#{$fa-css-prefix}-android:before { content: $fa-var-android; } +.#{$fa-css-prefix}-linux:before { content: $fa-var-linux; } +.#{$fa-css-prefix}-dribbble:before { content: $fa-var-dribbble; } +.#{$fa-css-prefix}-skype:before { content: $fa-var-skype; } +.#{$fa-css-prefix}-foursquare:before { content: $fa-var-foursquare; } +.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; } +.#{$fa-css-prefix}-female:before { content: $fa-var-female; } +.#{$fa-css-prefix}-male:before { content: $fa-var-male; } +.#{$fa-css-prefix}-gittip:before, +.#{$fa-css-prefix}-gratipay:before { content: $fa-var-gratipay; } +.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; } +.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; } +.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; } +.#{$fa-css-prefix}-bug:before { content: $fa-var-bug; } +.#{$fa-css-prefix}-vk:before { content: $fa-var-vk; } +.#{$fa-css-prefix}-weibo:before { content: $fa-var-weibo; } +.#{$fa-css-prefix}-renren:before { content: $fa-var-renren; } +.#{$fa-css-prefix}-pagelines:before { content: $fa-var-pagelines; } +.#{$fa-css-prefix}-stack-exchange:before { content: $fa-var-stack-exchange; } +.#{$fa-css-prefix}-arrow-circle-o-right:before { content: $fa-var-arrow-circle-o-right; } +.#{$fa-css-prefix}-arrow-circle-o-left:before { content: $fa-var-arrow-circle-o-left; } +.#{$fa-css-prefix}-toggle-left:before, +.#{$fa-css-prefix}-caret-square-o-left:before { content: $fa-var-caret-square-o-left; } +.#{$fa-css-prefix}-dot-circle-o:before { content: $fa-var-dot-circle-o; } +.#{$fa-css-prefix}-wheelchair:before { content: $fa-var-wheelchair; } +.#{$fa-css-prefix}-vimeo-square:before { content: $fa-var-vimeo-square; } +.#{$fa-css-prefix}-turkish-lira:before, +.#{$fa-css-prefix}-try:before { content: $fa-var-try; } +.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; } +.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; } +.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; } +.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; } +.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; } +.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; } +.#{$fa-css-prefix}-institution:before, +.#{$fa-css-prefix}-bank:before, +.#{$fa-css-prefix}-university:before { content: $fa-var-university; } +.#{$fa-css-prefix}-mortar-board:before, +.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; } +.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; } +.#{$fa-css-prefix}-google:before { content: $fa-var-google; } +.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; } +.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; } +.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; } +.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; } +.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; } +.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; } +.#{$fa-css-prefix}-pied-piper-pp:before { content: $fa-var-pied-piper-pp; } +.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; } +.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; } +.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; } +.#{$fa-css-prefix}-language:before { content: $fa-var-language; } +.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; } +.#{$fa-css-prefix}-building:before { content: $fa-var-building; } +.#{$fa-css-prefix}-child:before { content: $fa-var-child; } +.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; } +.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; } +.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; } +.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; } +.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; } +.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; } +.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; } +.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; } +.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; } +.#{$fa-css-prefix}-automobile:before, +.#{$fa-css-prefix}-car:before { content: $fa-var-car; } +.#{$fa-css-prefix}-cab:before, +.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; } +.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; } +.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; } +.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; } +.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; } +.#{$fa-css-prefix}-database:before { content: $fa-var-database; } +.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; } +.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; } +.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; } +.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; } +.#{$fa-css-prefix}-file-photo-o:before, +.#{$fa-css-prefix}-file-picture-o:before, +.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; } +.#{$fa-css-prefix}-file-zip-o:before, +.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; } +.#{$fa-css-prefix}-file-sound-o:before, +.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; } +.#{$fa-css-prefix}-file-movie-o:before, +.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; } +.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; } +.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; } +.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; } +.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; } +.#{$fa-css-prefix}-life-bouy:before, +.#{$fa-css-prefix}-life-buoy:before, +.#{$fa-css-prefix}-life-saver:before, +.#{$fa-css-prefix}-support:before, +.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; } +.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; } +.#{$fa-css-prefix}-ra:before, +.#{$fa-css-prefix}-resistance:before, +.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; } +.#{$fa-css-prefix}-ge:before, +.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; } +.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; } +.#{$fa-css-prefix}-git:before { content: $fa-var-git; } +.#{$fa-css-prefix}-y-combinator-square:before, +.#{$fa-css-prefix}-yc-square:before, +.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; } +.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; } +.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; } +.#{$fa-css-prefix}-wechat:before, +.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; } +.#{$fa-css-prefix}-send:before, +.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; } +.#{$fa-css-prefix}-send-o:before, +.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; } +.#{$fa-css-prefix}-history:before { content: $fa-var-history; } +.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; } +.#{$fa-css-prefix}-header:before { content: $fa-var-header; } +.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; } +.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; } +.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; } +.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; } +.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; } +.#{$fa-css-prefix}-soccer-ball-o:before, +.#{$fa-css-prefix}-futbol-o:before { content: $fa-var-futbol-o; } +.#{$fa-css-prefix}-tty:before { content: $fa-var-tty; } +.#{$fa-css-prefix}-binoculars:before { content: $fa-var-binoculars; } +.#{$fa-css-prefix}-plug:before { content: $fa-var-plug; } +.#{$fa-css-prefix}-slideshare:before { content: $fa-var-slideshare; } +.#{$fa-css-prefix}-twitch:before { content: $fa-var-twitch; } +.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; } +.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; } +.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; } +.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; } +.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; } +.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; } +.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; } +.#{$fa-css-prefix}-cc-mastercard:before { content: $fa-var-cc-mastercard; } +.#{$fa-css-prefix}-cc-discover:before { content: $fa-var-cc-discover; } +.#{$fa-css-prefix}-cc-amex:before { content: $fa-var-cc-amex; } +.#{$fa-css-prefix}-cc-paypal:before { content: $fa-var-cc-paypal; } +.#{$fa-css-prefix}-cc-stripe:before { content: $fa-var-cc-stripe; } +.#{$fa-css-prefix}-bell-slash:before { content: $fa-var-bell-slash; } +.#{$fa-css-prefix}-bell-slash-o:before { content: $fa-var-bell-slash-o; } +.#{$fa-css-prefix}-trash:before { content: $fa-var-trash; } +.#{$fa-css-prefix}-copyright:before { content: $fa-var-copyright; } +.#{$fa-css-prefix}-at:before { content: $fa-var-at; } +.#{$fa-css-prefix}-eyedropper:before { content: $fa-var-eyedropper; } +.#{$fa-css-prefix}-paint-brush:before { content: $fa-var-paint-brush; } +.#{$fa-css-prefix}-birthday-cake:before { content: $fa-var-birthday-cake; } +.#{$fa-css-prefix}-area-chart:before { content: $fa-var-area-chart; } +.#{$fa-css-prefix}-pie-chart:before { content: $fa-var-pie-chart; } +.#{$fa-css-prefix}-line-chart:before { content: $fa-var-line-chart; } +.#{$fa-css-prefix}-lastfm:before { content: $fa-var-lastfm; } +.#{$fa-css-prefix}-lastfm-square:before { content: $fa-var-lastfm-square; } +.#{$fa-css-prefix}-toggle-off:before { content: $fa-var-toggle-off; } +.#{$fa-css-prefix}-toggle-on:before { content: $fa-var-toggle-on; } +.#{$fa-css-prefix}-bicycle:before { content: $fa-var-bicycle; } +.#{$fa-css-prefix}-bus:before { content: $fa-var-bus; } +.#{$fa-css-prefix}-ioxhost:before { content: $fa-var-ioxhost; } +.#{$fa-css-prefix}-angellist:before { content: $fa-var-angellist; } +.#{$fa-css-prefix}-cc:before { content: $fa-var-cc; } +.#{$fa-css-prefix}-shekel:before, +.#{$fa-css-prefix}-sheqel:before, +.#{$fa-css-prefix}-ils:before { content: $fa-var-ils; } +.#{$fa-css-prefix}-meanpath:before { content: $fa-var-meanpath; } +.#{$fa-css-prefix}-buysellads:before { content: $fa-var-buysellads; } +.#{$fa-css-prefix}-connectdevelop:before { content: $fa-var-connectdevelop; } +.#{$fa-css-prefix}-dashcube:before { content: $fa-var-dashcube; } +.#{$fa-css-prefix}-forumbee:before { content: $fa-var-forumbee; } +.#{$fa-css-prefix}-leanpub:before { content: $fa-var-leanpub; } +.#{$fa-css-prefix}-sellsy:before { content: $fa-var-sellsy; } +.#{$fa-css-prefix}-shirtsinbulk:before { content: $fa-var-shirtsinbulk; } +.#{$fa-css-prefix}-simplybuilt:before { content: $fa-var-simplybuilt; } +.#{$fa-css-prefix}-skyatlas:before { content: $fa-var-skyatlas; } +.#{$fa-css-prefix}-cart-plus:before { content: $fa-var-cart-plus; } +.#{$fa-css-prefix}-cart-arrow-down:before { content: $fa-var-cart-arrow-down; } +.#{$fa-css-prefix}-diamond:before { content: $fa-var-diamond; } +.#{$fa-css-prefix}-ship:before { content: $fa-var-ship; } +.#{$fa-css-prefix}-user-secret:before { content: $fa-var-user-secret; } +.#{$fa-css-prefix}-motorcycle:before { content: $fa-var-motorcycle; } +.#{$fa-css-prefix}-street-view:before { content: $fa-var-street-view; } +.#{$fa-css-prefix}-heartbeat:before { content: $fa-var-heartbeat; } +.#{$fa-css-prefix}-venus:before { content: $fa-var-venus; } +.#{$fa-css-prefix}-mars:before { content: $fa-var-mars; } +.#{$fa-css-prefix}-mercury:before { content: $fa-var-mercury; } +.#{$fa-css-prefix}-intersex:before, +.#{$fa-css-prefix}-transgender:before { content: $fa-var-transgender; } +.#{$fa-css-prefix}-transgender-alt:before { content: $fa-var-transgender-alt; } +.#{$fa-css-prefix}-venus-double:before { content: $fa-var-venus-double; } +.#{$fa-css-prefix}-mars-double:before { content: $fa-var-mars-double; } +.#{$fa-css-prefix}-venus-mars:before { content: $fa-var-venus-mars; } +.#{$fa-css-prefix}-mars-stroke:before { content: $fa-var-mars-stroke; } +.#{$fa-css-prefix}-mars-stroke-v:before { content: $fa-var-mars-stroke-v; } +.#{$fa-css-prefix}-mars-stroke-h:before { content: $fa-var-mars-stroke-h; } +.#{$fa-css-prefix}-neuter:before { content: $fa-var-neuter; } +.#{$fa-css-prefix}-genderless:before { content: $fa-var-genderless; } +.#{$fa-css-prefix}-facebook-official:before { content: $fa-var-facebook-official; } +.#{$fa-css-prefix}-pinterest-p:before { content: $fa-var-pinterest-p; } +.#{$fa-css-prefix}-whatsapp:before { content: $fa-var-whatsapp; } +.#{$fa-css-prefix}-server:before { content: $fa-var-server; } +.#{$fa-css-prefix}-user-plus:before { content: $fa-var-user-plus; } +.#{$fa-css-prefix}-user-times:before { content: $fa-var-user-times; } +.#{$fa-css-prefix}-hotel:before, +.#{$fa-css-prefix}-bed:before { content: $fa-var-bed; } +.#{$fa-css-prefix}-viacoin:before { content: $fa-var-viacoin; } +.#{$fa-css-prefix}-train:before { content: $fa-var-train; } +.#{$fa-css-prefix}-subway:before { content: $fa-var-subway; } +.#{$fa-css-prefix}-medium:before { content: $fa-var-medium; } +.#{$fa-css-prefix}-yc:before, +.#{$fa-css-prefix}-y-combinator:before { content: $fa-var-y-combinator; } +.#{$fa-css-prefix}-optin-monster:before { content: $fa-var-optin-monster; } +.#{$fa-css-prefix}-opencart:before { content: $fa-var-opencart; } +.#{$fa-css-prefix}-expeditedssl:before { content: $fa-var-expeditedssl; } +.#{$fa-css-prefix}-battery-4:before, +.#{$fa-css-prefix}-battery:before, +.#{$fa-css-prefix}-battery-full:before { content: $fa-var-battery-full; } +.#{$fa-css-prefix}-battery-3:before, +.#{$fa-css-prefix}-battery-three-quarters:before { content: $fa-var-battery-three-quarters; } +.#{$fa-css-prefix}-battery-2:before, +.#{$fa-css-prefix}-battery-half:before { content: $fa-var-battery-half; } +.#{$fa-css-prefix}-battery-1:before, +.#{$fa-css-prefix}-battery-quarter:before { content: $fa-var-battery-quarter; } +.#{$fa-css-prefix}-battery-0:before, +.#{$fa-css-prefix}-battery-empty:before { content: $fa-var-battery-empty; } +.#{$fa-css-prefix}-mouse-pointer:before { content: $fa-var-mouse-pointer; } +.#{$fa-css-prefix}-i-cursor:before { content: $fa-var-i-cursor; } +.#{$fa-css-prefix}-object-group:before { content: $fa-var-object-group; } +.#{$fa-css-prefix}-object-ungroup:before { content: $fa-var-object-ungroup; } +.#{$fa-css-prefix}-sticky-note:before { content: $fa-var-sticky-note; } +.#{$fa-css-prefix}-sticky-note-o:before { content: $fa-var-sticky-note-o; } +.#{$fa-css-prefix}-cc-jcb:before { content: $fa-var-cc-jcb; } +.#{$fa-css-prefix}-cc-diners-club:before { content: $fa-var-cc-diners-club; } +.#{$fa-css-prefix}-clone:before { content: $fa-var-clone; } +.#{$fa-css-prefix}-balance-scale:before { content: $fa-var-balance-scale; } +.#{$fa-css-prefix}-hourglass-o:before { content: $fa-var-hourglass-o; } +.#{$fa-css-prefix}-hourglass-1:before, +.#{$fa-css-prefix}-hourglass-start:before { content: $fa-var-hourglass-start; } +.#{$fa-css-prefix}-hourglass-2:before, +.#{$fa-css-prefix}-hourglass-half:before { content: $fa-var-hourglass-half; } +.#{$fa-css-prefix}-hourglass-3:before, +.#{$fa-css-prefix}-hourglass-end:before { content: $fa-var-hourglass-end; } +.#{$fa-css-prefix}-hourglass:before { content: $fa-var-hourglass; } +.#{$fa-css-prefix}-hand-grab-o:before, +.#{$fa-css-prefix}-hand-rock-o:before { content: $fa-var-hand-rock-o; } +.#{$fa-css-prefix}-hand-stop-o:before, +.#{$fa-css-prefix}-hand-paper-o:before { content: $fa-var-hand-paper-o; } +.#{$fa-css-prefix}-hand-scissors-o:before { content: $fa-var-hand-scissors-o; } +.#{$fa-css-prefix}-hand-lizard-o:before { content: $fa-var-hand-lizard-o; } +.#{$fa-css-prefix}-hand-spock-o:before { content: $fa-var-hand-spock-o; } +.#{$fa-css-prefix}-hand-pointer-o:before { content: $fa-var-hand-pointer-o; } +.#{$fa-css-prefix}-hand-peace-o:before { content: $fa-var-hand-peace-o; } +.#{$fa-css-prefix}-trademark:before { content: $fa-var-trademark; } +.#{$fa-css-prefix}-registered:before { content: $fa-var-registered; } +.#{$fa-css-prefix}-creative-commons:before { content: $fa-var-creative-commons; } +.#{$fa-css-prefix}-gg:before { content: $fa-var-gg; } +.#{$fa-css-prefix}-gg-circle:before { content: $fa-var-gg-circle; } +.#{$fa-css-prefix}-tripadvisor:before { content: $fa-var-tripadvisor; } +.#{$fa-css-prefix}-odnoklassniki:before { content: $fa-var-odnoklassniki; } +.#{$fa-css-prefix}-odnoklassniki-square:before { content: $fa-var-odnoklassniki-square; } +.#{$fa-css-prefix}-get-pocket:before { content: $fa-var-get-pocket; } +.#{$fa-css-prefix}-wikipedia-w:before { content: $fa-var-wikipedia-w; } +.#{$fa-css-prefix}-safari:before { content: $fa-var-safari; } +.#{$fa-css-prefix}-chrome:before { content: $fa-var-chrome; } +.#{$fa-css-prefix}-firefox:before { content: $fa-var-firefox; } +.#{$fa-css-prefix}-opera:before { content: $fa-var-opera; } +.#{$fa-css-prefix}-internet-explorer:before { content: $fa-var-internet-explorer; } +.#{$fa-css-prefix}-tv:before, +.#{$fa-css-prefix}-television:before { content: $fa-var-television; } +.#{$fa-css-prefix}-contao:before { content: $fa-var-contao; } +.#{$fa-css-prefix}-500px:before { content: $fa-var-500px; } +.#{$fa-css-prefix}-amazon:before { content: $fa-var-amazon; } +.#{$fa-css-prefix}-calendar-plus-o:before { content: $fa-var-calendar-plus-o; } +.#{$fa-css-prefix}-calendar-minus-o:before { content: $fa-var-calendar-minus-o; } +.#{$fa-css-prefix}-calendar-times-o:before { content: $fa-var-calendar-times-o; } +.#{$fa-css-prefix}-calendar-check-o:before { content: $fa-var-calendar-check-o; } +.#{$fa-css-prefix}-industry:before { content: $fa-var-industry; } +.#{$fa-css-prefix}-map-pin:before { content: $fa-var-map-pin; } +.#{$fa-css-prefix}-map-signs:before { content: $fa-var-map-signs; } +.#{$fa-css-prefix}-map-o:before { content: $fa-var-map-o; } +.#{$fa-css-prefix}-map:before { content: $fa-var-map; } +.#{$fa-css-prefix}-commenting:before { content: $fa-var-commenting; } +.#{$fa-css-prefix}-commenting-o:before { content: $fa-var-commenting-o; } +.#{$fa-css-prefix}-houzz:before { content: $fa-var-houzz; } +.#{$fa-css-prefix}-vimeo:before { content: $fa-var-vimeo; } +.#{$fa-css-prefix}-black-tie:before { content: $fa-var-black-tie; } +.#{$fa-css-prefix}-fonticons:before { content: $fa-var-fonticons; } +.#{$fa-css-prefix}-reddit-alien:before { content: $fa-var-reddit-alien; } +.#{$fa-css-prefix}-edge:before { content: $fa-var-edge; } +.#{$fa-css-prefix}-credit-card-alt:before { content: $fa-var-credit-card-alt; } +.#{$fa-css-prefix}-codiepie:before { content: $fa-var-codiepie; } +.#{$fa-css-prefix}-modx:before { content: $fa-var-modx; } +.#{$fa-css-prefix}-fort-awesome:before { content: $fa-var-fort-awesome; } +.#{$fa-css-prefix}-usb:before { content: $fa-var-usb; } +.#{$fa-css-prefix}-product-hunt:before { content: $fa-var-product-hunt; } +.#{$fa-css-prefix}-mixcloud:before { content: $fa-var-mixcloud; } +.#{$fa-css-prefix}-scribd:before { content: $fa-var-scribd; } +.#{$fa-css-prefix}-pause-circle:before { content: $fa-var-pause-circle; } +.#{$fa-css-prefix}-pause-circle-o:before { content: $fa-var-pause-circle-o; } +.#{$fa-css-prefix}-stop-circle:before { content: $fa-var-stop-circle; } +.#{$fa-css-prefix}-stop-circle-o:before { content: $fa-var-stop-circle-o; } +.#{$fa-css-prefix}-shopping-bag:before { content: $fa-var-shopping-bag; } +.#{$fa-css-prefix}-shopping-basket:before { content: $fa-var-shopping-basket; } +.#{$fa-css-prefix}-hashtag:before { content: $fa-var-hashtag; } +.#{$fa-css-prefix}-bluetooth:before { content: $fa-var-bluetooth; } +.#{$fa-css-prefix}-bluetooth-b:before { content: $fa-var-bluetooth-b; } +.#{$fa-css-prefix}-percent:before { content: $fa-var-percent; } +.#{$fa-css-prefix}-gitlab:before { content: $fa-var-gitlab; } +.#{$fa-css-prefix}-wpbeginner:before { content: $fa-var-wpbeginner; } +.#{$fa-css-prefix}-wpforms:before { content: $fa-var-wpforms; } +.#{$fa-css-prefix}-envira:before { content: $fa-var-envira; } +.#{$fa-css-prefix}-universal-access:before { content: $fa-var-universal-access; } +.#{$fa-css-prefix}-wheelchair-alt:before { content: $fa-var-wheelchair-alt; } +.#{$fa-css-prefix}-question-circle-o:before { content: $fa-var-question-circle-o; } +.#{$fa-css-prefix}-blind:before { content: $fa-var-blind; } +.#{$fa-css-prefix}-audio-description:before { content: $fa-var-audio-description; } +.#{$fa-css-prefix}-volume-control-phone:before { content: $fa-var-volume-control-phone; } +.#{$fa-css-prefix}-braille:before { content: $fa-var-braille; } +.#{$fa-css-prefix}-assistive-listening-systems:before { content: $fa-var-assistive-listening-systems; } +.#{$fa-css-prefix}-asl-interpreting:before, +.#{$fa-css-prefix}-american-sign-language-interpreting:before { content: $fa-var-american-sign-language-interpreting; } +.#{$fa-css-prefix}-deafness:before, +.#{$fa-css-prefix}-hard-of-hearing:before, +.#{$fa-css-prefix}-deaf:before { content: $fa-var-deaf; } +.#{$fa-css-prefix}-glide:before { content: $fa-var-glide; } +.#{$fa-css-prefix}-glide-g:before { content: $fa-var-glide-g; } +.#{$fa-css-prefix}-signing:before, +.#{$fa-css-prefix}-sign-language:before { content: $fa-var-sign-language; } +.#{$fa-css-prefix}-low-vision:before { content: $fa-var-low-vision; } +.#{$fa-css-prefix}-viadeo:before { content: $fa-var-viadeo; } +.#{$fa-css-prefix}-viadeo-square:before { content: $fa-var-viadeo-square; } +.#{$fa-css-prefix}-snapchat:before { content: $fa-var-snapchat; } +.#{$fa-css-prefix}-snapchat-ghost:before { content: $fa-var-snapchat-ghost; } +.#{$fa-css-prefix}-snapchat-square:before { content: $fa-var-snapchat-square; } +.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; } +.#{$fa-css-prefix}-first-order:before { content: $fa-var-first-order; } +.#{$fa-css-prefix}-yoast:before { content: $fa-var-yoast; } +.#{$fa-css-prefix}-themeisle:before { content: $fa-var-themeisle; } +.#{$fa-css-prefix}-google-plus-circle:before, +.#{$fa-css-prefix}-google-plus-official:before { content: $fa-var-google-plus-official; } +.#{$fa-css-prefix}-fa:before, +.#{$fa-css-prefix}-font-awesome:before { content: $fa-var-font-awesome; } +.#{$fa-css-prefix}-handshake-o:before { content: $fa-var-handshake-o; } +.#{$fa-css-prefix}-envelope-open:before { content: $fa-var-envelope-open; } +.#{$fa-css-prefix}-envelope-open-o:before { content: $fa-var-envelope-open-o; } +.#{$fa-css-prefix}-linode:before { content: $fa-var-linode; } +.#{$fa-css-prefix}-address-book:before { content: $fa-var-address-book; } +.#{$fa-css-prefix}-address-book-o:before { content: $fa-var-address-book-o; } +.#{$fa-css-prefix}-vcard:before, +.#{$fa-css-prefix}-address-card:before { content: $fa-var-address-card; } +.#{$fa-css-prefix}-vcard-o:before, +.#{$fa-css-prefix}-address-card-o:before { content: $fa-var-address-card-o; } +.#{$fa-css-prefix}-user-circle:before { content: $fa-var-user-circle; } +.#{$fa-css-prefix}-user-circle-o:before { content: $fa-var-user-circle-o; } +.#{$fa-css-prefix}-user-o:before { content: $fa-var-user-o; } +.#{$fa-css-prefix}-id-badge:before { content: $fa-var-id-badge; } +.#{$fa-css-prefix}-drivers-license:before, +.#{$fa-css-prefix}-id-card:before { content: $fa-var-id-card; } +.#{$fa-css-prefix}-drivers-license-o:before, +.#{$fa-css-prefix}-id-card-o:before { content: $fa-var-id-card-o; } +.#{$fa-css-prefix}-quora:before { content: $fa-var-quora; } +.#{$fa-css-prefix}-free-code-camp:before { content: $fa-var-free-code-camp; } +.#{$fa-css-prefix}-telegram:before { content: $fa-var-telegram; } +.#{$fa-css-prefix}-thermometer-4:before, +.#{$fa-css-prefix}-thermometer:before, +.#{$fa-css-prefix}-thermometer-full:before { content: $fa-var-thermometer-full; } +.#{$fa-css-prefix}-thermometer-3:before, +.#{$fa-css-prefix}-thermometer-three-quarters:before { content: $fa-var-thermometer-three-quarters; } +.#{$fa-css-prefix}-thermometer-2:before, +.#{$fa-css-prefix}-thermometer-half:before { content: $fa-var-thermometer-half; } +.#{$fa-css-prefix}-thermometer-1:before, +.#{$fa-css-prefix}-thermometer-quarter:before { content: $fa-var-thermometer-quarter; } +.#{$fa-css-prefix}-thermometer-0:before, +.#{$fa-css-prefix}-thermometer-empty:before { content: $fa-var-thermometer-empty; } +.#{$fa-css-prefix}-shower:before { content: $fa-var-shower; } +.#{$fa-css-prefix}-bathtub:before, +.#{$fa-css-prefix}-s15:before, +.#{$fa-css-prefix}-bath:before { content: $fa-var-bath; } +.#{$fa-css-prefix}-podcast:before { content: $fa-var-podcast; } +.#{$fa-css-prefix}-window-maximize:before { content: $fa-var-window-maximize; } +.#{$fa-css-prefix}-window-minimize:before { content: $fa-var-window-minimize; } +.#{$fa-css-prefix}-window-restore:before { content: $fa-var-window-restore; } +.#{$fa-css-prefix}-times-rectangle:before, +.#{$fa-css-prefix}-window-close:before { content: $fa-var-window-close; } +.#{$fa-css-prefix}-times-rectangle-o:before, +.#{$fa-css-prefix}-window-close-o:before { content: $fa-var-window-close-o; } +.#{$fa-css-prefix}-bandcamp:before { content: $fa-var-bandcamp; } +.#{$fa-css-prefix}-grav:before { content: $fa-var-grav; } +.#{$fa-css-prefix}-etsy:before { content: $fa-var-etsy; } +.#{$fa-css-prefix}-imdb:before { content: $fa-var-imdb; } +.#{$fa-css-prefix}-ravelry:before { content: $fa-var-ravelry; } +.#{$fa-css-prefix}-eercast:before { content: $fa-var-eercast; } +.#{$fa-css-prefix}-microchip:before { content: $fa-var-microchip; } +.#{$fa-css-prefix}-snowflake-o:before { content: $fa-var-snowflake-o; } +.#{$fa-css-prefix}-superpowers:before { content: $fa-var-superpowers; } +.#{$fa-css-prefix}-wpexplorer:before { content: $fa-var-wpexplorer; } +.#{$fa-css-prefix}-meetup:before { content: $fa-var-meetup; } diff --git a/js/font-awesome/scss/_larger.scss b/js/font-awesome/scss/_larger.scss new file mode 100644 index 000000000..41e9a8184 --- /dev/null +++ b/js/font-awesome/scss/_larger.scss @@ -0,0 +1,13 @@ +// Icon Sizes +// ------------------------- + +/* makes the font 33% larger relative to the icon container */ +.#{$fa-css-prefix}-lg { + font-size: (4em / 3); + line-height: (3em / 4); + vertical-align: -15%; +} +.#{$fa-css-prefix}-2x { font-size: 2em; } +.#{$fa-css-prefix}-3x { font-size: 3em; } +.#{$fa-css-prefix}-4x { font-size: 4em; } +.#{$fa-css-prefix}-5x { font-size: 5em; } diff --git a/js/font-awesome/scss/_list.scss b/js/font-awesome/scss/_list.scss new file mode 100644 index 000000000..7d1e4d54d --- /dev/null +++ b/js/font-awesome/scss/_list.scss @@ -0,0 +1,19 @@ +// List Icons +// ------------------------- + +.#{$fa-css-prefix}-ul { + padding-left: 0; + margin-left: $fa-li-width; + list-style-type: none; + > li { position: relative; } +} +.#{$fa-css-prefix}-li { + position: absolute; + left: -$fa-li-width; + width: $fa-li-width; + top: (2em / 14); + text-align: center; + &.#{$fa-css-prefix}-lg { + left: -$fa-li-width + (4em / 14); + } +} diff --git a/js/font-awesome/scss/_mixins.scss b/js/font-awesome/scss/_mixins.scss new file mode 100644 index 000000000..c3bbd5745 --- /dev/null +++ b/js/font-awesome/scss/_mixins.scss @@ -0,0 +1,60 @@ +// Mixins +// -------------------------- + +@mixin fa-icon() { + display: inline-block; + font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + +} + +@mixin fa-icon-rotate($degrees, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; + -webkit-transform: rotate($degrees); + -ms-transform: rotate($degrees); + transform: rotate($degrees); +} + +@mixin fa-icon-flip($horiz, $vert, $rotation) { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; + -webkit-transform: scale($horiz, $vert); + -ms-transform: scale($horiz, $vert); + transform: scale($horiz, $vert); +} + + +// Only display content to screen readers. A la Bootstrap 4. +// +// See: http://a11yproject.com/posts/how-to-hide-content/ + +@mixin sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0,0,0,0); + border: 0; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +@mixin sr-only-focusable { + &:active, + &:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; + } +} diff --git a/js/font-awesome/scss/_path.scss b/js/font-awesome/scss/_path.scss new file mode 100644 index 000000000..bb457c23a --- /dev/null +++ b/js/font-awesome/scss/_path.scss @@ -0,0 +1,15 @@ +/* FONT PATH + * -------------------------- */ + +@font-face { + font-family: 'FontAwesome'; + src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); + src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), + url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), + url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), + url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), + url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); +// src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts + font-weight: normal; + font-style: normal; +} diff --git a/js/font-awesome/scss/_rotated-flipped.scss b/js/font-awesome/scss/_rotated-flipped.scss new file mode 100644 index 000000000..a3558fd09 --- /dev/null +++ b/js/font-awesome/scss/_rotated-flipped.scss @@ -0,0 +1,20 @@ +// Rotated & Flipped Icons +// ------------------------- + +.#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } +.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } +.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } + +.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } +.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } + +// Hook for IE8-9 +// ------------------------- + +:root .#{$fa-css-prefix}-rotate-90, +:root .#{$fa-css-prefix}-rotate-180, +:root .#{$fa-css-prefix}-rotate-270, +:root .#{$fa-css-prefix}-flip-horizontal, +:root .#{$fa-css-prefix}-flip-vertical { + filter: none; +} diff --git a/js/font-awesome/scss/_screen-reader.scss b/js/font-awesome/scss/_screen-reader.scss new file mode 100644 index 000000000..637426f0d --- /dev/null +++ b/js/font-awesome/scss/_screen-reader.scss @@ -0,0 +1,5 @@ +// Screen Readers +// ------------------------- + +.sr-only { @include sr-only(); } +.sr-only-focusable { @include sr-only-focusable(); } diff --git a/js/font-awesome/scss/_stacked.scss b/js/font-awesome/scss/_stacked.scss new file mode 100644 index 000000000..aef740366 --- /dev/null +++ b/js/font-awesome/scss/_stacked.scss @@ -0,0 +1,20 @@ +// Stacked Icons +// ------------------------- + +.#{$fa-css-prefix}-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.#{$fa-css-prefix}-stack-1x { line-height: inherit; } +.#{$fa-css-prefix}-stack-2x { font-size: 2em; } +.#{$fa-css-prefix}-inverse { color: $fa-inverse; } diff --git a/js/font-awesome/scss/_variables.scss b/js/font-awesome/scss/_variables.scss new file mode 100644 index 000000000..498fc4a08 --- /dev/null +++ b/js/font-awesome/scss/_variables.scss @@ -0,0 +1,800 @@ +// Variables +// -------------------------- + +$fa-font-path: "../fonts" !default; +$fa-font-size-base: 14px !default; +$fa-line-height-base: 1 !default; +//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.7.0/fonts" !default; // for referencing Bootstrap CDN font files directly +$fa-css-prefix: fa !default; +$fa-version: "4.7.0" !default; +$fa-border-color: #eee !default; +$fa-inverse: #fff !default; +$fa-li-width: (30em / 14) !default; + +$fa-var-500px: "\f26e"; +$fa-var-address-book: "\f2b9"; +$fa-var-address-book-o: "\f2ba"; +$fa-var-address-card: "\f2bb"; +$fa-var-address-card-o: "\f2bc"; +$fa-var-adjust: "\f042"; +$fa-var-adn: "\f170"; +$fa-var-align-center: "\f037"; +$fa-var-align-justify: "\f039"; +$fa-var-align-left: "\f036"; +$fa-var-align-right: "\f038"; +$fa-var-amazon: "\f270"; +$fa-var-ambulance: "\f0f9"; +$fa-var-american-sign-language-interpreting: "\f2a3"; +$fa-var-anchor: "\f13d"; +$fa-var-android: "\f17b"; +$fa-var-angellist: "\f209"; +$fa-var-angle-double-down: "\f103"; +$fa-var-angle-double-left: "\f100"; +$fa-var-angle-double-right: "\f101"; +$fa-var-angle-double-up: "\f102"; +$fa-var-angle-down: "\f107"; +$fa-var-angle-left: "\f104"; +$fa-var-angle-right: "\f105"; +$fa-var-angle-up: "\f106"; +$fa-var-apple: "\f179"; +$fa-var-archive: "\f187"; +$fa-var-area-chart: "\f1fe"; +$fa-var-arrow-circle-down: "\f0ab"; +$fa-var-arrow-circle-left: "\f0a8"; +$fa-var-arrow-circle-o-down: "\f01a"; +$fa-var-arrow-circle-o-left: "\f190"; +$fa-var-arrow-circle-o-right: "\f18e"; +$fa-var-arrow-circle-o-up: "\f01b"; +$fa-var-arrow-circle-right: "\f0a9"; +$fa-var-arrow-circle-up: "\f0aa"; +$fa-var-arrow-down: "\f063"; +$fa-var-arrow-left: "\f060"; +$fa-var-arrow-right: "\f061"; +$fa-var-arrow-up: "\f062"; +$fa-var-arrows: "\f047"; +$fa-var-arrows-alt: "\f0b2"; +$fa-var-arrows-h: "\f07e"; +$fa-var-arrows-v: "\f07d"; +$fa-var-asl-interpreting: "\f2a3"; +$fa-var-assistive-listening-systems: "\f2a2"; +$fa-var-asterisk: "\f069"; +$fa-var-at: "\f1fa"; +$fa-var-audio-description: "\f29e"; +$fa-var-automobile: "\f1b9"; +$fa-var-backward: "\f04a"; +$fa-var-balance-scale: "\f24e"; +$fa-var-ban: "\f05e"; +$fa-var-bandcamp: "\f2d5"; +$fa-var-bank: "\f19c"; +$fa-var-bar-chart: "\f080"; +$fa-var-bar-chart-o: "\f080"; +$fa-var-barcode: "\f02a"; +$fa-var-bars: "\f0c9"; +$fa-var-bath: "\f2cd"; +$fa-var-bathtub: "\f2cd"; +$fa-var-battery: "\f240"; +$fa-var-battery-0: "\f244"; +$fa-var-battery-1: "\f243"; +$fa-var-battery-2: "\f242"; +$fa-var-battery-3: "\f241"; +$fa-var-battery-4: "\f240"; +$fa-var-battery-empty: "\f244"; +$fa-var-battery-full: "\f240"; +$fa-var-battery-half: "\f242"; +$fa-var-battery-quarter: "\f243"; +$fa-var-battery-three-quarters: "\f241"; +$fa-var-bed: "\f236"; +$fa-var-beer: "\f0fc"; +$fa-var-behance: "\f1b4"; +$fa-var-behance-square: "\f1b5"; +$fa-var-bell: "\f0f3"; +$fa-var-bell-o: "\f0a2"; +$fa-var-bell-slash: "\f1f6"; +$fa-var-bell-slash-o: "\f1f7"; +$fa-var-bicycle: "\f206"; +$fa-var-binoculars: "\f1e5"; +$fa-var-birthday-cake: "\f1fd"; +$fa-var-bitbucket: "\f171"; +$fa-var-bitbucket-square: "\f172"; +$fa-var-bitcoin: "\f15a"; +$fa-var-black-tie: "\f27e"; +$fa-var-blind: "\f29d"; +$fa-var-bluetooth: "\f293"; +$fa-var-bluetooth-b: "\f294"; +$fa-var-bold: "\f032"; +$fa-var-bolt: "\f0e7"; +$fa-var-bomb: "\f1e2"; +$fa-var-book: "\f02d"; +$fa-var-bookmark: "\f02e"; +$fa-var-bookmark-o: "\f097"; +$fa-var-braille: "\f2a1"; +$fa-var-briefcase: "\f0b1"; +$fa-var-btc: "\f15a"; +$fa-var-bug: "\f188"; +$fa-var-building: "\f1ad"; +$fa-var-building-o: "\f0f7"; +$fa-var-bullhorn: "\f0a1"; +$fa-var-bullseye: "\f140"; +$fa-var-bus: "\f207"; +$fa-var-buysellads: "\f20d"; +$fa-var-cab: "\f1ba"; +$fa-var-calculator: "\f1ec"; +$fa-var-calendar: "\f073"; +$fa-var-calendar-check-o: "\f274"; +$fa-var-calendar-minus-o: "\f272"; +$fa-var-calendar-o: "\f133"; +$fa-var-calendar-plus-o: "\f271"; +$fa-var-calendar-times-o: "\f273"; +$fa-var-camera: "\f030"; +$fa-var-camera-retro: "\f083"; +$fa-var-car: "\f1b9"; +$fa-var-caret-down: "\f0d7"; +$fa-var-caret-left: "\f0d9"; +$fa-var-caret-right: "\f0da"; +$fa-var-caret-square-o-down: "\f150"; +$fa-var-caret-square-o-left: "\f191"; +$fa-var-caret-square-o-right: "\f152"; +$fa-var-caret-square-o-up: "\f151"; +$fa-var-caret-up: "\f0d8"; +$fa-var-cart-arrow-down: "\f218"; +$fa-var-cart-plus: "\f217"; +$fa-var-cc: "\f20a"; +$fa-var-cc-amex: "\f1f3"; +$fa-var-cc-diners-club: "\f24c"; +$fa-var-cc-discover: "\f1f2"; +$fa-var-cc-jcb: "\f24b"; +$fa-var-cc-mastercard: "\f1f1"; +$fa-var-cc-paypal: "\f1f4"; +$fa-var-cc-stripe: "\f1f5"; +$fa-var-cc-visa: "\f1f0"; +$fa-var-certificate: "\f0a3"; +$fa-var-chain: "\f0c1"; +$fa-var-chain-broken: "\f127"; +$fa-var-check: "\f00c"; +$fa-var-check-circle: "\f058"; +$fa-var-check-circle-o: "\f05d"; +$fa-var-check-square: "\f14a"; +$fa-var-check-square-o: "\f046"; +$fa-var-chevron-circle-down: "\f13a"; +$fa-var-chevron-circle-left: "\f137"; +$fa-var-chevron-circle-right: "\f138"; +$fa-var-chevron-circle-up: "\f139"; +$fa-var-chevron-down: "\f078"; +$fa-var-chevron-left: "\f053"; +$fa-var-chevron-right: "\f054"; +$fa-var-chevron-up: "\f077"; +$fa-var-child: "\f1ae"; +$fa-var-chrome: "\f268"; +$fa-var-circle: "\f111"; +$fa-var-circle-o: "\f10c"; +$fa-var-circle-o-notch: "\f1ce"; +$fa-var-circle-thin: "\f1db"; +$fa-var-clipboard: "\f0ea"; +$fa-var-clock-o: "\f017"; +$fa-var-clone: "\f24d"; +$fa-var-close: "\f00d"; +$fa-var-cloud: "\f0c2"; +$fa-var-cloud-download: "\f0ed"; +$fa-var-cloud-upload: "\f0ee"; +$fa-var-cny: "\f157"; +$fa-var-code: "\f121"; +$fa-var-code-fork: "\f126"; +$fa-var-codepen: "\f1cb"; +$fa-var-codiepie: "\f284"; +$fa-var-coffee: "\f0f4"; +$fa-var-cog: "\f013"; +$fa-var-cogs: "\f085"; +$fa-var-columns: "\f0db"; +$fa-var-comment: "\f075"; +$fa-var-comment-o: "\f0e5"; +$fa-var-commenting: "\f27a"; +$fa-var-commenting-o: "\f27b"; +$fa-var-comments: "\f086"; +$fa-var-comments-o: "\f0e6"; +$fa-var-compass: "\f14e"; +$fa-var-compress: "\f066"; +$fa-var-connectdevelop: "\f20e"; +$fa-var-contao: "\f26d"; +$fa-var-copy: "\f0c5"; +$fa-var-copyright: "\f1f9"; +$fa-var-creative-commons: "\f25e"; +$fa-var-credit-card: "\f09d"; +$fa-var-credit-card-alt: "\f283"; +$fa-var-crop: "\f125"; +$fa-var-crosshairs: "\f05b"; +$fa-var-css3: "\f13c"; +$fa-var-cube: "\f1b2"; +$fa-var-cubes: "\f1b3"; +$fa-var-cut: "\f0c4"; +$fa-var-cutlery: "\f0f5"; +$fa-var-dashboard: "\f0e4"; +$fa-var-dashcube: "\f210"; +$fa-var-database: "\f1c0"; +$fa-var-deaf: "\f2a4"; +$fa-var-deafness: "\f2a4"; +$fa-var-dedent: "\f03b"; +$fa-var-delicious: "\f1a5"; +$fa-var-desktop: "\f108"; +$fa-var-deviantart: "\f1bd"; +$fa-var-diamond: "\f219"; +$fa-var-digg: "\f1a6"; +$fa-var-dollar: "\f155"; +$fa-var-dot-circle-o: "\f192"; +$fa-var-download: "\f019"; +$fa-var-dribbble: "\f17d"; +$fa-var-drivers-license: "\f2c2"; +$fa-var-drivers-license-o: "\f2c3"; +$fa-var-dropbox: "\f16b"; +$fa-var-drupal: "\f1a9"; +$fa-var-edge: "\f282"; +$fa-var-edit: "\f044"; +$fa-var-eercast: "\f2da"; +$fa-var-eject: "\f052"; +$fa-var-ellipsis-h: "\f141"; +$fa-var-ellipsis-v: "\f142"; +$fa-var-empire: "\f1d1"; +$fa-var-envelope: "\f0e0"; +$fa-var-envelope-o: "\f003"; +$fa-var-envelope-open: "\f2b6"; +$fa-var-envelope-open-o: "\f2b7"; +$fa-var-envelope-square: "\f199"; +$fa-var-envira: "\f299"; +$fa-var-eraser: "\f12d"; +$fa-var-etsy: "\f2d7"; +$fa-var-eur: "\f153"; +$fa-var-euro: "\f153"; +$fa-var-exchange: "\f0ec"; +$fa-var-exclamation: "\f12a"; +$fa-var-exclamation-circle: "\f06a"; +$fa-var-exclamation-triangle: "\f071"; +$fa-var-expand: "\f065"; +$fa-var-expeditedssl: "\f23e"; +$fa-var-external-link: "\f08e"; +$fa-var-external-link-square: "\f14c"; +$fa-var-eye: "\f06e"; +$fa-var-eye-slash: "\f070"; +$fa-var-eyedropper: "\f1fb"; +$fa-var-fa: "\f2b4"; +$fa-var-facebook: "\f09a"; +$fa-var-facebook-f: "\f09a"; +$fa-var-facebook-official: "\f230"; +$fa-var-facebook-square: "\f082"; +$fa-var-fast-backward: "\f049"; +$fa-var-fast-forward: "\f050"; +$fa-var-fax: "\f1ac"; +$fa-var-feed: "\f09e"; +$fa-var-female: "\f182"; +$fa-var-fighter-jet: "\f0fb"; +$fa-var-file: "\f15b"; +$fa-var-file-archive-o: "\f1c6"; +$fa-var-file-audio-o: "\f1c7"; +$fa-var-file-code-o: "\f1c9"; +$fa-var-file-excel-o: "\f1c3"; +$fa-var-file-image-o: "\f1c5"; +$fa-var-file-movie-o: "\f1c8"; +$fa-var-file-o: "\f016"; +$fa-var-file-pdf-o: "\f1c1"; +$fa-var-file-photo-o: "\f1c5"; +$fa-var-file-picture-o: "\f1c5"; +$fa-var-file-powerpoint-o: "\f1c4"; +$fa-var-file-sound-o: "\f1c7"; +$fa-var-file-text: "\f15c"; +$fa-var-file-text-o: "\f0f6"; +$fa-var-file-video-o: "\f1c8"; +$fa-var-file-word-o: "\f1c2"; +$fa-var-file-zip-o: "\f1c6"; +$fa-var-files-o: "\f0c5"; +$fa-var-film: "\f008"; +$fa-var-filter: "\f0b0"; +$fa-var-fire: "\f06d"; +$fa-var-fire-extinguisher: "\f134"; +$fa-var-firefox: "\f269"; +$fa-var-first-order: "\f2b0"; +$fa-var-flag: "\f024"; +$fa-var-flag-checkered: "\f11e"; +$fa-var-flag-o: "\f11d"; +$fa-var-flash: "\f0e7"; +$fa-var-flask: "\f0c3"; +$fa-var-flickr: "\f16e"; +$fa-var-floppy-o: "\f0c7"; +$fa-var-folder: "\f07b"; +$fa-var-folder-o: "\f114"; +$fa-var-folder-open: "\f07c"; +$fa-var-folder-open-o: "\f115"; +$fa-var-font: "\f031"; +$fa-var-font-awesome: "\f2b4"; +$fa-var-fonticons: "\f280"; +$fa-var-fort-awesome: "\f286"; +$fa-var-forumbee: "\f211"; +$fa-var-forward: "\f04e"; +$fa-var-foursquare: "\f180"; +$fa-var-free-code-camp: "\f2c5"; +$fa-var-frown-o: "\f119"; +$fa-var-futbol-o: "\f1e3"; +$fa-var-gamepad: "\f11b"; +$fa-var-gavel: "\f0e3"; +$fa-var-gbp: "\f154"; +$fa-var-ge: "\f1d1"; +$fa-var-gear: "\f013"; +$fa-var-gears: "\f085"; +$fa-var-genderless: "\f22d"; +$fa-var-get-pocket: "\f265"; +$fa-var-gg: "\f260"; +$fa-var-gg-circle: "\f261"; +$fa-var-gift: "\f06b"; +$fa-var-git: "\f1d3"; +$fa-var-git-square: "\f1d2"; +$fa-var-github: "\f09b"; +$fa-var-github-alt: "\f113"; +$fa-var-github-square: "\f092"; +$fa-var-gitlab: "\f296"; +$fa-var-gittip: "\f184"; +$fa-var-glass: "\f000"; +$fa-var-glide: "\f2a5"; +$fa-var-glide-g: "\f2a6"; +$fa-var-globe: "\f0ac"; +$fa-var-google: "\f1a0"; +$fa-var-google-plus: "\f0d5"; +$fa-var-google-plus-circle: "\f2b3"; +$fa-var-google-plus-official: "\f2b3"; +$fa-var-google-plus-square: "\f0d4"; +$fa-var-google-wallet: "\f1ee"; +$fa-var-graduation-cap: "\f19d"; +$fa-var-gratipay: "\f184"; +$fa-var-grav: "\f2d6"; +$fa-var-group: "\f0c0"; +$fa-var-h-square: "\f0fd"; +$fa-var-hacker-news: "\f1d4"; +$fa-var-hand-grab-o: "\f255"; +$fa-var-hand-lizard-o: "\f258"; +$fa-var-hand-o-down: "\f0a7"; +$fa-var-hand-o-left: "\f0a5"; +$fa-var-hand-o-right: "\f0a4"; +$fa-var-hand-o-up: "\f0a6"; +$fa-var-hand-paper-o: "\f256"; +$fa-var-hand-peace-o: "\f25b"; +$fa-var-hand-pointer-o: "\f25a"; +$fa-var-hand-rock-o: "\f255"; +$fa-var-hand-scissors-o: "\f257"; +$fa-var-hand-spock-o: "\f259"; +$fa-var-hand-stop-o: "\f256"; +$fa-var-handshake-o: "\f2b5"; +$fa-var-hard-of-hearing: "\f2a4"; +$fa-var-hashtag: "\f292"; +$fa-var-hdd-o: "\f0a0"; +$fa-var-header: "\f1dc"; +$fa-var-headphones: "\f025"; +$fa-var-heart: "\f004"; +$fa-var-heart-o: "\f08a"; +$fa-var-heartbeat: "\f21e"; +$fa-var-history: "\f1da"; +$fa-var-home: "\f015"; +$fa-var-hospital-o: "\f0f8"; +$fa-var-hotel: "\f236"; +$fa-var-hourglass: "\f254"; +$fa-var-hourglass-1: "\f251"; +$fa-var-hourglass-2: "\f252"; +$fa-var-hourglass-3: "\f253"; +$fa-var-hourglass-end: "\f253"; +$fa-var-hourglass-half: "\f252"; +$fa-var-hourglass-o: "\f250"; +$fa-var-hourglass-start: "\f251"; +$fa-var-houzz: "\f27c"; +$fa-var-html5: "\f13b"; +$fa-var-i-cursor: "\f246"; +$fa-var-id-badge: "\f2c1"; +$fa-var-id-card: "\f2c2"; +$fa-var-id-card-o: "\f2c3"; +$fa-var-ils: "\f20b"; +$fa-var-image: "\f03e"; +$fa-var-imdb: "\f2d8"; +$fa-var-inbox: "\f01c"; +$fa-var-indent: "\f03c"; +$fa-var-industry: "\f275"; +$fa-var-info: "\f129"; +$fa-var-info-circle: "\f05a"; +$fa-var-inr: "\f156"; +$fa-var-instagram: "\f16d"; +$fa-var-institution: "\f19c"; +$fa-var-internet-explorer: "\f26b"; +$fa-var-intersex: "\f224"; +$fa-var-ioxhost: "\f208"; +$fa-var-italic: "\f033"; +$fa-var-joomla: "\f1aa"; +$fa-var-jpy: "\f157"; +$fa-var-jsfiddle: "\f1cc"; +$fa-var-key: "\f084"; +$fa-var-keyboard-o: "\f11c"; +$fa-var-krw: "\f159"; +$fa-var-language: "\f1ab"; +$fa-var-laptop: "\f109"; +$fa-var-lastfm: "\f202"; +$fa-var-lastfm-square: "\f203"; +$fa-var-leaf: "\f06c"; +$fa-var-leanpub: "\f212"; +$fa-var-legal: "\f0e3"; +$fa-var-lemon-o: "\f094"; +$fa-var-level-down: "\f149"; +$fa-var-level-up: "\f148"; +$fa-var-life-bouy: "\f1cd"; +$fa-var-life-buoy: "\f1cd"; +$fa-var-life-ring: "\f1cd"; +$fa-var-life-saver: "\f1cd"; +$fa-var-lightbulb-o: "\f0eb"; +$fa-var-line-chart: "\f201"; +$fa-var-link: "\f0c1"; +$fa-var-linkedin: "\f0e1"; +$fa-var-linkedin-square: "\f08c"; +$fa-var-linode: "\f2b8"; +$fa-var-linux: "\f17c"; +$fa-var-list: "\f03a"; +$fa-var-list-alt: "\f022"; +$fa-var-list-ol: "\f0cb"; +$fa-var-list-ul: "\f0ca"; +$fa-var-location-arrow: "\f124"; +$fa-var-lock: "\f023"; +$fa-var-long-arrow-down: "\f175"; +$fa-var-long-arrow-left: "\f177"; +$fa-var-long-arrow-right: "\f178"; +$fa-var-long-arrow-up: "\f176"; +$fa-var-low-vision: "\f2a8"; +$fa-var-magic: "\f0d0"; +$fa-var-magnet: "\f076"; +$fa-var-mail-forward: "\f064"; +$fa-var-mail-reply: "\f112"; +$fa-var-mail-reply-all: "\f122"; +$fa-var-male: "\f183"; +$fa-var-map: "\f279"; +$fa-var-map-marker: "\f041"; +$fa-var-map-o: "\f278"; +$fa-var-map-pin: "\f276"; +$fa-var-map-signs: "\f277"; +$fa-var-mars: "\f222"; +$fa-var-mars-double: "\f227"; +$fa-var-mars-stroke: "\f229"; +$fa-var-mars-stroke-h: "\f22b"; +$fa-var-mars-stroke-v: "\f22a"; +$fa-var-maxcdn: "\f136"; +$fa-var-meanpath: "\f20c"; +$fa-var-medium: "\f23a"; +$fa-var-medkit: "\f0fa"; +$fa-var-meetup: "\f2e0"; +$fa-var-meh-o: "\f11a"; +$fa-var-mercury: "\f223"; +$fa-var-microchip: "\f2db"; +$fa-var-microphone: "\f130"; +$fa-var-microphone-slash: "\f131"; +$fa-var-minus: "\f068"; +$fa-var-minus-circle: "\f056"; +$fa-var-minus-square: "\f146"; +$fa-var-minus-square-o: "\f147"; +$fa-var-mixcloud: "\f289"; +$fa-var-mobile: "\f10b"; +$fa-var-mobile-phone: "\f10b"; +$fa-var-modx: "\f285"; +$fa-var-money: "\f0d6"; +$fa-var-moon-o: "\f186"; +$fa-var-mortar-board: "\f19d"; +$fa-var-motorcycle: "\f21c"; +$fa-var-mouse-pointer: "\f245"; +$fa-var-music: "\f001"; +$fa-var-navicon: "\f0c9"; +$fa-var-neuter: "\f22c"; +$fa-var-newspaper-o: "\f1ea"; +$fa-var-object-group: "\f247"; +$fa-var-object-ungroup: "\f248"; +$fa-var-odnoklassniki: "\f263"; +$fa-var-odnoklassniki-square: "\f264"; +$fa-var-opencart: "\f23d"; +$fa-var-openid: "\f19b"; +$fa-var-opera: "\f26a"; +$fa-var-optin-monster: "\f23c"; +$fa-var-outdent: "\f03b"; +$fa-var-pagelines: "\f18c"; +$fa-var-paint-brush: "\f1fc"; +$fa-var-paper-plane: "\f1d8"; +$fa-var-paper-plane-o: "\f1d9"; +$fa-var-paperclip: "\f0c6"; +$fa-var-paragraph: "\f1dd"; +$fa-var-paste: "\f0ea"; +$fa-var-pause: "\f04c"; +$fa-var-pause-circle: "\f28b"; +$fa-var-pause-circle-o: "\f28c"; +$fa-var-paw: "\f1b0"; +$fa-var-paypal: "\f1ed"; +$fa-var-pencil: "\f040"; +$fa-var-pencil-square: "\f14b"; +$fa-var-pencil-square-o: "\f044"; +$fa-var-percent: "\f295"; +$fa-var-phone: "\f095"; +$fa-var-phone-square: "\f098"; +$fa-var-photo: "\f03e"; +$fa-var-picture-o: "\f03e"; +$fa-var-pie-chart: "\f200"; +$fa-var-pied-piper: "\f2ae"; +$fa-var-pied-piper-alt: "\f1a8"; +$fa-var-pied-piper-pp: "\f1a7"; +$fa-var-pinterest: "\f0d2"; +$fa-var-pinterest-p: "\f231"; +$fa-var-pinterest-square: "\f0d3"; +$fa-var-plane: "\f072"; +$fa-var-play: "\f04b"; +$fa-var-play-circle: "\f144"; +$fa-var-play-circle-o: "\f01d"; +$fa-var-plug: "\f1e6"; +$fa-var-plus: "\f067"; +$fa-var-plus-circle: "\f055"; +$fa-var-plus-square: "\f0fe"; +$fa-var-plus-square-o: "\f196"; +$fa-var-podcast: "\f2ce"; +$fa-var-power-off: "\f011"; +$fa-var-print: "\f02f"; +$fa-var-product-hunt: "\f288"; +$fa-var-puzzle-piece: "\f12e"; +$fa-var-qq: "\f1d6"; +$fa-var-qrcode: "\f029"; +$fa-var-question: "\f128"; +$fa-var-question-circle: "\f059"; +$fa-var-question-circle-o: "\f29c"; +$fa-var-quora: "\f2c4"; +$fa-var-quote-left: "\f10d"; +$fa-var-quote-right: "\f10e"; +$fa-var-ra: "\f1d0"; +$fa-var-random: "\f074"; +$fa-var-ravelry: "\f2d9"; +$fa-var-rebel: "\f1d0"; +$fa-var-recycle: "\f1b8"; +$fa-var-reddit: "\f1a1"; +$fa-var-reddit-alien: "\f281"; +$fa-var-reddit-square: "\f1a2"; +$fa-var-refresh: "\f021"; +$fa-var-registered: "\f25d"; +$fa-var-remove: "\f00d"; +$fa-var-renren: "\f18b"; +$fa-var-reorder: "\f0c9"; +$fa-var-repeat: "\f01e"; +$fa-var-reply: "\f112"; +$fa-var-reply-all: "\f122"; +$fa-var-resistance: "\f1d0"; +$fa-var-retweet: "\f079"; +$fa-var-rmb: "\f157"; +$fa-var-road: "\f018"; +$fa-var-rocket: "\f135"; +$fa-var-rotate-left: "\f0e2"; +$fa-var-rotate-right: "\f01e"; +$fa-var-rouble: "\f158"; +$fa-var-rss: "\f09e"; +$fa-var-rss-square: "\f143"; +$fa-var-rub: "\f158"; +$fa-var-ruble: "\f158"; +$fa-var-rupee: "\f156"; +$fa-var-s15: "\f2cd"; +$fa-var-safari: "\f267"; +$fa-var-save: "\f0c7"; +$fa-var-scissors: "\f0c4"; +$fa-var-scribd: "\f28a"; +$fa-var-search: "\f002"; +$fa-var-search-minus: "\f010"; +$fa-var-search-plus: "\f00e"; +$fa-var-sellsy: "\f213"; +$fa-var-send: "\f1d8"; +$fa-var-send-o: "\f1d9"; +$fa-var-server: "\f233"; +$fa-var-share: "\f064"; +$fa-var-share-alt: "\f1e0"; +$fa-var-share-alt-square: "\f1e1"; +$fa-var-share-square: "\f14d"; +$fa-var-share-square-o: "\f045"; +$fa-var-shekel: "\f20b"; +$fa-var-sheqel: "\f20b"; +$fa-var-shield: "\f132"; +$fa-var-ship: "\f21a"; +$fa-var-shirtsinbulk: "\f214"; +$fa-var-shopping-bag: "\f290"; +$fa-var-shopping-basket: "\f291"; +$fa-var-shopping-cart: "\f07a"; +$fa-var-shower: "\f2cc"; +$fa-var-sign-in: "\f090"; +$fa-var-sign-language: "\f2a7"; +$fa-var-sign-out: "\f08b"; +$fa-var-signal: "\f012"; +$fa-var-signing: "\f2a7"; +$fa-var-simplybuilt: "\f215"; +$fa-var-sitemap: "\f0e8"; +$fa-var-skyatlas: "\f216"; +$fa-var-skype: "\f17e"; +$fa-var-slack: "\f198"; +$fa-var-sliders: "\f1de"; +$fa-var-slideshare: "\f1e7"; +$fa-var-smile-o: "\f118"; +$fa-var-snapchat: "\f2ab"; +$fa-var-snapchat-ghost: "\f2ac"; +$fa-var-snapchat-square: "\f2ad"; +$fa-var-snowflake-o: "\f2dc"; +$fa-var-soccer-ball-o: "\f1e3"; +$fa-var-sort: "\f0dc"; +$fa-var-sort-alpha-asc: "\f15d"; +$fa-var-sort-alpha-desc: "\f15e"; +$fa-var-sort-amount-asc: "\f160"; +$fa-var-sort-amount-desc: "\f161"; +$fa-var-sort-asc: "\f0de"; +$fa-var-sort-desc: "\f0dd"; +$fa-var-sort-down: "\f0dd"; +$fa-var-sort-numeric-asc: "\f162"; +$fa-var-sort-numeric-desc: "\f163"; +$fa-var-sort-up: "\f0de"; +$fa-var-soundcloud: "\f1be"; +$fa-var-space-shuttle: "\f197"; +$fa-var-spinner: "\f110"; +$fa-var-spoon: "\f1b1"; +$fa-var-spotify: "\f1bc"; +$fa-var-square: "\f0c8"; +$fa-var-square-o: "\f096"; +$fa-var-stack-exchange: "\f18d"; +$fa-var-stack-overflow: "\f16c"; +$fa-var-star: "\f005"; +$fa-var-star-half: "\f089"; +$fa-var-star-half-empty: "\f123"; +$fa-var-star-half-full: "\f123"; +$fa-var-star-half-o: "\f123"; +$fa-var-star-o: "\f006"; +$fa-var-steam: "\f1b6"; +$fa-var-steam-square: "\f1b7"; +$fa-var-step-backward: "\f048"; +$fa-var-step-forward: "\f051"; +$fa-var-stethoscope: "\f0f1"; +$fa-var-sticky-note: "\f249"; +$fa-var-sticky-note-o: "\f24a"; +$fa-var-stop: "\f04d"; +$fa-var-stop-circle: "\f28d"; +$fa-var-stop-circle-o: "\f28e"; +$fa-var-street-view: "\f21d"; +$fa-var-strikethrough: "\f0cc"; +$fa-var-stumbleupon: "\f1a4"; +$fa-var-stumbleupon-circle: "\f1a3"; +$fa-var-subscript: "\f12c"; +$fa-var-subway: "\f239"; +$fa-var-suitcase: "\f0f2"; +$fa-var-sun-o: "\f185"; +$fa-var-superpowers: "\f2dd"; +$fa-var-superscript: "\f12b"; +$fa-var-support: "\f1cd"; +$fa-var-table: "\f0ce"; +$fa-var-tablet: "\f10a"; +$fa-var-tachometer: "\f0e4"; +$fa-var-tag: "\f02b"; +$fa-var-tags: "\f02c"; +$fa-var-tasks: "\f0ae"; +$fa-var-taxi: "\f1ba"; +$fa-var-telegram: "\f2c6"; +$fa-var-television: "\f26c"; +$fa-var-tencent-weibo: "\f1d5"; +$fa-var-terminal: "\f120"; +$fa-var-text-height: "\f034"; +$fa-var-text-width: "\f035"; +$fa-var-th: "\f00a"; +$fa-var-th-large: "\f009"; +$fa-var-th-list: "\f00b"; +$fa-var-themeisle: "\f2b2"; +$fa-var-thermometer: "\f2c7"; +$fa-var-thermometer-0: "\f2cb"; +$fa-var-thermometer-1: "\f2ca"; +$fa-var-thermometer-2: "\f2c9"; +$fa-var-thermometer-3: "\f2c8"; +$fa-var-thermometer-4: "\f2c7"; +$fa-var-thermometer-empty: "\f2cb"; +$fa-var-thermometer-full: "\f2c7"; +$fa-var-thermometer-half: "\f2c9"; +$fa-var-thermometer-quarter: "\f2ca"; +$fa-var-thermometer-three-quarters: "\f2c8"; +$fa-var-thumb-tack: "\f08d"; +$fa-var-thumbs-down: "\f165"; +$fa-var-thumbs-o-down: "\f088"; +$fa-var-thumbs-o-up: "\f087"; +$fa-var-thumbs-up: "\f164"; +$fa-var-ticket: "\f145"; +$fa-var-times: "\f00d"; +$fa-var-times-circle: "\f057"; +$fa-var-times-circle-o: "\f05c"; +$fa-var-times-rectangle: "\f2d3"; +$fa-var-times-rectangle-o: "\f2d4"; +$fa-var-tint: "\f043"; +$fa-var-toggle-down: "\f150"; +$fa-var-toggle-left: "\f191"; +$fa-var-toggle-off: "\f204"; +$fa-var-toggle-on: "\f205"; +$fa-var-toggle-right: "\f152"; +$fa-var-toggle-up: "\f151"; +$fa-var-trademark: "\f25c"; +$fa-var-train: "\f238"; +$fa-var-transgender: "\f224"; +$fa-var-transgender-alt: "\f225"; +$fa-var-trash: "\f1f8"; +$fa-var-trash-o: "\f014"; +$fa-var-tree: "\f1bb"; +$fa-var-trello: "\f181"; +$fa-var-tripadvisor: "\f262"; +$fa-var-trophy: "\f091"; +$fa-var-truck: "\f0d1"; +$fa-var-try: "\f195"; +$fa-var-tty: "\f1e4"; +$fa-var-tumblr: "\f173"; +$fa-var-tumblr-square: "\f174"; +$fa-var-turkish-lira: "\f195"; +$fa-var-tv: "\f26c"; +$fa-var-twitch: "\f1e8"; +$fa-var-twitter: "\f099"; +$fa-var-twitter-square: "\f081"; +$fa-var-umbrella: "\f0e9"; +$fa-var-underline: "\f0cd"; +$fa-var-undo: "\f0e2"; +$fa-var-universal-access: "\f29a"; +$fa-var-university: "\f19c"; +$fa-var-unlink: "\f127"; +$fa-var-unlock: "\f09c"; +$fa-var-unlock-alt: "\f13e"; +$fa-var-unsorted: "\f0dc"; +$fa-var-upload: "\f093"; +$fa-var-usb: "\f287"; +$fa-var-usd: "\f155"; +$fa-var-user: "\f007"; +$fa-var-user-circle: "\f2bd"; +$fa-var-user-circle-o: "\f2be"; +$fa-var-user-md: "\f0f0"; +$fa-var-user-o: "\f2c0"; +$fa-var-user-plus: "\f234"; +$fa-var-user-secret: "\f21b"; +$fa-var-user-times: "\f235"; +$fa-var-users: "\f0c0"; +$fa-var-vcard: "\f2bb"; +$fa-var-vcard-o: "\f2bc"; +$fa-var-venus: "\f221"; +$fa-var-venus-double: "\f226"; +$fa-var-venus-mars: "\f228"; +$fa-var-viacoin: "\f237"; +$fa-var-viadeo: "\f2a9"; +$fa-var-viadeo-square: "\f2aa"; +$fa-var-video-camera: "\f03d"; +$fa-var-vimeo: "\f27d"; +$fa-var-vimeo-square: "\f194"; +$fa-var-vine: "\f1ca"; +$fa-var-vk: "\f189"; +$fa-var-volume-control-phone: "\f2a0"; +$fa-var-volume-down: "\f027"; +$fa-var-volume-off: "\f026"; +$fa-var-volume-up: "\f028"; +$fa-var-warning: "\f071"; +$fa-var-wechat: "\f1d7"; +$fa-var-weibo: "\f18a"; +$fa-var-weixin: "\f1d7"; +$fa-var-whatsapp: "\f232"; +$fa-var-wheelchair: "\f193"; +$fa-var-wheelchair-alt: "\f29b"; +$fa-var-wifi: "\f1eb"; +$fa-var-wikipedia-w: "\f266"; +$fa-var-window-close: "\f2d3"; +$fa-var-window-close-o: "\f2d4"; +$fa-var-window-maximize: "\f2d0"; +$fa-var-window-minimize: "\f2d1"; +$fa-var-window-restore: "\f2d2"; +$fa-var-windows: "\f17a"; +$fa-var-won: "\f159"; +$fa-var-wordpress: "\f19a"; +$fa-var-wpbeginner: "\f297"; +$fa-var-wpexplorer: "\f2de"; +$fa-var-wpforms: "\f298"; +$fa-var-wrench: "\f0ad"; +$fa-var-xing: "\f168"; +$fa-var-xing-square: "\f169"; +$fa-var-y-combinator: "\f23b"; +$fa-var-y-combinator-square: "\f1d4"; +$fa-var-yahoo: "\f19e"; +$fa-var-yc: "\f23b"; +$fa-var-yc-square: "\f1d4"; +$fa-var-yelp: "\f1e9"; +$fa-var-yen: "\f157"; +$fa-var-yoast: "\f2b1"; +$fa-var-youtube: "\f167"; +$fa-var-youtube-play: "\f16a"; +$fa-var-youtube-square: "\f166"; + diff --git a/js/font-awesome/scss/font-awesome.scss b/js/font-awesome/scss/font-awesome.scss new file mode 100644 index 000000000..f1c83aaa5 --- /dev/null +++ b/js/font-awesome/scss/font-awesome.scss @@ -0,0 +1,18 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ + +@import "variables"; +@import "mixins"; +@import "path"; +@import "core"; +@import "larger"; +@import "fixed-width"; +@import "list"; +@import "bordered-pulled"; +@import "animated"; +@import "rotated-flipped"; +@import "stacked"; +@import "icons"; +@import "screen-reader"; diff --git a/js/jquery.anchorScroll.js b/js/jquery.anchorScroll.js new file mode 100644 index 000000000..76dea6175 --- /dev/null +++ b/js/jquery.anchorScroll.js @@ -0,0 +1,65 @@ +/*! + * jQuery.anchorScroll jQuery Plugin v1.0 + * + * Author: Virgiliu Diaconu + * http://www.virgiliu.com + * Licensed under the MIT license. + */ +; +(function($, window, document, undefined) { + 'use strict'; + $.anchorScroll = function(el, options) { + var base = this; + + // Access to jQuery and DOM versions of element + base.$el = $(el); + base.el = el; + + base.init = function() { + base.options = $.extend({}, $.anchorScroll.defaultOptions, options); + }; + + // On click + base.$el.click(function(e) { + e.preventDefault(); + if ($(e.target).closest('a').length && $(base.el.hash).length) { + var targetPos = $(base.el.hash).offset().top - base.options.offsetTop, + classTo = (base.$el.data("classTo") === "this") ? base.el : base.$el.data("classTo"), + onScroll = base.$el.data("onScroll"), + scrollEnd = base.$el.data("scrollEnd"); + // Callback scroll start + if (typeof base.options.scrollStart === 'function') { + base.options.scrollStart.call(el); + } + // Add class to element on scroll + $(classTo).addClass(onScroll).removeClass(scrollEnd); + // Smooth scroll + $('html,body').animate({ + scrollTop: targetPos + }, base.options.scrollSpeed).promise().done(function() { + // On animation complete + $(classTo).addClass(scrollEnd).removeClass(onScroll); + // Callback on scroll end + if (typeof base.options.scrollEnd === 'function') { + base.options.scrollEnd.call(el); + } + }); + } + }); + + // Run initializer + base.init(); + }; + + $.anchorScroll.defaultOptions = { + scrollSpeed: 800, + offsetTop: 0 + }; + + $.fn.anchorScroll = function(options) { + return this.each(function() { + (new $.anchorScroll(this, options)); + }); + }; + +})(jQuery, window, document); \ No newline at end of file diff --git a/js/jquery.bxslider.js b/js/jquery.bxslider.js new file mode 100644 index 000000000..02eb51191 --- /dev/null +++ b/js/jquery.bxslider.js @@ -0,0 +1,1374 @@ +/** + * BxSlider v4.1.1 - Fully loaded, responsive content slider + * http://bxslider.com + * + * Copyright 2013, Steven Wanderski - http://stevenwanderski.com - http://bxcreative.com + * Written while drinking Belgian ales and listening to jazz + * + * Released under the MIT license - http://opensource.org/licenses/MIT + */ + +;(function($){ + + var plugin = {}; + + var defaults = { + + // GENERAL + mode: 'horizontal', + slideSelector: '', + infiniteLoop: true, + hideControlOnEnd: false, + speed: 500, + easing: null, + slideMargin: 0, + startSlide: 0, + randomStart: false, + captions: false, + ticker: false, + tickerHover: false, + adaptiveHeight: false, + adaptiveHeightSpeed: 50, + video: false, + useCSS: true, + preloadImages: 'visible', + responsive: true, + + // TOUCH + touchEnabled: true, + swipeThreshold: 50, + oneToOneTouch: true, + preventDefaultSwipeX: true, + preventDefaultSwipeY: false, + + // PAGER + pager: true, + pagerType: 'full', + pagerShortSeparator: ' / ', + pagerSelector: null, + buildPager: null, + pagerCustom: null, + + // CONTROLS + controls: true, + nextText: 'Next', + prevText: 'Prev', + nextSelector: null, + prevSelector: null, + autoControls: false, + startText: 'Start', + stopText: 'Stop', + autoControlsCombine: false, + autoControlsSelector: null, + + // AUTO + auto: false, + pause: 4000, + autoStart: true, + autoDirection: 'next', + autoHover: false, + autoDelay: 0, + controlladd: false, + + // CAROUSEL + minSlides: 1, + maxSlides: 1, + moveSlides: 0, + slideWidth: 0, + + SUPPORTS_TOUCH : 'ontouchstart' in window, + + // CALLBACKS + onSliderLoad: function() {}, + onSlideBefore: function() {}, + onSlideAfter: function() {}, + onSlideNext: function() {}, + onSlidePrev: function() {}, + + //ADD + interval_arr: [] + } + + $.fn.bxSlider = function(options){ + + if(this.length == 0) return this; + + // support mutltiple elements + if(this.length > 1){ + this.each(function(){$(this).bxSlider(options)}); + return this; + } + + // create a namespace to be used throughout the plugin + var slider = {}; + // set a reference to our slider element + var el = this; + plugin.el = this; + + /** + * Makes slideshow responsive + */ + // first get the original window dimens (thanks alot IE) + var windowWidth = $(window).width(); + var windowHeight = $(window).height(); + + // Return if slider is already initialized + if ($(el).data('bxSlider')) { return; } + + /** + * =================================================================================== + * = PRIVATE FUNCTIONS + * =================================================================================== + */ + + /** + * Initializes namespace settings to be used throughout plugin + */ + var init = function(){ + // Return if slider is already initialized + if ($(el).data('bxSlider')) { return; } + // merge user-supplied options with the defaults + slider.settings = $.extend({}, defaults, options); + // parse slideWidth setting + slider.settings.slideWidth = parseInt(slider.settings.slideWidth); + // store the original children + slider.children = el.children(slider.settings.slideSelector); + // check if actual number of slides is less than minSlides / maxSlides + if(slider.children.length < slider.settings.minSlides) slider.settings.minSlides = slider.children.length; + if(slider.children.length < slider.settings.maxSlides) slider.settings.maxSlides = slider.children.length; + // if random start, set the startSlide setting to random number + if(slider.settings.randomStart) slider.settings.startSlide = Math.floor(Math.random() * slider.children.length); + // store active slide information + slider.active = { index: slider.settings.startSlide } + // store if the slider is in carousel mode (displaying / moving multiple slides) + slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1; + // if carousel, force preloadImages = 'all' + if(slider.carousel) slider.settings.preloadImages = 'all'; + // calculate the min / max width thresholds based on min / max number of slides + // used to setup and update carousel slides dimensions + slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin); + slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); + // store the current state of the slider (if currently animating, working is true) + slider.working = false; + // initialize the controls object + slider.controls = {}; + // initialize an auto interval + slider.interval = null; + // determine which property to use for transitions + slider.animProp = slider.settings.mode == 'vertical' ? 'top' : 'left'; + // determine if hardware acceleration can be used + slider.usingCSS = slider.settings.useCSS && slider.settings.mode != 'fade' && (function(){ + // create our test div element + var div = document.createElement('div'); + // css transition properties + var props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; + // test for each property + for(var i in props){ + if(div.style[props[i]] !== undefined){ + slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase(); + slider.animProp = '-' + slider.cssPrefix + '-transform'; + return true; + } + } + return false; + }()); + var useTouchEvents = slider.settings.SUPPORTS_TOUCH; + slider.START_EV = useTouchEvents ? 'touchstart' : 'mousedown', + slider.MOVE_EV = useTouchEvents ? 'touchmove' : 'mousemove', + slider.END_EV = useTouchEvents ? 'touchend' : 'mouseup', + slider.LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here + slider.CANCEL_EV = 'touchcancel'; + + // if vertical mode always make maxSlides and minSlides equal + if(slider.settings.mode == 'vertical') slider.settings.maxSlides = slider.settings.minSlides; + // save original style data + el.data("origStyle", el.attr("style")); + el.children(slider.settings.slideSelector).each(function() { + $(this).data("origStyle", $(this).attr("style")); + }); + el.pause = slider.settings.pause; + // perform all DOM / CSS modifications + setup(); + } + + /** + * Performs all DOM and CSS modifications + */ + var setup = function(){ + // wrap el in a wrapper + el.wrap('
    '); + // store a namspace reference to .bx-viewport + slider.viewport = el.parent(); + // add a loading div to display while images are loading + slider.loader = $('
    '); + slider.viewport.prepend(slider.loader); + // set el to a massive width, to hold any needed slides + // also strip any margin and padding from el + el.css({ + width: slider.settings.mode == 'horizontal' ? (slider.children.length * 100 + 215) + '%' : 'auto', + position: 'relative' + }); + el.state = slider.settings.auto ? 'start' : 'stop'; + // if using CSS, add the easing property + if(slider.usingCSS && slider.settings.easing){ + el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing); + // if not using CSS and no easing value was supplied, use the default JS animation easing (swing) + }else if(!slider.settings.easing){ + slider.settings.easing = 'swing'; + } + var slidesShowing = getNumberSlidesShowing(); + // make modifications to the viewport (.bx-viewport) + slider.viewport.css({ + width: '100%', + overflow: 'hidden', + position: 'relative' + }); + slider.viewport.parent().css({ + maxWidth: getViewportMaxWidth() + }); + // make modification to the wrapper (.bx-wrapper) + if(!slider.settings.pager) { + slider.viewport.parent().css({ + margin: '0 auto 0px' + }); + } + // apply css to all slider children + slider.children.css({ + 'float': slider.settings.mode == 'horizontal' ? 'left' : 'none', + listStyle: 'none', + position: 'relative' + }); + // apply the calculated width after the float is applied to prevent scrollbar interference + slider.children.css('width', getSlideWidth()); + // if slideMargin is supplied, add the css + if(slider.settings.mode == 'horizontal' && slider.settings.slideMargin > 0) slider.children.css('marginRight', slider.settings.slideMargin); + if(slider.settings.mode == 'vertical' && slider.settings.slideMargin > 0) slider.children.css('marginBottom', slider.settings.slideMargin); + // if "fade" mode, add positioning and z-index CSS + if(slider.settings.mode == 'fade'){ + slider.children.css({ + position: 'absolute', + zIndex: 0, + display: 'none' + }); + // prepare the z-index on the showing element + slider.children.eq(slider.settings.startSlide).css({zIndex: 50, display: 'block'}); + } + // create an element to contain all slider controls (pager, start / stop, etc) + slider.controls.el = $('
    '); + // if captions are requested, add them + if(slider.settings.captions) appendCaptions(); + // check if startSlide is last slide + slider.active.last = slider.settings.startSlide == getPagerQty() - 1; + // if video is true, set up the fitVids plugin + if(slider.settings.video) el.fitVids(); + // set the default preload selector (visible) + var preloadSelector = slider.children.eq(slider.settings.startSlide); + if (slider.settings.preloadImages == "all") preloadSelector = slider.children; + // only check for control addition if not in "ticker" mode + if(!slider.settings.ticker){ + // if pager is requested, add it + if(slider.settings.pager) appendPager(); + // if controls are requested, add them + if(slider.settings.controls) appendControls(); + // if auto is true, and auto controls are requested, add them + if(slider.settings.auto && slider.settings.autoControls) appendControlsAuto(); + // if any control option is requested, add the controls wrapper + if(slider.settings.controls || slider.settings.autoControls || slider.settings.pager) slider.viewport.after(slider.controls.el); + // if ticker mode, do not allow a pager + }else{ + slider.settings.pager = false; + } + // preload all images, then perform final DOM / CSS modifications that depend on images being loaded + loadElements(preloadSelector, start); + } + + var loadElements = function(selector, callback){ + var total = selector.find('img, iframe').length; + if (total == 0){ + callback(); + return; + } + var count = 0; + selector.find('img, iframe').each(function(){ + $(this).one('load', function() { + if(++count == total) callback(); + }).each(function() { + if(this.complete) $(this).load(); + }); + }); + } + + /** + * Start the slider + */ + var start = function(){ + // if infinite loop, prepare additional slides + if(slider.settings.infiniteLoop && slider.settings.mode != 'fade' && !slider.settings.ticker){ + var slice = slider.settings.mode == 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides; + var sliceAppend = slider.children.slice(0, slice).clone().addClass('bx-clone'); + var slicePrepend = slider.children.slice(-slice).clone().addClass('bx-clone'); + el.append(sliceAppend).prepend(slicePrepend); + } + // remove the loading DOM element + slider.loader.remove(); + // set the left / top position of "el" + setSlidePosition(); + // if "vertical" mode, always use adaptiveHeight to prevent odd behavior + if (slider.settings.mode == 'vertical') slider.settings.adaptiveHeight = true; + // set the viewport height + slider.viewport.height(getViewportHeight()); + // make sure everything is positioned just right (same as a window resize) + el.redrawSlider(); + // onSliderLoad callback + slider.settings.onSliderLoad(slider.active.index); + // slider has been fully initialized + slider.initialized = true; + // bind the resize call to the window + if (slider.settings.responsive) $(window).bind('resize', resizeWindow); + // if auto is true, start the show + if (slider.settings.auto && slider.settings.autoStart) initAuto(); + // if ticker is true, start the ticker + if (slider.settings.ticker) initTicker(); + // if pager is requested, make the appropriate pager link active + if (slider.settings.pager) updatePagerActive(slider.settings.startSlide); + // check for any updates to the controls (like hideControlOnEnd updates) + if (slider.settings.controls) updateDirectionControls(); + // if touchEnabled is true, setup the touch events + if (slider.settings.touchEnabled && !slider.settings.ticker) initTouch(); + } + + /** + * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value + */ + var getViewportHeight = function(){ + var height = 0; + // first determine which children (slides) should be used in our height calculation + var children = $(); + // if mode is not "vertical" and adaptiveHeight is false, include all children + if(slider.settings.mode != 'vertical' && !slider.settings.adaptiveHeight){ + children = slider.children; + }else{ + // if not carousel, return the single active child + if(!slider.carousel){ + children = slider.children.eq(slider.active.index); + // if carousel, return a slice of children + }else{ + // get the individual slide index + var currentIndex = slider.settings.moveSlides == 1 ? slider.active.index : slider.active.index * getMoveBy(); + // add the current slide to the children + children = slider.children.eq(currentIndex); + // cycle through the remaining "showing" slides + for (i = 1; i <= slider.settings.maxSlides - 1; i++){ + // if looped back to the start + if(currentIndex + i >= slider.children.length){ + children = children.add(slider.children.eq(i - 1)); + }else{ + children = children.add(slider.children.eq(currentIndex + i)); + } + } + } + } + // if "vertical" mode, calculate the sum of the heights of the children + if(slider.settings.mode == 'vertical'){ + children.each(function(index) { + height += $(this).outerHeight(); + }); + // add user-supplied margins + if(slider.settings.slideMargin > 0){ + height += slider.settings.slideMargin * (slider.settings.minSlides - 1); + } + // if not "vertical" mode, calculate the max height of the children + }else{ + height = Math.max.apply(Math, children.map(function(){ + return $(this).outerHeight(false); + }).get()); + } + return height; + } + + /** + * Returns the calculated width to be used for the outer wrapper / viewport + */ + var getViewportMaxWidth = function(){ + var width = '100%'; + if(slider.settings.slideWidth > 0){ + if(slider.settings.mode == 'horizontal'){ + width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); + }else{ + width = slider.settings.slideWidth; + } + } + return width; + } + + /** + * Returns the calculated width to be applied to each slide + */ + var getSlideWidth = function(){ + // start with any user-supplied slide width + var newElWidth = slider.settings.slideWidth; + // get the current viewport width + var wrapWidth = slider.viewport.width(); + // if slide width was not supplied, or is larger than the viewport use the viewport width + if(slider.settings.slideWidth == 0 || + (slider.settings.slideWidth > wrapWidth && !slider.carousel) || + slider.settings.mode == 'vertical'){ + newElWidth = wrapWidth; + // if carousel, use the thresholds to determine the width + }else if(slider.settings.maxSlides > 1 && slider.settings.mode == 'horizontal'){ + if(wrapWidth > slider.maxThreshold){ + // newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.maxSlides - 1))) / slider.settings.maxSlides; + }else if(wrapWidth < slider.minThreshold){ + newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides; + } + } + return newElWidth; + } + + /** + * Returns the number of slides currently visible in the viewport (includes partially visible slides) + */ + var getNumberSlidesShowing = function(){ + var slidesShowing = 1; + if(slider.settings.mode == 'horizontal' && slider.settings.slideWidth > 0){ + // if viewport is smaller than minThreshold, return minSlides + if(slider.viewport.width() < slider.minThreshold){ + slidesShowing = slider.settings.minSlides; + // if viewport is larger than minThreshold, return maxSlides + }else if(slider.viewport.width() > slider.maxThreshold){ + slidesShowing = slider.settings.maxSlides; + // if viewport is between min / max thresholds, divide viewport width by first child width + }else{ + var childWidth = slider.children.first().width(); + slidesShowing = Math.floor(slider.viewport.width() / childWidth); + } + // if "vertical" mode, slides showing will always be minSlides + }else if(slider.settings.mode == 'vertical'){ + slidesShowing = slider.settings.minSlides; + } + return slidesShowing; + } + + /** + * Returns the number of pages (one full viewport of slides is one "page") + */ + var getPagerQty = function(){ + var pagerQty = 0; + // if moveSlides is specified by the user + if(slider.settings.moveSlides > 0){ + if(slider.settings.infiniteLoop){ + pagerQty = slider.children.length / getMoveBy(); + }else{ + // use a while loop to determine pages + var breakPoint = 0; + var counter = 0 + // when breakpoint goes above children length, counter is the number of pages + while (breakPoint < slider.children.length){ + ++pagerQty; + breakPoint = counter + getNumberSlidesShowing(); + counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing(); + } + } + // if moveSlides is 0 (auto) divide children length by sides showing, then round up + }else{ + pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing()); + } + return pagerQty; + } + + /** + * Returns the number of indivual slides by which to shift the slider + */ + var getMoveBy = function(){ + // if moveSlides was set by the user and moveSlides is less than number of slides showing + if(slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()){ + return slider.settings.moveSlides; + } + // if moveSlides is 0 (auto) + return getNumberSlidesShowing(); + } + + /** + * Sets the slider's (el) left or top position + */ + var setSlidePosition = function(){ + // if last slide, not infinite loop, and number of children is larger than specified maxSlides + if(slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop){ + if (slider.settings.mode == 'horizontal'){ + // get the last child's position + var lastChild = slider.children.last(); + var position = lastChild.position(); + // set the left position + setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.width())), 'reset', 0); + }else if(slider.settings.mode == 'vertical'){ + // get the last showing index's position + var lastShowingIndex = slider.children.length - slider.settings.minSlides; + var position = slider.children.eq(lastShowingIndex).position(); + // set the top position + setPositionProperty(-position.top, 'reset', 0); + } + // if not last slide + }else{ + // get the position of the first showing slide + var position = slider.children.eq(slider.active.index * getMoveBy()).position(); + // check for last slide + if (slider.active.index == getPagerQty() - 1) slider.active.last = true; + // set the repective position + if (position != undefined){ + if (slider.settings.mode == 'horizontal') setPositionProperty(-position.left, 'reset', 0); + else if (slider.settings.mode == 'vertical') setPositionProperty(-position.top, 'reset', 0); + } + } + } + + /** + * Sets the el's animating property position (which in turn will sometimes animate el). + * If using CSS, sets the transform property. If not using CSS, sets the top / left property. + * + * @param value (int) + * - the animating property's value + * + * @param type (string) 'slider', 'reset', 'ticker' + * - the type of instance for which the function is being + * + * @param duration (int) + * - the amount of time (in ms) the transition should occupy + * + * @param params (array) optional + * - an optional parameter containing any variables that need to be passed in + */ + var setPositionProperty = function(value, type, duration, params){ + // use CSS transform + if(slider.usingCSS){ + // determine the translate3d value + var propValue = slider.settings.mode == 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)'; + // add the CSS transition-duration + el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's'); + if(type == 'slide'){ + // set the property value + el.css(slider.animProp, propValue); + // bind a callback method - executes when CSS transition completes + el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){ + // unbind the callback + el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); + updateAfterSlideTransition(); + }); + }else if(type == 'reset'){ + el.css(slider.animProp, propValue); + }else if(type == 'ticker'){ + // make the transition use 'linear' + el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear'); + el.css(slider.animProp, propValue); + // bind a callback method - executes when CSS transition completes + el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){ + // unbind the callback + el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); + // reset the position + setPositionProperty(params['resetValue'], 'reset', 0); + // start the loop again + tickerLoop(); + }); + } + // use JS animate + }else{ + var animateObj = {}; + animateObj[slider.animProp] = value; + if(type == 'slide'){ + el.animate(animateObj, duration, slider.settings.easing, function(){ + updateAfterSlideTransition(); + }); + }else if(type == 'reset'){ + el.css(slider.animProp, value) + }else if(type == 'ticker'){ + el.animate(animateObj, speed, 'linear', function(){ + setPositionProperty(params['resetValue'], 'reset', 0); + // run the recursive loop after animation + tickerLoop(); + }); + } + } + } + + /** + * Populates the pager with proper amount of pages + */ + var populatePager = function(){ + var pagerHtml = ''; + var pagerQty = getPagerQty(); + // loop through each pager item + for(var i=0; i < pagerQty; i++){ + var linkContent = ''; + // if a buildPager function is supplied, use it to get pager link value, else use index + 1 + if(slider.settings.buildPager && $.isFunction(slider.settings.buildPager)){ + linkContent = slider.settings.buildPager(i); + slider.pagerEl.addClass('bx-custom-pager'); + }else{ + linkContent = i + 1; + slider.pagerEl.addClass('bx-default-pager'); + } + // var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1; + // add the markup to the string + pagerHtml += ''; + }; + // populate the pager element with pager links + slider.pagerEl.html(pagerHtml); + } + + /** + * Appends the pager to the controls element + */ + var appendPager = function(){ + if(!slider.settings.pagerCustom){ + // create the pager DOM element + slider.pagerEl = $('
    '); + // if a pager selector was supplied, populate it with the pager + if(slider.settings.pagerSelector){ + $(slider.settings.pagerSelector).html(slider.pagerEl); + // if no pager selector was supplied, add it after the wrapper + }else{ + slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl); + } + // populate the pager + populatePager(); + }else{ + slider.pagerEl = $(slider.settings.pagerCustom); + } + // assign the pager click binding + slider.pagerEl.on('click', 'a', clickPagerBind); + } + + /** + * Appends prev / next controls to the controls element + */ + var appendControls = function(){ + slider.controls.next = $('' + slider.settings.nextText + ''); + slider.controls.prev = $('' + slider.settings.prevText + ''); + // bind click actions to the controls + slider.controls.next.bind('click', clickNextBind); + slider.controls.prev.bind('click', clickPrevBind); + // if nextSlector was supplied, populate it + if(slider.settings.nextSelector){ + $(slider.settings.nextSelector).append(slider.controls.next); + } + // if prevSlector was supplied, populate it + if(slider.settings.prevSelector){ + $(slider.settings.prevSelector).append(slider.controls.prev); + } + // if no custom selectors were supplied + if(!slider.settings.nextSelector && !slider.settings.prevSelector){ + // add the controls to the DOM + slider.controls.directionEl = $('
    '); + // add the control elements to the directionEl + slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next); + // slider.viewport.append(slider.controls.directionEl); + slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl); + } + } + + /** + * Appends start / stop auto controls to the controls element + */ + var appendControlsAuto = function(){ + slider.controls.start = $(''); + slider.controls.stop = $(''); + // add the controls to the DOM + slider.controls.autoEl = $('
    '); + // bind click actions to the controls + slider.controls.autoEl.delegate('.bx-start', 'click', clickStartBind); + slider.controls.autoEl.delegate('.bx-stop', 'click', clickStopBind); + // if autoControlsCombine, insert only the "start" control + if(slider.settings.autoControlsCombine){ + slider.controls.autoEl.append(slider.controls.start); + // if autoControlsCombine is false, insert both controls + }else{ + slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop); + } + // if auto controls selector was supplied, populate it with the controls + if(slider.settings.autoControlsSelector){ + $(slider.settings.autoControlsSelector).html(slider.controls.autoEl); + // if auto controls selector was not supplied, add it after the wrapper + }else{ + slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl); + } + + // update the auto controls + updateAutoControls(slider.settings.autoStart ? 'stop' : 'start'); + } + + /** + * Appends image captions to the DOM + */ + var appendCaptions = function(){ + // cycle through each child + slider.children.each(function(index){ + // get the image title attribute + var title = $(this).find('img:first').attr('title'); + // append the caption + if (title != undefined && ('' + title).length) { + $(this).append('
    ' + title + '
    '); + } + }); + } + + /** + * Click next binding + * + * @param e (event) + * - DOM event object + */ + var clickNextBind = function(e){ + // if auto show is running, stop it + if (slider.settings.auto) el.stopAuto(); + el.goToNextSlide(); + e.preventDefault(); + } + + /** + * Click prev binding + * + * @param e (event) + * - DOM event object + */ + var clickPrevBind = function(e){ + // if auto show is running, stop it + if (slider.settings.auto) el.stopAuto(); + el.goToPrevSlide(); + e.preventDefault(); + } + + /** + * Click start binding + * + * @param e (event) + * - DOM event object + */ + var clickStartBind = function(e){ + el.startAuto(); + e.preventDefault(); + } + + /** + * Click stop binding + * + * @param e (event) + * - DOM event object + */ + var clickStopBind = function(e){ + el.stopAuto(); + e.preventDefault(); + } + + /** + * Click pager binding + * + * @param e (event) + * - DOM event object + */ + var clickPagerBind = function(e){ + // if auto show is running, stop it + if (slider.settings.auto) el.stopAuto(); + var pagerLink = $(e.currentTarget); + if(pagerLink.attr('data-slide-index') !== undefined){ + var pagerIndex = parseInt(pagerLink.attr('data-slide-index')); + // if clicked pager link is not active, continue with the goToSlide call + if(pagerIndex != slider.active.index) el.goToSlide(pagerIndex); + e.preventDefault(); + } + } + + /** + * Updates the pager links with an active class + * + * @param slideIndex (int) + * - index of slide to make active + */ + var updatePagerActive = function(slideIndex){ + // if "short" pager type + var len = slider.children.length; // nb of children + if(slider.settings.pagerType == 'short'){ + if(slider.settings.maxSlides > 1) { + len = Math.ceil(slider.children.length/slider.settings.maxSlides); + } + slider.pagerEl.html( (slideIndex + 1) + slider.settings.pagerShortSeparator + len); + return; + } + // remove all pager active classes + slider.pagerEl.find('a').removeClass('active'); + // apply the active class for all pagers + slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); }); + } + + /** + * Performs needed actions after a slide transition + */ + var updateAfterSlideTransition = function(){ + // if infinte loop is true + if(slider.settings.infiniteLoop){ + var position = ''; + // first slide + if(slider.active.index == 0){ + // set the new position + position = slider.children.eq(0).position(); + // carousel, last slide + }else if(slider.active.index == getPagerQty() - 1 && slider.carousel){ + position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position(); + // last slide + }else if(slider.active.index == slider.children.length - 1){ + position = slider.children.eq(slider.children.length - 1).position(); + } + if (slider.settings.mode == 'horizontal') { setPositionProperty(-position.left, 'reset', 0);; } + else if (slider.settings.mode == 'vertical') { setPositionProperty(-position.top, 'reset', 0);; } + } + // declare that the transition is complete + slider.working = false; + // onSlideAfter callback + slider.settings.onSlideAfter(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); + } + + /** + * Updates the auto controls state (either active, or combined switch) + * + * @param state (string) "start", "stop" + * - the new state of the auto show + */ + var updateAutoControls = function(state){ + + el.trigger("updateautocontrols", state); + + // if autoControlsCombine is true, replace the current control with the new state + if(slider.settings.autoControlsCombine){ + slider.controls.autoEl.html(slider.controls[state]); + // if autoControlsCombine is false, apply the "active" class to the appropriate control + }else{ + slider.controls.autoEl.find('a').removeClass('active'); + slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active'); + } + } + + /** + * Updates the direction controls (checks if either should be hidden) + */ + var updateDirectionControls = function(){ + if(getPagerQty() == 1){ + slider.controls.prev.addClass('disabled'); + slider.controls.next.addClass('disabled'); + }else if(!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd){ + // if first slide + if (slider.active.index == 0){ + slider.controls.prev.addClass('disabled'); + slider.controls.next.removeClass('disabled'); + // if last slide + }else if(slider.active.index == getPagerQty() - 1){ + slider.controls.next.addClass('disabled'); + slider.controls.prev.removeClass('disabled'); + // if any slide in the middle + }else{ + slider.controls.prev.removeClass('disabled'); + slider.controls.next.removeClass('disabled'); + } + } + } + + /** + * Initialzes the auto process + */ + var initAuto = function(){ + // if autoDelay was supplied, launch the auto show using a setTimeout() call + if(slider.settings.autoDelay > 0){ + var timeout = setTimeout(el.startAuto, slider.settings.autoDelay); + // if autoDelay was not supplied, start the auto show normally + }else{ + el.startAuto(); + } + // if autoHover is requested + if(slider.settings.autoHover){ + // on el hover + el.hover(function(){ + // if the auto show is currently playing (has an active interval) + if(slider.interval){ + // stop the auto show and pass true agument which will prevent control update + el.stopAuto(true); + // create a new autoPaused value which will be used by the relative "mouseout" event + slider.autoPaused = true; + } + }, function(){ + // if the autoPaused value was created be the prior "mouseover" event + if(slider.autoPaused){ + // start the auto show and pass true agument which will prevent control update + el.startAuto(true); + // reset the autoPaused value + slider.autoPaused = null; + } + }); + } + } + + /** + * Initialzes the ticker process + */ + var initTicker = function(){ + var startPosition = 0; + // if autoDirection is "next", append a clone of the entire slider + if(slider.settings.autoDirection == 'next'){ + el.append(slider.children.clone().addClass('bx-clone')); + // if autoDirection is "prev", prepend a clone of the entire slider, and set the left position + }else{ + el.prepend(slider.children.clone().addClass('bx-clone')); + var position = slider.children.first().position(); + startPosition = slider.settings.mode == 'horizontal' ? -position.left : -position.top; + } + setPositionProperty(startPosition, 'reset', 0); + // do not allow controls in ticker mode + slider.settings.pager = false; + slider.settings.controls = false; + slider.settings.autoControls = false; + // if autoHover is requested + if(slider.settings.tickerHover && !slider.usingCSS){ + // on el hover + slider.viewport.hover(function(){ + el.stop(); + }, function(){ + // calculate the total width of children (used to calculate the speed ratio) + var totalDimens = 0; + slider.children.each(function(index){ + totalDimens += slider.settings.mode == 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true); + }); + // calculate the speed ratio (used to determine the new speed to finish the paused animation) + var ratio = slider.settings.speed / totalDimens; + // determine which property to use + var property = slider.settings.mode == 'horizontal' ? 'left' : 'top'; + // calculate the new speed + var newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property))))); + tickerLoop(newSpeed); + }); + } + // start the ticker loop + tickerLoop(); + } + + /** + * Runs a continuous loop, news ticker-style + */ + var tickerLoop = function(resumeSpeed){ + speed = resumeSpeed ? resumeSpeed : slider.settings.speed; + var position = {left: 0, top: 0}; + var reset = {left: 0, top: 0}; + // if "next" animate left position to last child, then reset left to 0 + if(slider.settings.autoDirection == 'next'){ + position = el.find('.bx-clone').first().position(); + // if "prev" animate left position to 0, then reset left to first non-clone child + }else{ + reset = slider.children.first().position(); + } + var animateProperty = slider.settings.mode == 'horizontal' ? -position.left : -position.top; + var resetValue = slider.settings.mode == 'horizontal' ? -reset.left : -reset.top; + var params = {resetValue: resetValue}; + setPositionProperty(animateProperty, 'ticker', speed, params); + } + + /** + * Initializes touch events + */ + var initTouch = function(){ + // initialize object to contain all touch values + slider.touch = { + start: {x: 0, y: 0}, + end: {x: 0, y: 0} + } + slider.viewport.bind(slider.START_EV, onTouchStart); + slider.children.bind('click', onClick_check); + } + + var isScrolling; + /** + * Event handler for "touchstart" + * + * @param e (event) + * - DOM event object + */ + var onTouchStart = function(e){ + // used for testing first move event + isScrolling = undefined; + if(slider.working){ + e.preventDefault(); + }else{ + // record the original position when touch starts + slider.touch.originalPos = el.position(); + var orig = e.originalEvent; + var evt = slider.settings.SUPPORTS_TOUCH ? orig.changedTouches[0] : e; + // record the starting touch x, y coordinates + slider.touch.start.x = evt.pageX; + slider.touch.start.y = evt.pageY; + // bind a "touchmove" event to the viewport + slider.viewport.bind(slider.MOVE_EV, onTouchMove); + // bind a "touchend" event to the viewport + slider.viewport.bind(slider.END_EV, onTouchEnd); + } + } + + var onClick_check = function(e){ + if(slider.working){ + e.preventDefault(); + } + } + /** + * Event handler for "touchmove" + * + * @param e (event) + * - DOM event object + */ + var onTouchMove = function(e){ + var orig = e.originalEvent; + var evt = slider.settings.SUPPORTS_TOUCH ? orig.changedTouches[0] : e; + // if scrolling on y axis, do not prevent default + var xMovement = Math.abs(evt.pageX - slider.touch.start.x); + var yMovement = Math.abs(evt.pageY - slider.touch.start.y); + + // determine if scrolling test has run - one time test + if ( typeof isScrolling == 'undefined') { + isScrolling = !!( isScrolling || xMovement < yMovement ); + } + if (!isScrolling && slider.settings.mode != 'vertical') { + // x axis swipe + if((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX){ + e.preventDefault(); + // y axis swipe + }else if((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY){ + e.preventDefault(); + } + if(slider.settings.mode != 'fade' && slider.settings.oneToOneTouch){ + var value = 0; + // if horizontal, drag along x axis + if(slider.settings.mode == 'horizontal'){ + var change = evt.pageX - slider.touch.start.x; + value = slider.touch.originalPos.left + change; + // if vertical, drag along y axis + }else{ + var change = evt.pageY - slider.touch.start.y; + value = slider.touch.originalPos.top + change; + } + setPositionProperty(value, 'reset', 0); + } + } + } + + /** + * Event handler for "touchend" + * + * @param e (event) + * - DOM event object + */ + var onTouchEnd = function(e){ + slider.viewport.unbind(slider.MOVE_EV, onTouchMove); + var orig = e.originalEvent; + var evt = slider.settings.SUPPORTS_TOUCH ? orig.changedTouches[0] : e; + var value = 0; + // record end x, y positions + slider.touch.end.x = evt.pageX; + slider.touch.end.y = evt.pageY; + // if fade mode, check if absolute x distance clears the threshold + if(slider.settings.mode == 'fade'){ + var distance = Math.abs(slider.touch.start.x - slider.touch.end.x); + if(distance >= slider.settings.swipeThreshold){ + slider.touch.start.x > slider.touch.end.x ? el.goToNextSlide() : el.goToPrevSlide(); + el.stopAuto(); + } + // not fade mode + }else{ + var distance = 0; + // calculate distance and el's animate property + if(slider.settings.mode == 'horizontal'){ + distance = slider.touch.end.x - slider.touch.start.x; + value = slider.touch.originalPos.left; + }else{ + distance = slider.touch.end.y - slider.touch.start.y; + value = slider.touch.originalPos.top; + } + // if not infinite loop and first / last slide, do not attempt a slide transition + if(!slider.settings.infiniteLoop && ((slider.active.index == 0 && distance > 0) || (slider.active.last && distance < 0))){ + setPositionProperty(value, 'reset', 200); + }else{ + // check if distance clears threshold + if(Math.abs(distance) >= slider.settings.swipeThreshold){ + distance < 0 ? el.goToNextSlide() : el.goToPrevSlide(); + el.stopAuto(); + }else{ + // el.animate(property, 200); + setPositionProperty(value, 'reset', 200); + } + } + } + slider.viewport.unbind(slider.END_EV, onTouchEnd); + } + + /** + * Window resize event callback + */ + var resizeWindow = function(e){ + // get the new window dimens (again, thank you IE) + var windowWidthNew = $(window).width(); + var windowHeightNew = $(window).height(); + // make sure that it is a true window resize + // *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements + // are resized. Can you just die already?* + if(windowWidth != windowWidthNew || windowHeight != windowHeightNew){ + // set the new window dimens + windowWidth = windowWidthNew; + windowHeight = windowHeightNew; + // update all dynamic elements + el.redrawSlider(); + } + } + + /** + * =================================================================================== + * = PUBLIC FUNCTIONS + * =================================================================================== + */ + + /** + * Performs slide transition to the specified slide + * + * @param slideIndex (int) + * - the destination slide's index (zero-based) + * + * @param direction (string) + * - INTERNAL USE ONLY - the direction of travel ("prev" / "next") + */ + el.goToSlide = function(slideIndex, direction, workignore){ + // if plugin is currently in motion, ignore request + if( slider.active.index == slideIndex ) return; + if( !workignore && slider.working ) return; + + // declare that plugin is in motion + slider.working = true; + // store the old index + slider.oldIndex = slider.active.index; + // if slideIndex is less than zero, set active index to last child (this happens during infinite loop) + if(slideIndex < 0){ + slider.active.index = getPagerQty() - 1; + // if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop) + }else if(slideIndex >= getPagerQty()){ + slider.active.index = 0; + // set active index to requested slide + }else{ + slider.active.index = slideIndex; + } + // onSlideBefore, onSlideNext, onSlidePrev callbacks + slider.settings.onSlideBefore(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); + if(direction == 'next'){ + slider.settings.onSlideNext(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); + }else if(direction == 'prev'){ + slider.settings.onSlidePrev(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); + } + // check if last slide + slider.active.last = slider.active.index >= getPagerQty() - 1; + // update the pager with active class + if(slider.settings.pager) updatePagerActive(slider.active.index); + // // check for direction control update + if(slider.settings.controls) updateDirectionControls(); + // if slider is set to mode: "fade" + if(slider.settings.mode == 'fade'){ + // if adaptiveHeight is true and next height is different from current height, animate to the new height + if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){ + slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); + } + // fade out the visible child and reset its z-index value + slider.children.filter(':visible').stop( true, true ).fadeOut(slider.settings.speed).css({zIndex: 0}); + // fade in the newly requested slide + slider.children.eq(slider.active.index).css('zIndex', 51).stop( true, true ).fadeIn(slider.settings.speed, function(){ + $(this).css('zIndex', 50); + updateAfterSlideTransition(); + }); + // slider mode is not "fade" + }else{ + // if adaptiveHeight is true and next height is different from current height, animate to the new height + if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){ + slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); + } + var moveBy = 0; + var position = {left: 0, top: 0}; + // if carousel and not infinite loop + if(!slider.settings.infiniteLoop && slider.carousel && slider.active.last){ + if(slider.settings.mode == 'horizontal'){ + // get the last child position + var lastChild = slider.children.eq(slider.children.length - 1); + position = lastChild.position(); + // calculate the position of the last slide + moveBy = slider.viewport.width() - lastChild.outerWidth(); + }else{ + // get last showing index position + var lastShowingIndex = slider.children.length - slider.settings.minSlides; + position = slider.children.eq(lastShowingIndex).position(); + } + // horizontal carousel, going previous while on first slide (infiniteLoop mode) + }else if(slider.carousel && slider.active.last && direction == 'prev'){ + // get the last child position + var eq = slider.settings.moveSlides == 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides); + var lastChild = el.children('.bx-clone').eq(eq); + position = lastChild.position(); + // if infinite loop and "Next" is clicked on the last slide + }else if(direction == 'next' && slider.active.index == 0){ + // get the last clone position + position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position(); + slider.active.last = false; + // normal non-zero requests + }else if(slideIndex >= 0){ + var requestEl = slideIndex * getMoveBy(); + position = slider.children.eq(requestEl).position(); + } + + /* If the position doesn't exist + * (e.g. if you destroy the slider on a next click), + * it doesn't throw an error. + */ + if ("undefined" !== typeof(position)) { + var value = slider.settings.mode == 'horizontal' ? -(position.left - moveBy) : -position.top; + // plugin values to be animated + setPositionProperty(value, 'slide', slider.settings.speed); + } + } + } + + /** + * Transitions to the next slide in the show + */ + el.goToNextSlide = function(){ + // if infiniteLoop is false and last page is showing, disregard call + if (!slider.settings.infiniteLoop && slider.active.last) return; + var pagerIndex = parseInt(slider.active.index) + 1; + el.goToSlide(pagerIndex, 'next'); + } + + /** + * Transitions to the prev slide in the show + */ + el.goToPrevSlide = function(){ + // if infiniteLoop is false and last page is showing, disregard call + if (!slider.settings.infiniteLoop && slider.active.index == 0) return; + var pagerIndex = parseInt(slider.active.index) - 1; + el.goToSlide(pagerIndex, 'prev'); + } + + /** + * Starts the auto show + * + * @param preventControlUpdate (boolean) + * - if true, auto controls state will not be updated + */ + el.startAuto = function(preventControlUpdate){ + // if an interval already exists, disregard call + if(slider.interval) return; + // create an interval + slider.interval = setInterval(function(){ + slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide(); + }, el.pause); + + // if auto controls are displayed and preventControlUpdate is not true + if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop'); + } + + /** + * Stops the auto show + * + * @param preventControlUpdate (boolean) + * - if true, auto controls state will not be updated + */ + el.stopAuto = function(preventControlUpdate){ + // if no interval exists, disregard call + if(!slider.interval) return; + // clear the interval + el.clearTimer(); + slider.interval = null; + // if auto controls are displayed and preventControlUpdate is not true + if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('start'); + } + + /** + * clear + */ + el.clearTimer = function(){ + clearInterval(slider.interval); + } + + /** + * Returns current slide index (zero-based) + */ + el.getCurrentSlide = function(){ + return slider.active.index; + } + + /** + * Returns number of slides in show + */ + el.getSlideCount = function(){ + return slider.children.length; + } + + /** + * Update all dynamic slider elements + */ + el.redrawSlider = function(){ + // resize all children in ratio to new screen size + slider.children.add(el.find('.bx-clone')).outerWidth(getSlideWidth()); + // adjust the height + slider.viewport.css('height', getViewportHeight()); + // update the slide position + if(!slider.settings.ticker) setSlidePosition(); + // if active.last was true before the screen resize, we want + // to keep it last no matter what screen size we end on + if (slider.active.last) slider.active.index = getPagerQty() - 1; + // if the active index (page) no longer exists due to the resize, simply set the index as last + if (slider.active.index >= getPagerQty()) slider.active.last = true; + // if a pager is being displayed and a custom pager is not being used, update it + if(slider.settings.pager && !slider.settings.pagerCustom){ + populatePager(); + updatePagerActive(slider.active.index); + } + } + + /** + * Destroy the current instance of the slider (revert everything back to original state) + */ + el.destroySlider = function(){ + // don't do anything if slider has already been destroyed + if(!slider.initialized) return; + slider.initialized = false; + $('.bx-clone', this).remove(); + slider.children.each(function() { + $(this).data("origStyle") != undefined ? $(this).attr("style", $(this).data("origStyle")) : $(this).removeAttr('style'); + }); + $(this).data("origStyle") != undefined ? this.attr("style", $(this).data("origStyle")) : $(this).removeAttr('style'); + $(this).unwrap().unwrap(); + if(slider.controls.el) slider.controls.el.remove(); + if(slider.controls.next) slider.controls.next.remove(); + if(slider.controls.prev) slider.controls.prev.remove(); + if(slider.pagerEl) slider.pagerEl.remove(); + $('.bx-caption', this).remove(); + if(slider.controls.autoEl) slider.controls.autoEl.remove(); + el.clearTimer(); + //remove self reference in data + $(this).removeData('bxSlider'); + if(slider.settings.responsive) $(window).unbind('resize', resizeWindow); + } + + /** + * Reload the slider (revert all DOM changes, and re-initialize) + */ + el.reloadSlider = function(settings){ + if (settings != undefined) options = settings; + el.destroySlider(); + init(); + //store reference to self in order to access public functions later + $(el).data('bxSlider', this); + } + + init(); + + $(el).data('bxSlider', this); + + // returns the current jQuery object + return this; + } + +})(jQuery); \ No newline at end of file diff --git a/js/placeholders.min.js b/js/placeholders.min.js new file mode 100644 index 000000000..c8740839e --- /dev/null +++ b/js/placeholders.min.js @@ -0,0 +1,25 @@ +/* Placeholders.js v4.0.1 */ +/*! + * The MIT License + * + * Copyright (c) 2012 James Allardice + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +!function(a){"use strict";function b(){}function c(){try{return document.activeElement}catch(a){}}function d(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return!0;return!1}function e(a,b,c){return a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent?a.attachEvent("on"+b,c):void 0}function f(a,b){var c;a.createTextRange?(c=a.createTextRange(),c.move("character",b),c.select()):a.selectionStart&&(a.focus(),a.setSelectionRange(b,b))}function g(a,b){try{return a.type=b,!0}catch(c){return!1}}function h(a,b){if(a&&a.getAttribute(B))b(a);else for(var c,d=a?a.getElementsByTagName("input"):N,e=a?a.getElementsByTagName("textarea"):O,f=d?d.length:0,g=e?e.length:0,h=f+g,i=0;h>i;i++)c=f>i?d[i]:e[i-f],b(c)}function i(a){h(a,k)}function j(a){h(a,l)}function k(a,b){var c=!!b&&a.value!==b,d=a.value===a.getAttribute(B);if((c||d)&&"true"===a.getAttribute(C)){a.removeAttribute(C),a.value=a.value.replace(a.getAttribute(B),""),a.className=a.className.replace(A,"");var e=a.getAttribute(I);parseInt(e,10)>=0&&(a.setAttribute("maxLength",e),a.removeAttribute(I));var f=a.getAttribute(D);return f&&(a.type=f),!0}return!1}function l(a){var b=a.getAttribute(B);if(""===a.value&&b){a.setAttribute(C,"true"),a.value=b,a.className+=" "+z;var c=a.getAttribute(I);c||(a.setAttribute(I,a.maxLength),a.removeAttribute("maxLength"));var d=a.getAttribute(D);return d?a.type="text":"password"===a.type&&g(a,"text")&&a.setAttribute(D,"password"),!0}return!1}function m(a){return function(){P&&a.value===a.getAttribute(B)&&"true"===a.getAttribute(C)?f(a,0):k(a)}}function n(a){return function(){l(a)}}function o(a){return function(){i(a)}}function p(a){return function(b){return v=a.value,"true"===a.getAttribute(C)&&v===a.getAttribute(B)&&d(x,b.keyCode)?(b.preventDefault&&b.preventDefault(),!1):void 0}}function q(a){return function(){k(a,v),""===a.value&&(a.blur(),f(a,0))}}function r(a){return function(){a===c()&&a.value===a.getAttribute(B)&&"true"===a.getAttribute(C)&&f(a,0)}}function s(a){var b=a.form;b&&"string"==typeof b&&(b=document.getElementById(b),b.getAttribute(E)||(e(b,"submit",o(b)),b.setAttribute(E,"true"))),e(a,"focus",m(a)),e(a,"blur",n(a)),P&&(e(a,"keydown",p(a)),e(a,"keyup",q(a)),e(a,"click",r(a))),a.setAttribute(F,"true"),a.setAttribute(B,T),(P||a!==c())&&l(a)}var t=document.createElement("input"),u=void 0!==t.placeholder;if(a.Placeholders={nativeSupport:u,disable:u?b:i,enable:u?b:j},!u){var v,w=["text","search","url","tel","email","password","number","textarea"],x=[27,33,34,35,36,37,38,39,40,8,46],y="#ccc",z="placeholdersjs",A=new RegExp("(?:^|\\s)"+z+"(?!\\S)"),B="data-placeholder-value",C="data-placeholder-active",D="data-placeholder-type",E="data-placeholder-submit",F="data-placeholder-bound",G="data-placeholder-focus",H="data-placeholder-live",I="data-placeholder-maxlength",J=100,K=document.getElementsByTagName("head")[0],L=document.documentElement,M=a.Placeholders,N=document.getElementsByTagName("input"),O=document.getElementsByTagName("textarea"),P="false"===L.getAttribute(G),Q="false"!==L.getAttribute(H),R=document.createElement("style");R.type="text/css";var S=document.createTextNode("."+z+" {color:"+y+";}");R.styleSheet?R.styleSheet.cssText=S.nodeValue:R.appendChild(S),K.insertBefore(R,K.firstChild);for(var T,U,V=0,W=N.length+O.length;W>V;V++)U=Va;a++)U=a max) { + max = num; + } + } + + return max; + } + + /** + * Returns a scrollbar width + * @private + * @returns {Number} + */ + function getScrollbarWidth() { + if ($(document).height() <= $(window).height()) { + return 0; + } + + var outer = document.createElement('div'); + var inner = document.createElement('div'); + var widthNoScroll; + var widthWithScroll; + + outer.style.visibility = 'hidden'; + outer.style.width = '100px'; + document.body.appendChild(outer); + + widthNoScroll = outer.offsetWidth; + + // Force scrollbars + outer.style.overflow = 'scroll'; + + // Add inner div + inner.style.width = '100%'; + outer.appendChild(inner); + + widthWithScroll = inner.offsetWidth; + + // Remove divs + outer.parentNode.removeChild(outer); + + return widthNoScroll - widthWithScroll; + } + + /** + * Locks the screen + * @private + */ + function lockScreen() { + if (IS_IOS) { + return; + } + + var $html = $('html'); + var lockedClass = namespacify('is-locked'); + var paddingRight; + var $body; + + if (!$html.hasClass(lockedClass)) { + $body = $(document.body); + + // Zepto does not support '-=', '+=' in the `css` method + paddingRight = parseInt($body.css('padding-right'), 10) + getScrollbarWidth(); + + $body.css('padding-right', paddingRight + 'px'); + $html.addClass(lockedClass); + } + } + + /** + * Unlocks the screen + * @private + */ + function unlockScreen() { + if (IS_IOS) { + return; + } + + var $html = $('html'); + var lockedClass = namespacify('is-locked'); + var paddingRight; + var $body; + + if ($html.hasClass(lockedClass)) { + $body = $(document.body); + + // Zepto does not support '-=', '+=' in the `css` method + paddingRight = parseInt($body.css('padding-right'), 10) - getScrollbarWidth(); + + $body.css('padding-right', paddingRight + 'px'); + $html.removeClass(lockedClass); + } + } + + /** + * Sets a state for an instance + * @private + * @param {Remodal} instance + * @param {STATES} state + * @param {Boolean} isSilent If true, Remodal does not trigger events + * @param {String} Reason of a state change. + */ + function setState(instance, state, isSilent, reason) { + + var newState = namespacify('is', state); + var allStates = [namespacify('is', STATES.CLOSING), + namespacify('is', STATES.OPENING), + namespacify('is', STATES.CLOSED), + namespacify('is', STATES.OPENED)].join(' '); + + instance.$bg + .removeClass(allStates) + .addClass(newState); + + instance.$overlay + .removeClass(allStates) + .addClass(newState); + + instance.$wrapper + .removeClass(allStates) + .addClass(newState); + + instance.$modal + .removeClass(allStates) + .addClass(newState); + + instance.state = state; + !isSilent && instance.$modal.trigger({ + type: state, + reason: reason + }, [{ reason: reason }]); + } + + /** + * Synchronizes with the animation + * @param {Function} doBeforeAnimation + * @param {Function} doAfterAnimation + * @param {Remodal} instance + */ + function syncWithAnimation(doBeforeAnimation, doAfterAnimation, instance) { + var runningAnimationsCount = 0; + + var handleAnimationStart = function(e) { + if (e.target !== this) { + return; + } + + runningAnimationsCount++; + }; + + var handleAnimationEnd = function(e) { + if (e.target !== this) { + return; + } + + if (--runningAnimationsCount === 0) { + + // Remove event listeners + $.each(['$bg', '$overlay', '$wrapper', '$modal'], function(index, elemName) { + instance[elemName].off(ANIMATIONSTART_EVENTS + ' ' + ANIMATIONEND_EVENTS); + }); + + doAfterAnimation(); + } + }; + + $.each(['$bg', '$overlay', '$wrapper', '$modal'], function(index, elemName) { + instance[elemName] + .on(ANIMATIONSTART_EVENTS, handleAnimationStart) + .on(ANIMATIONEND_EVENTS, handleAnimationEnd); + }); + + doBeforeAnimation(); + + // If the animation is not supported by a browser or its duration is 0 + if ( + getAnimationDuration(instance.$bg) === 0 && + getAnimationDuration(instance.$overlay) === 0 && + getAnimationDuration(instance.$wrapper) === 0 && + getAnimationDuration(instance.$modal) === 0 + ) { + + // Remove event listeners + $.each(['$bg', '$overlay', '$wrapper', '$modal'], function(index, elemName) { + instance[elemName].off(ANIMATIONSTART_EVENTS + ' ' + ANIMATIONEND_EVENTS); + }); + + doAfterAnimation(); + } + } + + /** + * Closes immediately + * @private + * @param {Remodal} instance + */ + function halt(instance) { + if (instance.state === STATES.CLOSED) { + return; + } + + $.each(['$bg', '$overlay', '$wrapper', '$modal'], function(index, elemName) { + instance[elemName].off(ANIMATIONSTART_EVENTS + ' ' + ANIMATIONEND_EVENTS); + }); + + instance.$bg.removeClass(instance.settings.modifier); + instance.$overlay.removeClass(instance.settings.modifier).hide(); + instance.$wrapper.hide(); + unlockScreen(); + setState(instance, STATES.CLOSED, true); + } + + /** + * Parses a string with options + * @private + * @param str + * @returns {Object} + */ + function parseOptions(str) { + var obj = {}; + var arr; + var len; + var val; + var i; + + // Remove spaces before and after delimiters + str = str.replace(/\s*:\s*/g, ':').replace(/\s*,\s*/g, ','); + + // Parse a string + arr = str.split(','); + for (i = 0, len = arr.length; i < len; i++) { + arr[i] = arr[i].split(':'); + val = arr[i][1]; + + // Convert a string value if it is like a boolean + if (typeof val === 'string' || val instanceof String) { + val = val === 'true' || (val === 'false' ? false : val); + } + + // Convert a string value if it is like a number + if (typeof val === 'string' || val instanceof String) { + val = !isNaN(val) ? +val : val; + } + + obj[arr[i][0]] = val; + } + + return obj; + } + + /** + * Generates a string separated by dashes and prefixed with NAMESPACE + * @private + * @param {...String} + * @returns {String} + */ + function namespacify() { + var result = NAMESPACE; + + for (var i = 0; i < arguments.length; ++i) { + result += '-' + arguments[i]; + } + + return result; + } + + /** + * Handles the hashchange event + * @private + * @listens hashchange + */ + function handleHashChangeEvent() { + var id = location.hash.replace('#', ''); + var instance; + var $elem; + + if (!id) { + + // Check if we have currently opened modal and animation was completed + if (current && current.state === STATES.OPENED && current.settings.hashTracking) { + current.close(); + } + } else { + + // Catch syntax error if your hash is bad + try { + $elem = $( + '[data-' + PLUGIN_NAME + '-id="' + id + '"]' + ); + } catch (err) {} + + if ($elem && $elem.length) { + instance = $[PLUGIN_NAME].lookup[$elem.data(PLUGIN_NAME)]; + + if (instance && instance.settings.hashTracking) { + instance.open(); + } + } + + } + } + + /** + * Remodal constructor + * @constructor + * @param {jQuery} $modal + * @param {Object} options + */ + function Remodal($modal, options) { + var $body = $(document.body); + var $appendTo = $body; + var remodal = this; + + remodal.settings = $.extend({}, DEFAULTS, options); + remodal.index = $[PLUGIN_NAME].lookup.push(remodal) - 1; + remodal.state = STATES.CLOSED; + + remodal.$overlay = $('.' + namespacify('overlay')); + + if (remodal.settings.appendTo !== null && remodal.settings.appendTo.length) { + $appendTo = $(remodal.settings.appendTo); + } + + if (!remodal.$overlay.length) { + remodal.$overlay = $('
    ').addClass(namespacify('overlay') + ' ' + namespacify('is', STATES.CLOSED)).hide(); + $appendTo.append(remodal.$overlay); + } + + remodal.$bg = $('.' + namespacify('bg')).addClass(namespacify('is', STATES.CLOSED)); + + remodal.$modal = $modal + .addClass( + NAMESPACE + ' ' + + namespacify('is-initialized') + ' ' + + remodal.settings.modifier + ' ' + + namespacify('is', STATES.CLOSED)) + .attr('tabindex', '-1'); + + remodal.$wrapper = $('
    ') + .addClass( + namespacify('wrapper') + ' ' + + remodal.settings.modifier + ' ' + + namespacify('is', STATES.CLOSED)) + .hide() + .append(remodal.$modal); + $appendTo.append(remodal.$wrapper); + + // Add the event listener for the close button + remodal.$wrapper.on('click.' + NAMESPACE, '[data-' + PLUGIN_NAME + '-action="close"]', function(e) { + e.preventDefault(); + + remodal.close(); + }); + + // Add the event listener for the cancel button + remodal.$wrapper.on('click.' + NAMESPACE, '[data-' + PLUGIN_NAME + '-action="cancel"]', function(e) { + e.preventDefault(); + + remodal.$modal.trigger(STATE_CHANGE_REASONS.CANCELLATION); + + if (remodal.settings.closeOnCancel) { + remodal.close(STATE_CHANGE_REASONS.CANCELLATION); + } + }); + + // Add the event listener for the confirm button + remodal.$wrapper.on('click.' + NAMESPACE, '[data-' + PLUGIN_NAME + '-action="confirm"]', function(e) { + e.preventDefault(); + + remodal.$modal.trigger(STATE_CHANGE_REASONS.CONFIRMATION); + + if (remodal.settings.closeOnConfirm) { + remodal.close(STATE_CHANGE_REASONS.CONFIRMATION); + } + }); + + // Add the event listener for the overlay + remodal.$wrapper.on('click.' + NAMESPACE, function(e) { + var $target = $(e.target); + + if (!$target.hasClass(namespacify('wrapper'))) { + return; + } + + if (remodal.settings.closeOnOutsideClick) { + remodal.close(); + } + }); + } + + /** + * Opens a modal window + * @public + */ + Remodal.prototype.open = function() { + var remodal = this; + var id; + + // Check if the animation was completed + if (remodal.state === STATES.OPENING || remodal.state === STATES.CLOSING) { + return; + } + + id = remodal.$modal.attr('data-' + PLUGIN_NAME + '-id'); + + if (id && remodal.settings.hashTracking) { + scrollTop = $(window).scrollTop(); + location.hash = id; + } + + if (current && current !== remodal) { + halt(current); + } + + current = remodal; + lockScreen(); + remodal.$bg.addClass(remodal.settings.modifier); + remodal.$overlay.addClass(remodal.settings.modifier).show(); + remodal.$wrapper.show().scrollTop(0); + remodal.$modal.focus(); + + syncWithAnimation( + function() { + setState(remodal, STATES.OPENING); + }, + + function() { + setState(remodal, STATES.OPENED); + }, + + remodal); + }; + + /** + * Closes a modal window + * @public + * @param {String} reason + */ + Remodal.prototype.close = function(reason) { + var remodal = this; + + // Check if the animation was completed + if (remodal.state === STATES.OPENING || remodal.state === STATES.CLOSING || remodal.state === STATES.CLOSED) { + return; + } + + if ( + remodal.settings.hashTracking && + remodal.$modal.attr('data-' + PLUGIN_NAME + '-id') === location.hash.substr(1) + ) { + location.hash = ''; + $(window).scrollTop(scrollTop); + } + + syncWithAnimation( + function() { + setState(remodal, STATES.CLOSING, false, reason); + }, + + function() { + remodal.$bg.removeClass(remodal.settings.modifier); + remodal.$overlay.removeClass(remodal.settings.modifier).hide(); + remodal.$wrapper.hide(); + unlockScreen(); + + setState(remodal, STATES.CLOSED, false, reason); + }, + + remodal); + }; + + /** + * Returns a current state of a modal + * @public + * @returns {STATES} + */ + Remodal.prototype.getState = function() { + return this.state; + }; + + /** + * Destroys a modal + * @public + */ + Remodal.prototype.destroy = function() { + var lookup = $[PLUGIN_NAME].lookup; + var instanceCount; + + halt(this); + this.$wrapper.remove(); + + delete lookup[this.index]; + instanceCount = $.grep(lookup, function(instance) { + return !!instance; + }).length; + + if (instanceCount === 0) { + this.$overlay.remove(); + this.$bg.removeClass( + namespacify('is', STATES.CLOSING) + ' ' + + namespacify('is', STATES.OPENING) + ' ' + + namespacify('is', STATES.CLOSED) + ' ' + + namespacify('is', STATES.OPENED)); + } + }; + + /** + * Special plugin object for instances + * @public + * @type {Object} + */ + $[PLUGIN_NAME] = { + lookup: [] + }; + + /** + * Plugin constructor + * @constructor + * @param {Object} options + * @returns {JQuery} + */ + $.fn[PLUGIN_NAME] = function(opts) { + var instance; + var $elem; + + this.each(function(index, elem) { + $elem = $(elem); + + if ($elem.data(PLUGIN_NAME) == null) { + instance = new Remodal($elem, opts); + $elem.data(PLUGIN_NAME, instance.index); + + if ( + instance.settings.hashTracking && + $elem.attr('data-' + PLUGIN_NAME + '-id') === location.hash.substr(1) + ) { + instance.open(); + } + } else { + instance = $[PLUGIN_NAME].lookup[$elem.data(PLUGIN_NAME)]; + } + }); + + return instance; + }; + + $(document).ready(function() { + + // data-remodal-target opens a modal window with the special Id + $(document).on('click', '[data-' + PLUGIN_NAME + '-target]', function(e) { + e.preventDefault(); + + var elem = e.currentTarget; + var id = elem.getAttribute('data-' + PLUGIN_NAME + '-target'); + var $target = $('[data-' + PLUGIN_NAME + '-id="' + id + '"]'); + + $[PLUGIN_NAME].lookup[$target.data(PLUGIN_NAME)].open(); + }); + + // Auto initialization of modal windows + // They should have the 'remodal' class attribute + // Also you can write the `data-remodal-options` attribute to pass params into the modal + $(document).find('.' + NAMESPACE).each(function(i, container) { + var $container = $(container); + var options = $container.data(PLUGIN_NAME + '-options'); + + if (!options) { + options = {}; + } else if (typeof options === 'string' || options instanceof String) { + options = parseOptions(options); + } + + $container[PLUGIN_NAME](options); + }); + + // Handles the keydown event + $(document).on('keydown.' + NAMESPACE, function(e) { + if (current && current.settings.closeOnEscape && current.state === STATES.OPENED && e.keyCode === 27) { + current.close(); + } + }); + + // Handles the hashchange event + $(window).on('hashchange.' + NAMESPACE, handleHashChangeEvent); + }); +}); diff --git a/lib/common.lib.php b/lib/common.lib.php index 8bf11615f..604ef164b 100644 --- a/lib/common.lib.php +++ b/lib/common.lib.php @@ -394,15 +394,15 @@ function get_list($write_row, $board, $skin_url, $subject_len=40) $reply = $list['wr_reply']; - $list['reply'] = strlen($reply)*10; + $list['reply'] = strlen($reply)*20; $list['icon_reply'] = ''; if ($list['reply']) - $list['icon_reply'] = '답변글'; + $list['icon_reply'] = '답변글'; $list['icon_link'] = ''; if ($list['wr_link1'] || $list['wr_link2']) - $list['icon_link'] = '관련링크'; + $list['icon_link'] = ' '; // 분류명 링크 $list['ca_name_href'] = G5_BBS_URL.'/board.php?bo_table='.$board['bo_table'].'&sca='.urlencode($list['ca_name']); @@ -412,15 +412,15 @@ function get_list($write_row, $board, $skin_url, $subject_len=40) $list['icon_new'] = ''; if ($board['bo_new'] && $list['wr_datetime'] >= date("Y-m-d H:i:s", G5_SERVER_TIME - ($board['bo_new'] * 3600))) - $list['icon_new'] = '새글'; + $list['icon_new'] = '새글 '; $list['icon_hot'] = ''; if ($board['bo_hot'] && $list['wr_hit'] >= $board['bo_hot']) - $list['icon_hot'] = '인기글'; + $list['icon_hot'] = ' '; $list['icon_secret'] = ''; if (strstr($list['wr_option'], 'secret')) - $list['icon_secret'] = '비밀글'; + $list['icon_secret'] = ' '; // 링크 for ($i=1; $i<=G5_LINK_COUNT; $i++) { @@ -437,7 +437,7 @@ function get_list($write_row, $board, $skin_url, $subject_len=40) } if ($list['file']['count']) - $list['icon_file'] = '첨부파일'; + $list['icon_file'] = ' '; return $list; } @@ -1234,12 +1234,18 @@ function get_sideview($mb_id, $name='', $email='', $homepage='') $width = $config['cf_member_icon_width']; $height = $config['cf_member_icon_height']; $icon_file_url = G5_DATA_URL.'/member/'.$mb_dir.'/'.$mb_id.'.gif'; - $tmp_name .= ''; + $tmp_name .= ''; if ($config['cf_use_member_icon'] == 2) // 회원아이콘+이름 $tmp_name = $tmp_name.' '.$name; } else { - $tmp_name = $tmp_name." ".$name; + if( defined('G5_THEME_NO_PROFILE_IMG') ){ + $tmp_name .= G5_THEME_NO_PROFILE_IMG; + } else if( defined('G5_NO_PROFILE_IMG') ){ + $tmp_name .= G5_NO_PROFILE_IMG; + } + if ($config['cf_use_member_icon'] == 2) // 회원아이콘+이름 + $tmp_name = $tmp_name.' '.$name; } } else { $tmp_name = $tmp_name.' '.$name; @@ -2925,6 +2931,11 @@ function member_delete($mb_id) // 게시판관리자인 경우 게시판관리자를 공백으로 sql_query(" update {$g5['board_table']} set bo_admin = '' where bo_admin = '$mb_id' "); + //소셜로그인에서 삭제 또는 해제 + if(function_exists('social_member_link_delete')){ + social_member_link_delete($mb_id); + } + // 아이콘 삭제 @unlink(G5_DATA_PATH.'/member/'.substr($mb_id,0,2).'/'.$mb_id.'.gif'); } @@ -3321,6 +3332,77 @@ function check_write_token($bo_table) return true; } +function get_member_profile_img($mb_id='', $width='', $height='', $alt='profile_image', $title=''){ + global $member; + + static $no_profile_cache = ''; + static $member_cache = array(); + + $src = ''; + + if( $mb_id ){ + if( isset($member_cache[$mb_id]) ){ + $src = $member_cache[$mb_id]; + } else { + $member_img = G5_DATA_PATH.'/member_image/'.substr($mb_id,0,2).'/'.$mb_id.'.gif'; + if (is_file($member_img)) { + $member_cache[$mb_id] = $src = str_replace(G5_DATA_PATH, G5_DATA_URL, $member_img); + } + } + } + + if( !$src ){ + if( !empty($no_profile_cache) ){ + $src = $no_profile_cache; + } else { + // 프로필 이미지가 없을때 기본 이미지 + $no_profile_img = (defined('G5_THEME_NO_PROFILE_IMG') && G5_THEME_NO_PROFILE_IMG) ? G5_THEME_NO_PROFILE_IMG : G5_NO_PROFILE_IMG; + $tmp = array(); + preg_match( '/src="([^"]*)"/i', $foo, $tmp ); + $no_profile_cache = $src = isset($tmp[1]) ? $tmp[1] : G5_IMG_URL.'/no_profile.gif'; + } + } + + if( $src ){ + $attributes = array('src'=>$src, 'width'=>$width, 'height'=>$height, 'alt'=>$alt, 'title'=>$title); + + $output = ' $value) { + if (!empty($value)) { + $output .= sprintf(' %s="%s"', $name, $value); + } + } + $output .= '>'; + + return $output; + } + + return ''; +} + +function get_head_title($title){ + global $g5; + + if( isset($g5['board_title']) && $g5['board_title'] ){ + $title = $g5['board_title']; + } + + return $title; +} + +function is_use_email_certify(){ + global $config; + + if( $config['cf_use_email_certify'] && function_exists('social_is_login_check') ){ + if( $config['cf_social_login_use'] && (get_session('ss_social_provider') || social_is_login_check()) ){ //소셜 로그인을 사용한다면 + $tmp = (defined('G5_SOCIAL_CERTIFY_MAIL') && G5_SOCIAL_CERTIFY_MAIL) ? 1 : 0; + return $tmp; + } + } + + return $config['cf_use_email_certify']; +} + function get_call_func_cache($func, $args=array()){ static $cache = array(); @@ -3402,4 +3484,18 @@ function is_include_path_check($path='', $is_input='') return true; } + +function option_array_checked($option, $arr=array()){ + $checked = ''; + + if( !is_array($arr) ){ + $arr = explode(',', $arr); + } + + if ( !empty($arr) && in_array($option, (array) $arr) ){ + $checked = 'checked="checked"'; + } + + return $checked; +} ?> \ No newline at end of file diff --git a/lib/latest.lib.php b/lib/latest.lib.php index a37ba466e..63fe44f47 100644 --- a/lib/latest.lib.php +++ b/lib/latest.lib.php @@ -32,7 +32,7 @@ function latest($skin_dir='', $bo_table, $rows=10, $subject_len=40, $cache_time= $cache_fwrite = false; if(G5_USE_CACHE) { - $cache_file = G5_DATA_PATH."/cache/latest-{$bo_table}-{$skin_dir}-{$rows}-{$subject_len}.php"; + $cache_file = G5_DATA_PATH."/cache/latest-{$bo_table}-{$skin_dir}-{$rows}-{$subject_len}-serial.php"; if(!file_exists($cache_file)) { $cache_fwrite = true; @@ -44,9 +44,20 @@ function latest($skin_dir='', $bo_table, $rows=10, $subject_len=40, $cache_time= $cache_fwrite = true; } } + + if(!$cache_fwrite) { + try{ + $file_contents = file_get_contents($cache_file); + $file_ex = explode("\n\n", $file_contents); + $caches = unserialize(base64_decode($file_ex[1])); - if(!$cache_fwrite) - include($cache_file); + $list = (is_array($caches) && isset($caches['list'])) ? $caches['list'] : array(); + $bo_subject = (is_array($caches) && isset($caches['bo_subject'])) ? $caches['bo_subject'] : ''; + } catch(Exception $e){ + $cache_fwrite = true; + $list = array(); + } + } } } @@ -62,17 +73,30 @@ function latest($skin_dir='', $bo_table, $rows=10, $subject_len=40, $cache_time= $result = sql_query($sql); for ($i=0; $row = sql_fetch_array($result); $i++) { try { - unset($row['wr_password']); + unset($row['wr_password']); //패스워드 저장 안함( 아예 삭제 ) } catch (Exception $e) { } + $row['wr_email'] = ''; //이메일 저장 안함 + if (strstr($row['wr_option'], 'secret')){ // 비밀글일 경우 내용, 링크, 파일 저장 안함 + $row['wr_content'] = $row['wr_link1'] = $row['wr_link2'] = ''; + $row['file'] = array('count'=>0); + } $list[$i] = get_list($row, $board, $latest_skin_url, $subject_len); } if($cache_fwrite) { $handle = fopen($cache_file, 'w'); - $cache_content = ""; + $caches = array( + 'list' => $list, + 'bo_subject' => sql_escape_string($bo_subject), + ); + $cache_content = "\n\n"; + $cache_content .= base64_encode(serialize($caches)); //serialize + fwrite($handle, $cache_content); fclose($handle); + + @chmod($cache_file, 0640); } } diff --git a/lib/thumbnail.lib.php b/lib/thumbnail.lib.php index 3f6c20866..1665d207a 100644 --- a/lib/thumbnail.lib.php +++ b/lib/thumbnail.lib.php @@ -349,14 +349,17 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h } else { // 비율에 맞게 생성 $dst = imagecreatetruecolor($dst_w, $dst_h); $bgcolor = imagecolorallocate($dst, 255, 255, 255); // 배경색 - if($src_w > $src_h) { - $tmp_h = round(($dst_w * $src_h) / $src_w); - $dst_y = round(($dst_h - $tmp_h) / 2); - $dst_h = $tmp_h; - } else { - $tmp_w = round(($dst_h * $src_w) / $src_h); - $dst_x = round(($dst_w - $tmp_w) / 2); - $dst_w = $tmp_w; + + if ( !((defined('G5_USE_THUMB_RATIO') && false === G5_USE_THUMB_RATIO) || (defined('G5_THEME_USE_THUMB_RATIO') && false === G5_THEME_USE_THUMB_RATIO)) ){ + if($src_w > $src_h) { + $tmp_h = round(($dst_w * $src_h) / $src_w); + $dst_y = round(($dst_h - $tmp_h) / 2); + $dst_h = $tmp_h; + } else { + $tmp_w = round(($dst_h * $src_w) / $src_h); + $dst_x = round(($dst_w - $tmp_w) / 2); + $dst_w = $tmp_w; + } } if($size[2] == 3) { @@ -382,34 +385,64 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h $dst = imagecreatetruecolor($dst_w, $dst_h); $bgcolor = imagecolorallocate($dst, 255, 255, 255); // 배경색 - if($src_w < $dst_w) { - if($src_h >= $dst_h) { - if( $src_h > $src_w ){ - $tmp_w = round(($dst_h * $src_w) / $src_h); - $dst_x = round(($dst_w - $tmp_w) / 2); - $dst_w = $tmp_w; - } else { + if ( ((defined('G5_USE_THUMB_RATIO') && false === G5_USE_THUMB_RATIO) || (defined('G5_THEME_USE_THUMB_RATIO') && false === G5_THEME_USE_THUMB_RATIO)) ){ + //이미지 썸네일을 비율 유지하지 않습니다. (5.2.6 버전 이하에서 처리된 부분과 같음) + + if($src_w < $dst_w) { + if($src_h >= $dst_h) { $dst_x = round(($dst_w - $src_w) / 2); $src_h = $dst_h; + if( $dst_w > $src_w ){ + $dst_w = $src_w; + } + } else { + $dst_x = round(($dst_w - $src_w) / 2); + $dst_y = round(($dst_h - $src_h) / 2); + $dst_w = $src_w; + $dst_h = $src_h; } } else { - $dst_x = round(($dst_w - $src_w) / 2); - $dst_y = round(($dst_h - $src_h) / 2); - $dst_w = $src_w; - $dst_h = $src_h; - } - } else { - if($src_h < $dst_h) { - if( $src_w > $dst_w ){ - $tmp_h = round(($dst_w * $src_h) / $src_w); - $dst_y = round(($dst_h - $tmp_h) / 2); - $dst_h = $tmp_h; - } else { + if($src_h < $dst_h) { $dst_y = round(($dst_h - $src_h) / 2); $dst_h = $src_h; $src_w = $dst_w; } } + + } else { + //이미지 썸네일을 비율 유지하며 썸네일 생성합니다. + if($src_w < $dst_w) { + if($src_h >= $dst_h) { + if( $src_h > $src_w ){ + $tmp_w = round(($dst_h * $src_w) / $src_h); + $dst_x = round(($dst_w - $tmp_w) / 2); + $dst_w = $tmp_w; + } else { + $dst_x = round(($dst_w - $src_w) / 2); + $src_h = $dst_h; + if( $dst_w > $src_w ){ + $dst_w = $src_w; + } + } + } else { + $dst_x = round(($dst_w - $src_w) / 2); + $dst_y = round(($dst_h - $src_h) / 2); + $dst_w = $src_w; + $dst_h = $src_h; + } + } else { + if($src_h < $dst_h) { + if( $src_w > $dst_w ){ + $tmp_h = round(($dst_w * $src_h) / $src_w); + $dst_y = round(($dst_h - $tmp_h) / 2); + $dst_h = $tmp_h; + } else { + $dst_y = round(($dst_h - $src_h) / 2); + $dst_h = $src_h; + $src_w = $dst_w; + } + } + } } if($size[2] == 3) { diff --git a/mobile/head.php b/mobile/head.php index c7727e996..03d1c2d3b 100644 --- a/mobile/head.php +++ b/mobile/head.php @@ -28,12 +28,14 @@ include_once(G5_LIB_PATH.'/popular.lib.php');
    - +
    + +
      '.PHP_EOL; + echo ' - + +
      +

      사이트 내 전체검색

      +
      + + + + +
      + + +
    - + +
    + -
    -

    사이트 내 전체검색

    -
    - - - - -
    + - - +
    + + + + +
    - - - +
    -
    +
    -
    - -
    +
    -
    -
    - - - - -
    \ No newline at end of file +

    diff --git a/mobile/index.php b/mobile/index.php index 499d2f573..a540e326b 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -25,7 +25,7 @@ for ($i=0; $row=sql_fetch_array($result); $i++) { // 사용방법 // latest(스킨, 게시판아이디, 출력라인, 글자수); - echo latest("basic", $row['bo_table'], 5, 25); + echo latest('basic', $row['bo_table'], 5, 25); } ?> diff --git a/mobile/skin/board/basic/img/btn_next2.gif b/mobile/skin/board/basic/img/btn_next2.gif new file mode 100644 index 000000000..f17993bb1 Binary files /dev/null and b/mobile/skin/board/basic/img/btn_next2.gif differ diff --git a/mobile/skin/board/basic/img/btn_prev2.gif b/mobile/skin/board/basic/img/btn_prev2.gif new file mode 100644 index 000000000..63604af1a Binary files /dev/null and b/mobile/skin/board/basic/img/btn_prev2.gif differ diff --git a/mobile/skin/board/basic/img/cmt_btn.png b/mobile/skin/board/basic/img/cmt_btn.png new file mode 100644 index 000000000..202f1ff47 Binary files /dev/null and b/mobile/skin/board/basic/img/cmt_btn.png differ diff --git a/mobile/skin/board/basic/img/icon_bad.png b/mobile/skin/board/basic/img/icon_bad.png new file mode 100644 index 000000000..e568b1d83 Binary files /dev/null and b/mobile/skin/board/basic/img/icon_bad.png differ diff --git a/mobile/skin/board/basic/img/icon_comment.png b/mobile/skin/board/basic/img/icon_comment.png new file mode 100644 index 000000000..bd7e67f33 Binary files /dev/null and b/mobile/skin/board/basic/img/icon_comment.png differ diff --git a/mobile/skin/board/basic/img/icon_file.gif b/mobile/skin/board/basic/img/icon_file.gif index cca47f566..244af004d 100644 Binary files a/mobile/skin/board/basic/img/icon_file.gif and b/mobile/skin/board/basic/img/icon_file.gif differ diff --git a/mobile/skin/board/basic/img/icon_good.png b/mobile/skin/board/basic/img/icon_good.png new file mode 100644 index 000000000..69841a134 Binary files /dev/null and b/mobile/skin/board/basic/img/icon_good.png differ diff --git a/mobile/skin/board/basic/img/icon_hot.gif b/mobile/skin/board/basic/img/icon_hot.gif index c95b839ae..4e8d7ff1b 100644 Binary files a/mobile/skin/board/basic/img/icon_hot.gif and b/mobile/skin/board/basic/img/icon_hot.gif differ diff --git a/mobile/skin/board/basic/img/icon_link.gif b/mobile/skin/board/basic/img/icon_link.gif index 0f3cb1ac6..e9cb9559c 100644 Binary files a/mobile/skin/board/basic/img/icon_link.gif and b/mobile/skin/board/basic/img/icon_link.gif differ diff --git a/mobile/skin/board/basic/img/icon_lock.png b/mobile/skin/board/basic/img/icon_lock.png new file mode 100644 index 000000000..2a083a51d Binary files /dev/null and b/mobile/skin/board/basic/img/icon_lock.png differ diff --git a/mobile/skin/board/basic/img/icon_reply.gif b/mobile/skin/board/basic/img/icon_reply.gif index 91c135977..7fe2c6558 100644 Binary files a/mobile/skin/board/basic/img/icon_reply.gif and b/mobile/skin/board/basic/img/icon_reply.gif differ diff --git a/mobile/skin/board/basic/img/icon_secret.gif b/mobile/skin/board/basic/img/icon_secret.gif index c04899f14..7be670092 100644 Binary files a/mobile/skin/board/basic/img/icon_secret.gif and b/mobile/skin/board/basic/img/icon_secret.gif differ diff --git a/mobile/skin/board/basic/img/icon_view.png b/mobile/skin/board/basic/img/icon_view.png new file mode 100644 index 000000000..bfa5eb1e6 Binary files /dev/null and b/mobile/skin/board/basic/img/icon_view.png differ diff --git a/mobile/skin/board/basic/img/require.png b/mobile/skin/board/basic/img/require.png new file mode 100644 index 000000000..c03e1eb6f Binary files /dev/null and b/mobile/skin/board/basic/img/require.png differ diff --git a/mobile/skin/board/basic/img/sch_btn.png b/mobile/skin/board/basic/img/sch_btn.png new file mode 100644 index 000000000..94f98db8f Binary files /dev/null and b/mobile/skin/board/basic/img/sch_btn.png differ diff --git a/mobile/skin/board/basic/list.skin.php b/mobile/skin/board/basic/list.skin.php index f651a3aff..ebdacd66f 100644 --- a/mobile/skin/board/basic/list.skin.php +++ b/mobile/skin/board/basic/list.skin.php @@ -10,10 +10,15 @@ if ($is_checkbox) $colspan++; add_stylesheet('', 0); ?> -

    목록

    - + + + -
    "> +
    -
    -
    - Total - 페이지 -
    - - - - +
    + 전체 + 페이지
    +
    @@ -49,79 +45,75 @@ add_stylesheet('', 0 -
      -
    • 목록
    • +
    • 목록
    • -
    • -
    • -
    • +
    • +
    • +
    - -
    @@ -144,7 +136,7 @@ add_stylesheet('', 0 - @@ -153,8 +145,8 @@ add_stylesheet('', 0 - - + + diff --git a/mobile/skin/board/basic/style.css b/mobile/skin/board/basic/style.css index b1d433d3a..3dde42f44 100644 --- a/mobile/skin/board/basic/style.css +++ b/mobile/skin/board/basic/style.css @@ -1,5 +1,4 @@ @charset "utf-8"; -/* SIR 지운아빠 */ /* ### 기본 스타일 커스터마이징 시작 ### */ @@ -11,7 +10,7 @@ #bo_list a.btn_b02:focus, #bo_list .btn_b02:hover {} #bo_list a.btn_admin {} /* 관리자 전용 버튼 */ #bo_list a.btn_admin:focus, #bo_list a.btn_admin:hover {} - +.chk_all{margin:10px 0} /* 읽기 버튼 */ #bo_v a.btn_b01 {} #bo_v a.btn_b01:focus, #bo_v .btn_b01:hover {} @@ -26,55 +25,6 @@ #bo_w .btn_cancel {} #bo_w .btn_frmline {} /* 우편번호검색버튼 등 */ -/* 기본테이블 */ -/* 목록 테이블 */ -#bo_list .tbl_head01 {} -#bo_list .tbl_head01 caption {} -#bo_list .tbl_head01 thead th {} -#bo_list .tbl_head01 thead a {} -#bo_list .tbl_head01 thead th input {} /* middle 로 하면 게시판 읽기에서 목록 사용시 체크박스 라인 깨짐 */ -#bo_list .tbl_head01 tfoot th {} -#bo_list .tbl_head01 tfoot td {} -#bo_list .tbl_head01 tbody th {} -#bo_list .tbl_head01 td {} -#bo_list .tbl_head01 a {} -#bo_list td.empty_table {} - -/* 읽기 내 테이블 */ -#bo_v .tbl_head01 {} -#bo_v .tbl_head01 caption {} -#bo_v .tbl_head01 thead th {} -#bo_v .tbl_head01 thead a {} -#bo_v .tbl_head01 thead th input {} /* middle 로 하면 게시판 읽기에서 목록 사용시 체크박스 라인 깨짐 */ -#bo_v .tbl_head01 tfoot th {} -#bo_v .tbl_head01 tfoot td {} -#bo_v .tbl_head01 tbody th {} -#bo_v .tbl_head01 td {} -#bo_v .tbl_head01 a {} -#bo_v td.empty_table {} - -/* 쓰기 테이블 */ -#bo_w table {} -#bo_w caption {} -#bo_w .frm_address {} -#bo_w .frm_file {} -#bo_w .frm_info {} - -#bo_w .tbl_frm01 {} -#bo_w .tbl_frm01 caption {} -#bo_w .tbl_frm01 th {} -#bo_w .tbl_frm01 td {} -#bo_w .tbl_frm01 textarea, #bo_w .frm_input {} -#bo_w .tbl_frm01 textarea {} -/* -#bo_w .tbl_frm01 #captcha {} -#bo_w .tbl_frm01 #captcha input {} -*/ -#bo_w .tbl_frm01 a {} - -#bo_w .required, #bo_w textarea.required {} - -/* ### 기본 스타일 커스터마이징 끝 ### */ /* 게시판 목록 */ #bo_list .td_chk {width:30px;text-align:center} @@ -88,14 +38,24 @@ #bo_list .td_date {width:60px;text-align:center} #bo_list .td_datetime {width:150px;text-align:center} #bo_list .td_mng {width:80px;text-align:center} +#bo_list .notice_icon{display: inline-block;background: #ff6f6f;padding: 0 5px;line-height: 20px;border-radius: 5px;font-weight: normal;font-size:11px;color: #fff;} +#bo_list .notice_icon i{color:#fff} +#bo_list .bo_subject .fa-download{width:16px;height:16px;line-height:16px;background:#ecaa30;color:#fff;text-align:center;font-size:10px;border-radius:2px} +#bo_list .bo_subject .fa-link{width:16px;height:16px;line-height:16px;background:#2aa974;color:#fff;text-align:center;font-size:10px;border-radius:2px} +#bo_list .bo_subject .fa-heart{color:#ff0000;;text-align:center;font-size:10px;border-radius:2px} +#bo_list .bo_subject .new_icon{display:inline-block;padding: 0 3px;line-height:16px ;font-size:0.833em;color:#fff;background:#c56bed} +#bo_list .bo_tit .fa-lock{color:#666} + #bo_cate h2 {width:0;height:0;font-size:0;line-height:0;overflow:hidden} -#bo_cate ul {margin:5px 10px;padding-left:1px;zoom:1} -#bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} -#bo_cate li {float:left;margin-bottom:-1px;width:25%} -#bo_cate a {display:block;position:relative;margin-left:-1px;padding:5px 0;border:1px solid #ddd;background:#f7f7f7;color:#888;text-align:center;text-decoration:none;letter-spacing:-0.1em} -#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none} -#bo_cate #bo_cate_on {z-index:2;border:1px solid #565e60;background:#fff;color:#565e60;font-weight:bold} +#bo_cate ul {margin: 10px;padding-left:1px;zoom:1} +#bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} +#bo_cate li{display:inline-block;float:left;margin:3px 5px 3px 0} +#bo_cate a {display:block;line-height:24px;padding:0 10px;border-radius:13px;background:#fff;} +#bo_cate #bo_cate_on {background:#4162ff;color:#fff; +-webkit-box-shadow:0 0 5px rgba(65,98,255,0.8); +-moz-box-shadow:0 0 5px rgba(65,98,255,0.8); +box-shadow: 0 0 8px rgba(65,98,255,0.8);} /* 관리자일 때 */ #bo_list_admin th label {position:absolute;font-size:0;line-height:0;overflow:hidden} @@ -112,25 +72,35 @@ #bo_list td:nth-of-type(2) {text-align:center} /* 게시판 목록 공통 */ -.bo_fx {margin-bottom:5px;padding:5px 10px} +.bo_fx {margin-bottom:5px;padding:0 10px} .bo_fx:after {display:block;visibility:hidden;clear:both;content:""} .bo_fx ul {margin:0;padding:0;list-style:none} -#bo_list_total {float:left;padding:0;height:2.5em;line-height:2.5em} +#bo_list_total{position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden;font-size:0} .btn_bo_user {float:right;margin:0;padding:0;list-style:none} .btn_bo_user li {float:left;margin-left:5px} -.btn_bo_adm {float:left} -.btn_bo_adm li {float:left;margin-right:5px} -.btn_bo_adm input {padding:8px;border:0;background:#e8180c;color:#fff;text-decoration:none;vertical-align:middle} +.btn_bo_adm {text-align:center} +.btn_bo_adm li {display:inline-block;} +.btn_bo_adm button {border:0;padding:0 10px;background:#d13f4a;color:#fff;text-decoration:none;vertical-align:middle} .bo_notice td {background:#f7f7f7} .bo_notice td a {font-weight:bold} .td_num strong {color:#000} -.bo_cate_link {display:inline-block;margin:0 3px 0 0;padding:0 6px 0 0;border-right:1px solid #e7f1ed;color:#999 !important;font-weight:bold;text-decoration:none} /* 글제목줄 분류스타일 */ +.bo_cate_link {;color:#3ca1ff !important;font-weight:normal;text-decoration:none;font-size:0.92em} /* 글제목줄 분류스타일 */ +.bo_subject{display:block;font-size:1.083em;font-weight:bold;margin:5px 0} +.bo_subject i{color: #8d96c2;font-size:12px} +.bo_subject .fa-heart{color:#ff0000} .bo_current {color:#e8180c} -.td_subject a {display:block} -.td_subject img {margin-left:3px} -#bo_list .cnt_cmt {display:inline-block;margin:0 0 0 3px;font-weight:bold} +.bo_info{border-top: 1px solid #eee;margin: 10px 0 0;line-height: 20px;color: #666;position: relative;padding-top: 10px;vertical-align:top} +.bo_info .comment_icon{background:url(./img/icon_comment.png) no-repeat 50% 50% ;display:inline-block;width:20px;height:28px;text-indent:-999px;overflow:hidden;vertical-align:top;background-size:70%;margin:0 0px 0 5px} +.bo_info .bo_date{position:absolute;top:10px;right:0;font-style: italic;} +.bo_info .cnt_cmt {display:inline-block;margin: 0 5px 0 3px;} +.bo_info .profile_img img{border-radius:50%;vertical-align:top} -#bo_sch {margin-bottom:10px;padding-top:5px;text-align:center} +#bo_sch {background:#fff;border:1px solid #bdc2d8;position:relative;margin:10px;border-radius:3px} +#bo_sch:after {display:block;visibility:hidden;clear:both;content:""} +#bo_sch legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} +#bo_sch select{border:0;;margin:9px 0;height:20px;border-right:1px solid #ddd;float:left;width:40%} +#bo_sch .sch_input{height:38px;border:0;padding:0;background-color:transparent;float:left;width:60%;padding:0 40px 0 10px} +#bo_sch .sch_btn{height:38px;position:absolute;top:0;right:0;border:0;width:40px;background:none;font-size:15px} /* 게시판 쓰기 */ #bo_w #wr_email, #bo_w #wr_homepage, #bo_w #wr_subject {width:100%} @@ -142,97 +112,163 @@ #wr_email, #wr_homepage, #wr_subject, .wr_link {width:100%} /* 게시판 읽기 */ -#bo_v {margin-bottom:15px;padding-bottom:15px} +#bo_v {padding:20px 10px 10px;background:#fff +;-webkit-box-shadow: 0 1px 4px #ddd; +-moz-box-shadow: 0 1px 4px #ddd; +box-shadow: 0 1px 4px #ddd;} -#bo_v_table {padding:0 10px;color:#999;font-size:0.9em;font-weight:bold} +#bo_v_table {padding: 10px;color:#999;font-size:0.9em;font-weight:bold} -#bo_v_title {padding:0 10px 5px;font-size:1.2em} +#bo_v_title {;text-align:center} +.bo_v_cate{display:inline-block;background: #4162ff;color: #fff;border-radius: 13px;line-height: 24px;padding: 0 10px;font-weight:normal; +-webkit-box-shadow: 0 0 5px rgba(65,98,255,0.8); +-moz-box-shadow: 0 0 5px rgba(65,98,255,0.8); +box-shadow: 0 0 8px rgba(65,98,255,0.8);} +.bo_v_tit{display:block;font-size:1.5em;margin:10px 0 0} +#bo_v header p{font-size:0.92em;color:#777;font-style:italic ;text-align:center;margin:10px 0 0 } -#bo_v_info {padding:0 10px 10px;border-bottom:1px solid #ddd} +#bo_v_info {padding:15px 0px 10px;border-bottom:1px solid #eee;text-align:center;color:#666;line-height:20px;} #bo_v_info h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} -#bo_v_info {} -#bo_v_info strong {display:inline-block;margin:0 0 0 5px;font-weight:normal} +#bo_v_info strong {display:inline-block;font-weight:normal;margin:0 5px} +#bo_v_info .profile_img img{border-radius:50%;vertical-align:top} +#bo_v_info .icon_view{display:inline-block;background:url(./img/icon_view.png) no-repeat 50% 50%;background-size:80%;height:15px;width:20px;overflow:hidden;text-indent:-999px;vertical-align:middle;margin:0 3px 0 5px} +#bo_v_info .icon_comment{display:inline-block;background:url(./img/icon_comment.png) no-repeat 50% 50%;background-size:70%;height:15px;width:20px;overflow:hidden;text-indent:-999px;vertical-align:middle;margin:0 3px 0 5px} -#bo_v_file {} -#bo_v_file h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} +#bo_v_file {margin:10px 0} +#bo_v_file h2 {background:#949ab4;color:#fff;margin-bottom:1px;line-height:35px;padding: 0 10px} #bo_v_file ul {margin:0;padding:0;list-style:none} -#bo_v_file li {padding:0 10px;border-bottom:1px solid #eee;background:#f7f7f7} -#bo_v_file a {display:inline-block;padding:5px 0;color:#000;text-decoration:none} +#bo_v_file li {padding: 10px;border-bottom:1px solid #fff;background:#f1f7fa;color:#777} +#bo_v_file a {display:block;color:#000;text-decoration:none;margin:0 0 3px} #bo_v_file a:focus, #bo_v_file a:hover, #bo_v_file a:active {text-decoration:none} -.bo_v_file_cnt {display:inline-block;margin:0 10px} +#bo_v_file a strong{color:#3497d9;text-decoration:underline} +.bo_v_file_cnt {font-size:0.92em} -#bo_v_link {} -#bo_v_link h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} +#bo_v_link{margin:10px 0} +#bo_v_link h2 {background:#949ab4;color:#fff;margin-bottom:1px;line-height:35px;padding: 0 10px} #bo_v_link ul {margin:0;padding:0;list-style:none} -#bo_v_link li {padding:0 10px;border-bottom:1px solid #eee;background:#f7f7f7} -#bo_v_link a {display:inline-block;padding:5px 0;color:#000;text-decoration:none} +#bo_v_link li {padding: 10px;border-bottom:1px solid #fff;background:#f1f7fa;color:#777} +#bo_v_link a {display:block;color:#000;text-decoration:none;margin:0 0 3px} +#bo_v_link a strong{color:#3497d9;text-decoration:underline} #bo_v_link a:focus, #bo_v_link a:hover, #bo_v_link a:active {text-decoration:none} -.bo_v_link_cnt {display:inline-block;margin:0 10px} +.bo_v_link_cnt {font-size:0.92em} -#bo_v_top {margin:0 0 10px;padding:10px} +#bo_v_top {margin:10px 0;} #bo_v_top:after {display:block;visibility:hidden;clear:both;content:""} #bo_v_top h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} #bo_v_top ul {margin:0;padding:0;list-style:none} +#bo_v_top ul:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_top ul li{display:inline-block;} +.bo_v_left{float:left} +.bo_v_right{float:right} #bo_v_bot {padding:0 10px} #bo_v_bot:after {display:block;visibility:hidden;clear:both;content:""} #bo_v_bot h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} #bo_v_bot ul {margin:0;padding:0;list-style:none} -.bo_v_nb {float:left} -.bo_v_nb li {float:left;margin-right:5px} -.bo_v_com {float:right} -.bo_v_com li {float:left;margin-left:5px} +.bo_v_nb{margin:10px 0;border-top:1px solid #ddd;border-bottom:1px solid #ddd;text-align:center;position:relative;} +.bo_v_nb:after {display:block;visibility:hidden;clear:both;content:""} +.bo_v_nb li {} +.bo_v_nb li a{display:inline-block;padding:10px;color:#777} +.bo_v_nb .bo_v_next{;position:absolute;top:0;right:0;} +.bo_v_nb .bo_v_prev{;position:absolute;top:0;left:0;} -#bo_v_atc {padding:0 10px;min-height:200px} +#bo_v_atc {min-height:200px} #bo_v_atc_title {margin:0;padding:0;height:0;overflow:hidden} #bo_v_img {margin:0 0 10px;width:100%;overflow:hidden;zoom:1} #bo_v_img:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_img a.view_image{display:block} #bo_v_img img {margin-bottom:15px;max-width:100%;height:auto} -#bo_v_con {margin-bottom:20px;width:100%;font-size:1.250em;line-height:1.7em;word-break:break-all;overflow:hidden} +#bo_v_con {min-height:200px;margin-bottom:20px;width:100%;font-size:1.250em;line-height:1.7em;word-break:break-all;overflow:hidden} #bo_v_con a {color:#000;text-decoration:underline} #bo_v_con img {max-width:100%;height:auto} -#bo_v_act {position:relative;margin-bottom:20px;text-align:center} +#bo_v_act {margin-bottom:30px;text-align:center} +#bo_v_act .bo_v_act_gng {position:relative} #bo_v_act a {margin-right:5px;vertical-align:middle} -#bo_v_act strong {color:#ff3061} -#bo_v_act_good, #bo_v_act_nogood {display:none;position:absolute;top:30px;right:10%;padding:10px 0;width:165px;background:#ff3061;color:#fff;text-align:center} +#bo_v_act a:hover{background-color:#f3f3f3} +#bo_v_act_good, #bo_v_act_nogood {display:none;position:absolute;top:30px;left:0;padding:10px 0;width:165px;background:#ff3061;color:#fff;text-align:center} +#bo_v_act .bo_v_good{padding:15px 0;display:inline-block;border:1px solid #000;width:70px;height:70px;line-height:20px;border-radius:50%;font-style:italic} +#bo_v_act .bo_v_nogood{padding:15px 0;display:inline-block;border:1px solid #000;width:70px;height:70px;line-height:20px;border-radius:50%;font-style:italic} +#bo_v_act .bo_v_good i,#bo_v_act .bo_v_nogood i{font-size:18px;} +#bo_v_share{position:relative;margin:20px 0;text-align:right} +#bo_v_share:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_share .btn_scrap{display:inline-block;background:#d4d4d4;color:#444;line-height:40px;width:60px;font-weight:bold;text-align:center;float:left;border-radius:3px} -#bo_v_sns {margin:0 0 20px;padding:0;list-style:none;zoom:1} +.btn_share{display:none;} +.bo_v_snswr{position:relative;float:right} +#bo_v_sns {;padding:0;list-style:none;zoom:1} #bo_v_sns:after {display:block;visibility:hidden;clear:both;content:""} -#bo_v_sns li {float:left;margin:0 5px 0 0} +#bo_v_sns li {float:left;width:50px;text-align:center;margin-left:3px} +#bo_v_sns li a{height:40px;padding:10px 0;} +#bo_v_sns li .sns_f{display:block;background:#415b92;border-radius:3px} +#bo_v_sns li .sns_t{display:block;background:#35b3dc;border-radius:3px} +#bo_v_sns li .sns_g{display:block;background:#d5503a;border-radius:3px} +#bo_v_sns li .sns_k{display:block;background:#fbe300;border-radius:3px} +#bo_v_sns li img{vertical-align:top} /* 게시판 댓글 */ -#bo_vc {margin:0 0 20px;padding:20px 10px 10px;border:1px solid #e5e8ec;background:#f5f8f9} -#bo_vc h2 {margin-bottom:5px} -#bo_vc article {padding:0 0 5px;border-top:1px dotted #ccc} -#bo_vc header {position:relative;padding:13px 0 5px} -#bo_vc header .icon_reply {position:absolute;top:13px;left:-20px} +.cmt_btn{background:url('./img/cmt_btn.png') no-repeat right 8px;text-align:left ;width:100% ;border:0;color:#ed6478;font-weight:bold;font-size:1.167em;margin: 20px 0 10px;padding:0 0 10px ;border-bottom:1px solid #e8e8e8} +.cmt_btn_op{background:url('./img/cmt_btn.png') no-repeat right -23px} + +#bo_vc {} +#bo_vc h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_vc article {margin:0 0 15px} +#bo_vc header {position:relative;padding:0 0 0 50px;height:40px;line-height:20px} +#bo_vc .comment_profile_img{position:absolute;top:0;left:0} +#bo_vc .comment_profile_img img, #bo_vc .profile_img img{border-radius:50%} #bo_vc .sv_member, #bo_vc .sv_guest {font-weight:bold} -.bo_vc_hdinfo {display:inline-block;margin:0 10px 0 5px} +.bo_vc_hdinfo {display:inline-block;color:#777;font-style:italic} #bo_vc h1 {width:0;height:0;font-size:0;line-height:0;overflow:hidden} -#bo_vc a {color:#000;text-decoration:none} -#bo_vc p {padding:0 0 5px;line-height:1.8em} +#bo_vc .cmt_contents {padding:10px 15px ;margin:5px 0 0 ;border-radius:5px;background:#f6f6f6;line-height:1.8em} +#bo_vc .cmt_contents p{font-size:1.083em} #bo_vc p a {text-decoration:underline} -#bo_vc p a.s_cmt {text-decoration:none} +#bo_vc p a.s_cmt {text-decoration:underline;color:#ed6479} #bo_vc_empty {margin:0;padding:15px !important;text-align:center} #bo_vc #bo_vc_winfo {float:left} #bo_vc footer {zoom:1} #bo_vc footer:after {display:block;visibility:hidden;clear:both;content:""} -.bo_vc_act {float:right;margin:0;list-style:none} +.bo_vc_act {text-align:right;;margin:0;list-style:none} .bo_vc_act:after {display:block;visibility:hidden;clear:both;content:""} -.bo_vc_act li {float:left;margin-left:5px} +.bo_vc_act li {display:inline-block;margin:0 2px} +.bo_vc_act li a{color:#3497d9;text-decoration:underline} -#bo_vc_w {position:relative;margin-bottom:10px;padding:0 10px 15px;border-bottom:1px solid #dde4e9} -#bo_vc_w h2 {padding:10px 0 5px} -#bo_vc_w .tbl_wrap {margin:0 0 15px} -#bo_vc_w #char_cnt {display:block;margin-bottom:5px} -#bo_vc_w textarea {width:99%} +.bo_vc_w {position:relative;margin:10px 0;display:block;} +.bo_vc_w:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +.bo_vc_w #char_cnt {display:block;margin:0 0 5px} +.bo_vc_w textarea{border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;width:100%;height:120px} +#wr_secret{} +.bo_vc_w_info{margin:5px 0} +.bo_vc_w_info:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w_info .frm_input{float:left;;width:49.5%;margin: 0 0 5px 0} +.bo_vc_w_info #wr_password{float:right;} +.bo_vc_w_info #captcha{;display:block;clear:both} +.bo_vc_w .btn_confirm{margin-top:5px;clear:both} +.bo_vc_w .icon_lock{display:inline-block;font-size:17px;padding: 5px;margin-right:5px;} +.bo_vc_w .btn_submit{height:50px;width:100%;padding:0 20px;border-radius:3px;font-weight:bold;font-size:1.083em;} +.bo_vc_w_wr:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w .bo_vc_secret{float:right;display:block;} -#bo_vc_sns {margin:0;padding:0;list-style:none;zoom:1} +#bo_vc_send_sns{display:block;float:left} +#bo_vc_sns {display:block;margin:0;padding:0;list-style:none;zoom:1} #bo_vc_sns:after {display:block;visibility:hidden;clear:both;content:""} -#bo_vc_sns li {float:left;margin:0 10px 0 0} -#bo_vc_sns input {margin:0 0 0 5px} \ No newline at end of file +#bo_vc_sns li {float:left;margin:0 5px 0 0} +#bo_vc_sns .sns_li_f{border-radius:3px;background:#3a589b;height:40px;;padding: 10px 0 10px 10px} +#bo_vc_sns .sns_li_t{border-radius:3px;background:#00aced;height:40px;;padding: 10px 0 10px 10px} +#bo_vc_sns .sns_li_off{background:#bbb} +#bo_vc_sns a{display:inline-block;padding:0 15px 0 5px;} +#bo_vc_sns input {margin:0 5px 0 0 } + +/*글쓰기*/ +#bo_w .bo_w_select select{border:1px solid #3497d9;background:#fff;width:100%} +#bo_w .bo_w_link label{position:absolute;top:1px;left:1px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;background:#eee;text-align:center} +#bo_w .bo_w_link .frm_input{padding-left:50px} +#bo_w .bo_w_flie .lb_icon{position:absolute;top:0px;left:0px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;background:#eee;text-align:center} +#bo_w .bo_w_flie .frm_file{padding-left:50px;} +#bo_w .bo_w_flie .file_wr{border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;height:40px;margin:0} +#bo_w .bo_w_flie .frm_input{margin:5px 0 0 } + diff --git a/mobile/skin/board/basic/view.skin.php b/mobile/skin/board/basic/view.skin.php index daa532271..a2b4fb77b 100644 --- a/mobile/skin/board/basic/view.skin.php +++ b/mobile/skin/board/basic/view.skin.php @@ -8,112 +8,46 @@ add_stylesheet('', 0 -
    + +
    -

    +

    + + + + -

    + ?> + +

    작성일

    페이지 정보

    - 작성자 - 작성일 - 조회 - 댓글 + 작성자 + 조회 + 댓글
    - - - -
    -

    첨부파일

    - -
    - - - - - -
    - - - +
    + +

    댓글목록

    @@ -23,54 +25,53 @@ var char_max = parseInt(); // 최대 ?>
    style="margin-left:px;border-top-color:#e0e0e0">
    -

    님의 댓글

    - - 댓글의 댓글 +

    님의 댓글의 댓글

    + + - 아이피 - + 아이피 + () - 작성일 +
    + 작성일
    +
    + +

    + "; ?> + +

    - -

    - "; ?> - -

    + "> - + if($w == 'cu') { + $sql = " select wr_id, wr_content, mb_id from $write_table where wr_id = '$c_id' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + if (!($is_admin || ($member['mb_id'] == $cmt['mb_id'] && $cmt['mb_id']))) + $cmt['wr_content'] = ''; + $c_wr_content = $cmt['wr_content']; + } + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w'; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w'; + ?> + + +
    + + "> - - -

    등록된 댓글이 없습니다.

    @@ -83,7 +84,7 @@ var char_max = parseInt(); // 최대 ?> @@ -259,7 +246,10 @@ var char_max = parseInt(); // 최대 function comment_box(comment_id, work) { - var el_id; + var el_id, + form_el = 'fviewcomment', + respond = document.getElementById(form_el); + // 댓글 아이디가 넘어오면 답변, 수정 if (comment_id) { @@ -276,11 +266,13 @@ var char_max = parseInt(); // 최대 if (save_before) { document.getElementById(save_before).style.display = 'none'; - document.getElementById(save_before).innerHTML = ''; } document.getElementById(el_id).style.display = ''; - document.getElementById(el_id).innerHTML = save_html; + document.getElementById(el_id).appendChild(respond); + //입력값 초기화 + document.getElementById('wr_content').value = ''; + // 댓글 수정 if (work == 'cu') { @@ -311,15 +303,26 @@ var char_max = parseInt(); // 최대 comment_box('', 'c'); // 댓글 입력폼이 보이도록 처리하기위해서 추가 (root님) - // sns 등록 $(function() { + // sns 등록 $("#bo_vc_send_sns").load( "/view_comment_write.sns.skin.php?bo_table=", function() { save_html = document.getElementById('bo_vc_w').innerHTML; } ); + + + }); + + $(function() { + //댓글열기 + $(".cmt_btn").click(function(){ + $(this).toggleClass("cmt_btn_op"); + $("#bo_vc").toggle(); + }); + }); diff --git a/mobile/skin/board/basic/write.skin.php b/mobile/skin/board/basic/write.skin.php index 8d9076d2f..31e01e4cf 100644 --- a/mobile/skin/board/basic/write.skin.php +++ b/mobile/skin/board/basic/write.skin.php @@ -6,8 +6,6 @@ add_stylesheet('', 0 ?>
    -

    -
    @@ -51,115 +49,113 @@ add_stylesheet('', 0 echo $option_hidden; ?> -
    - - - +
    +

    + + +
    + + +
    + + -
    - - - +
    + + +
    - - - - +
    + + class="frm_input full_input " maxlength="20" placeholder="비밀번호"> +
    - - - - +
    + + +
    - - - - +
    + + +
    - - - - +
    + 옵션 + +
    - - - - - - +
    + + +
    - - - - +
    + + + +

    이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

    + + + + +
    글자
    + +
    - - - - - - - - + + - - - - +
    +
    + + +
    + + + + + + + + + + +
    - - - - - + +
    + 자동등록방지 + + +
    - -
    class="frm_input " maxlength="20">
    옵션
    - -
    - - -

    이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

    - - - - -
    글자
    - -
    " id="wr_link" class="frm_input wr_link">
    파일 # - - - - - - - -
    자동등록방지 - -
    -
    - +
    취소 +
    @@ -242,7 +238,7 @@ function fwrite_submit(f) } } - + document.getElementById("btn_submit").disabled = "disabled"; diff --git a/mobile/skin/board/gallery/list.skin.php b/mobile/skin/board/gallery/list.skin.php index 598b13675..4b9e2c65f 100644 --- a/mobile/skin/board/gallery/list.skin.php +++ b/mobile/skin/board/gallery/list.skin.php @@ -8,7 +8,13 @@ add_stylesheet('', 0 -

    목록

    + + +
    @@ -22,19 +28,9 @@ add_stylesheet('', 0 -
    -
    - Total - 페이지 -
    - - - - +
    + 전체 + 페이지
    @@ -60,47 +56,49 @@ add_stylesheet('', 0
  • - - - - - - 열람중"; - else - echo $list[$i]['num']; - ?> - - + 작성자 +
    + 조회 + 추천 + 비추천 + 작성일 +
    +
  • +
    게시물이 없습니다."; } ?> @@ -130,29 +130,20 @@ add_stylesheet('', 0
      -
    • 목록
    • +
    • 목록
    • -
    • -
    • -
    • +
    • +
    • +
    - -
    -
    -
    - - - - - - + echo ''.PHP_EOL; + } + ?> + + + 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. + +
    + 본인확인성인인증 완료 +
    + + + - - - - +
  • + + + + 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    + 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. +
    + + + + +
  • - - - - + + + - - - - +
  • + + " maxlength="255" placeholder="홈페이지"> +
  • - - - - +
  • + + " maxlength="20" placeholder="전화번호"> +
  • - - - - +
  • + + + class="frm_input full_input " maxlength="20" placeholder="휴대폰번호"> + + + + +
  • - - - - +
  • + 주소필수 + + class="frm_input " size="5" maxlength="6" placeholder="우편번호"> +
    + + class="frm_input frm_address " size="50" placeholder="주소">
    + + +
    + + + + +
  • -
    개인정보 입력
    - - 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. - - class="frm_input "> - 아이핀 본인확인'.PHP_EOL; - if($config['cf_cert_hp']) - echo ''.PHP_EOL; +
    + +

    개인정보 입력

    +
  • + + class="frm_input full_input " placeholder="이름"> + 아이핀 본인확인'.PHP_EOL; + if($config['cf_cert_hp'] && $config['cf_cert_hp'] != 'lg') + echo ''.PHP_EOL; - echo ''.PHP_EOL; - } - ?> - -
    - 본인확인성인인증 완료 -
    - -
  • - - 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    - 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. -
    - - - -
    +
  • + + @@ -104,155 +99,170 @@ add_stylesheet('', - -
  • " maxlength="255" >
    " maxlength="20" >
    - class="frm_input " maxlength="20"> - - - -
    - 주소 - 필수 - - - class="frm_input " size="5" maxlength="6"> -
    - - class="frm_input frm_address " size="50">
    - - -
    - - - -
    -
    - - +
    + +

    기타 개인설정

    -
    - - - +
  • + + +
  • - - - - +
  • + + +
  • = $config['cf_icon_level']) { ?> - - - - +
  • + + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다. +
    + + 회원아이콘 + + + + +
  • - - - - + = $config['cf_icon_level'] && $config['cf_member_img_size'] && $config['cf_member_img_width'] && $config['cf_member_img_height']) { ?> +
  • + + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다. +
    + + 회원아이콘 + + + + +
  • + + +
  • + + >정보 메일을 받겠습니다. + +
  • - - - - + + - - - - +
  • + + > + 다른분들이 나의 정보를 볼 수 있도록 합니다. + + 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. + + + +
  • - - - - +
  • + 정보공개 + + + + 정보공개는 수정후 일 이내, 까지는 변경이 안됩니다.
    + 이렇게 하는 이유는 잦은 정보공개 수정으로 인하여 쪽지를 보낸 후 받지 않는 경우를 막기 위해서 입니다. +
    + +
  • + + - - - - +
  • + + +
  • - - - - -
    기타 개인설정
    - - 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    - gif만 가능하며 용량 바이트 이하만 등록됩니다. -
    - - - 회원아이콘 - - - -
    - > - 정보 메일을 받겠습니다. -
    - > +
  • + + + > 휴대폰 문자메세지를 받겠습니다. -
  • - - 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. - - - > - 다른분들이 나의 정보를 볼 수 있도록 합니다. -
    정보공개 - - 정보공개는 수정후 일 이내, 까지는 변경이 안됩니다.
    - 이렇게 하는 이유는 잦은 정보공개 수정으로 인하여 쪽지를 보낸 후 받지 않는 경우를 막기 위해서 입니다. -
    - -
    자동등록방지
    +
  • + 자동등록방지 + +
  • +
    -
    - +
    취소 +
    @@ -288,10 +298,6 @@ add_stylesheet('', $cert_url = G5_KCPCERT_URL.'/kcpcert_form.php'; $cert_type = 'kcp-hp'; break; - case 'lg': - $cert_url = G5_LGXPAY_URL.'/AuthOnlyReq.php'; - $cert_type = 'lg-hp'; - break; default: echo 'alert("기본환경설정에서 휴대폰 본인확인 설정을 해주십시오");'; echo 'return false;'; @@ -412,14 +418,24 @@ add_stylesheet('', if (typeof f.mb_icon != 'undefined') { if (f.mb_icon.value) { - if (!f.mb_icon.value.toLowerCase().match(/.(gif)$/i)) { - alert('회원아이콘이 gif 파일이 아닙니다.'); + if (!f.mb_icon.value.toLowerCase().match(/.(gif|jpe?g|png)$/i)) { + alert('회원아이콘이 이미지 파일이 아닙니다.'); f.mb_icon.focus(); return false; } } } + if (typeof f.mb_img != "undefined") { + if (f.mb_img.value) { + if (!f.mb_img.value.toLowerCase().match(/.(gif|jpe?g|png)$/i)) { + alert("회원이미지가 이미지 파일이 아닙니다."); + f.mb_img.focus(); + return false; + } + } + } + if (typeof(f.mb_recommend) != 'undefined' && f.mb_recommend.value) { if (f.mb_id.value == f.mb_recommend.value) { alert('본인을 추천할 수 없습니다.'); diff --git a/mobile/skin/member/basic/register_result.skin.php b/mobile/skin/member/basic/register_result.skin.php index 44ebe9dd4..fb677f0c1 100644 --- a/mobile/skin/member/basic/register_result.skin.php +++ b/mobile/skin/member/basic/register_result.skin.php @@ -4,41 +4,42 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 // add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨 add_stylesheet('', 0); ?> +
    +

    회원가입이 완료되었습니다.

    +
    +

    + 님의 회원가입을 진심으로 축하합니다.
    +

    -
    + +

    + 회원 가입 시 입력하신 이메일 주소로 인증메일이 발송되었습니다.
    + 발송된 인증메일을 확인하신 후 인증처리를 하시면 사이트를 원활하게 이용하실 수 있습니다. +

    +
    + 아이디 +
    + 이메일 주소 + +
    +

    + 이메일 주소를 잘못 입력하셨다면, 사이트 관리자에게 문의해주시기 바랍니다. +

    + -

    - 님의 회원가입을 진심으로 축하합니다.
    -

    +

    + 회원님의 비밀번호는 아무도 알 수 없는 암호화 코드로 저장되므로 안심하셔도 좋습니다.
    + 아이디, 비밀번호 분실시에는 회원가입시 입력하신 이메일 주소를 이용하여 찾을 수 있습니다. +

    - -

    - 회원 가입 시 입력하신 이메일 주소로 인증메일이 발송되었습니다.
    - 발송된 인증메일을 확인하신 후 인증처리를 하시면 사이트를 원활하게 이용하실 수 있습니다. -

    -
    - 아이디 -
    - 이메일 주소 - +

    + 회원 탈퇴는 언제든지 가능하며 일정기간이 지난 후, 회원님의 정보는 삭제하고 있습니다.
    + 감사합니다. +

    -

    - 이메일 주소를 잘못 입력하셨다면, 사이트 관리자에게 문의해주시기 바랍니다. -

    - - -

    - 회원님의 비밀번호는 아무도 알 수 없는 암호화 코드로 저장되므로 안심하셔도 좋습니다.
    - 아이디, 비밀번호 분실시에는 회원가입시 입력하신 이메일 주소를 이용하여 찾을 수 있습니다. -

    - -

    - 회원 탈퇴는 언제든지 가능하며 일정기간이 지난 후, 회원님의 정보는 삭제하고 있습니다.
    - 감사합니다. -

    diff --git a/mobile/skin/member/basic/scrap.skin.php b/mobile/skin/member/basic/scrap.skin.php index ccb43bac5..6ba0a162c 100644 --- a/mobile/skin/member/basic/scrap.skin.php +++ b/mobile/skin/member/basic/scrap.skin.php @@ -5,13 +5,13 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 add_stylesheet('', 0); ?> -
    +

    -
      +
      • - + 삭제
      • @@ -22,6 +22,6 @@ add_stylesheet('',
        - +
    diff --git a/mobile/skin/member/basic/scrap_popin.skin.php b/mobile/skin/member/basic/scrap_popin.skin.php index 04dfd5fd3..1b3fc792b 100644 --- a/mobile/skin/member/basic/scrap_popin.skin.php +++ b/mobile/skin/member/basic/scrap_popin.skin.php @@ -5,35 +5,34 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 add_stylesheet('', 0); ?> -
    +

    스크랩하기

    + +
    +

    제목 확인 및 댓글 쓰기

    +
      +
    • + 제목 + +
    • +
    • + + +
    • +
    + +

    + 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. +

    -
    - - - - - - - - - - - - -
    제목 확인 및 댓글 쓰기
    제목
    +
    + +
    -

    - 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. -

    - -
    - -
    \ No newline at end of file diff --git a/mobile/skin/member/basic/style.css b/mobile/skin/member/basic/style.css index 60bd23600..7d2123881 100644 --- a/mobile/skin/member/basic/style.css +++ b/mobile/skin/member/basic/style.css @@ -1,7 +1,9 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* ### 기본 스타일 커스터마이징 시작 ### */ +.mbskin{text-align:center;padding:10px} +.mbskin h1{font-size:1.75em;margin:40px 0 25px} +.mbskin p {padding-bottom:20px;border-bottom:1px solid #c8c8c8} +.mbskin p strong{color:#4162ff;padding-bottom:5px;display:block;font-size:1.083em} /* 버튼 */ .mbskin a.btn01 {} @@ -73,123 +75,168 @@ /* ### 기본 스타일 커스터마이징 끝 ### */ /* 회원가입 약관 */ -#fregister section {padding:15px;border-bottom:1px solid #eee;background:#fafafa} -#fregister h2 {margin:0 0 15px;text-align:center} -#fregister textarea {display:block;margin-bottom:10px;padding:5px;width:99%;height:150px;border:1px solid #cfded8;background:#f7f7f7} -.fregister_agree {padding:10px 0 0;text-align:right} +#fregister section {background:#fff;margin:10px 0;border:1px solid #dbdbdb; +-webkit-box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2); +-moz-box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2); +box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2);} +#fregister .chk_all{text-align:left} +#fregister h2 {text-align:left;border-bottom:1px solid #dbdbdb;padding:10px 15px;line-height:1.7em;font-size:1.167em} +#fregister textarea {display:block;padding:10px;width:100%;border:0;background:#fff;height:180px;line-height:1.5em;color:#555} +.fregister_agree {border-top:1px solid #dbdbdb;padding:10px 15px;line-height:1.7em;text-align:left;font-size:1.083em} .fregister_agree label {display:inline-block;margin-right:5px} -#fregister p {color:#e8180c;text-align:center} +#fregister p {border:0;padding:0 0 5px;} #fregister .btn_confirm {margin:15px 0} -#fregister_private .tbl_head01 {margin:0} -#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%} -#fregister_private .tbl_head01 td {border:1px solid #e9e9e9;background:#fff} +#fregister_private .tbl_head01 {padding:20px;margin:0} #fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden;top:0;color:#fff} /* 회원가입 입력 */ #fregisterform #reg_mb_email, #fregisterform .frm_address {width:100%} - #fregisterform textarea {width:100%;height:50px} - #fregisterform #msg_certify {margin:5px 0 0;padding:5px;border:1px solid #dbecff;background:#eaf4ff;text-align:center} - #fregisterform .frm_address {margin:5px 0 0} #fregisterform #mb_addr3 {display:block;margin:5px 0 0} #fregisterform #mb_addr_jibeon {display:block;margin:5px 0 0} +#fregisterform .form_01{margin-bottom: 30px} +#fregisterform .form_01 h2{font-size:1.167em;margin:0 0 5px} +#fregisterform .frm_label{display:block;font-size:1.083em;margin:15px 0 5px;color:#555} +#fregisterform .btn_frmline {height:40px;padding:0 10px} +#fregisterform .rgs_name_li button{margin:5px 0 0 } +#fregisterform .reg_mb_img_file img{max-width:100%;height:auto} /* 회원가입 완료 */ -#reg_result {padding:40px 10px 0} +#reg_result {padding:20px 10px 10px} #reg_result #result_email {margin:20px 0;padding:10px 50px;border-top:1px solid #eee;border-bottom:1px solid #eee;background:#fff;line-height:2em} #reg_result #result_email span {display:inline-block;width:150px} #reg_result #result_email strong {color:#e8180c;font-size:1.2em} -#reg_result p {line-height:1.8em} -#reg_result .btn_confirm {margin:50px 0} +#reg_result h2{text-align:center;font-size:1.25em;margin:0 0 10px} +#reg_result h2 strong{color:#ed6478} +#reg_result p {line-height:1.7em} +#reg_result .btn_confirm {margin:20px 0 30px} +#reg_result .reg_result_wr{background:#fff;padding:10px 20px} +#reg_result .reg_cong{margin:10px 0;font-size:1.083em;font-weight:bold} +#reg_result .reg_cong strong{color:#3497d9} +#reg_result .btn_confirm a{display:inline-block;padding:0 20px;height:40px;line-height:38px;border:1px solid #ed6478;color:#ed6478;border-radius:3px;font-weight:bold} /* 아이디/비밀번호 찾기 */ -#find_info #info_fs {margin:0 20px 10px} -#find_info #info_fs p {margin:0 0 10px;line-height:1.8em} +/*#find_info #info_fs {margin:0 20px 10px}*/ +#find_info #info_fs p {margin:0 0 10px;line-height:1.5em;font-size:0.92em;color:#4162ff} #find_info #info_fs #mb_email {width:100%} -#find_info #captcha {margin:0 20px;padding:0 0 10px} -#find_info #captcha input {margin-left:5px} +#find_info #captcha{margin:5px 0 } /* 로그인 */ -#mb_login {margin:20px 0} -#mb_login h1 {margin:0 0 15px;padding:0 10px;font-size:1.3em} +#mb_login {margin:40px auto 10px;;max-width:500px;padding:20px;} +#mb_login h1 {font-size:2em;text-align:center;margin:0 0 20px} #mb_login h2 {margin:0} #mb_login p {padding:10px 0;line-height:1.5em} -#mb_login #login_frm {position:relative;padding:0 5px;font-size:1em} -#mb_login #login_frm div {padding:10px 0 0;text-align:right} -#mb_login .frm_input {display:block;margin-bottom:5px;padding:0;width:81%;height:1.8em;line-height:1.8em} -#mb_login .btn_submit {position:absolute;top:0;right:5px;padding:0 !important;width:18%;height:4.3em !important;text-align:center} -#mb_login section {margin:30px 0;padding:15px 10px;border:1px solid #cfded8;background:#f7f7f7} -#mb_login section div {text-align:right} +#mb_login #login_frm {position:relative} +#mb_login #login_frm div {padding:10px 0 ;text-align:right} +#mb_login .frm_input {width:100%;margin:5px 0} +#mb_login .btn_submit {width:100%;border-radius:3px;height:40px;margin:5px 0;font-size:1.083em;font-weight:bold} +#mb_login .mb_login_join{border-top:1px solid #ddd;margin:20px 0 0 ;padding:10px 0} +#mb_login .mb_login_join:after {display:block;visibility:hidden;clear:both;content:""} +#mb_login .mb_login_join h2{position:absolute;font-size:0;line-height:0;overflow:hidden} +#mb_login .mb_login_join a{display:block;float:left;width:50%;} +#login_password_lost{border-right:1px solid #cdcdcd;} +#flogin{background:#fff;padding:20px;margin:20px 0;border-bottom:1px solid #ddd;} + +#mb_login_notmb{background:#fff;border-bottom:1px solid #ccc;padding:20px;} +#mb_login_notmb h2{font-size:1.25em;padding:10px;background:#f3f3f3} +#mb_login_notmb p{border:0;padding:0;margin:10px;color:#} +#guest_privacy p{border:1px solid #ddd;background:#fff;color:#666;min-height:20px;height:200px;padding:10px;text-align:left;overflow-y:auto;margin:10px 0} +#mb_login_notmb .btn_submit{width:100%;display:block;height:40px;line-height:40px} + +#mb_login_od_wr{background:#fff;border-bottom:1px solid #ccc;padding:20px;} +#mb_login_od_wr p{border:0;text-align:left;} +#mb_login_od_wr p strong{display:inline} +#mb_login_odinfo{margin:10px 0 0 ;background:#f3f3f3;padding:10px} +#mb_login_odinfo h2{font-size:1.167em} /* 쪽지 */ -#memo_view_contents {margin:0 auto 20px;width:90%} -#memo_view_contents h1 {position:absolute;font-size:0;line-height:0;overflow:hidden} -#memo_view_ul {margin:0;padding:0 0 10px;border-bottom:1px solid #eee;list-style:none} -.memo_view_li {position:relative;padding:5px 0} -.memo_view_subj {display:inline-block;width:65px} +#memo_view_contents {} +#memo_view_contents h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#memo_view_ul {margin:0 0 3px;background:#fff;padding:5px 10px;border-radius:3px; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} +.memo_view_li {position:relative;padding:2px 0} +.memo_view_subj {display:inline-block;width:60px;font-size:0.92em;color:#777} #memo_view_ul a {} -#memo_view p {padding:10px 0;min-height:150px;height:auto !important;height:150px;line-height:1.8em} +#memo_view p {padding:10px 15px;border-radius:3px;;min-height:150px;height:auto !important;height:150px;line-height:1.8em;background:#fff; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} -#memo_list_ul {margin:0 20px;padding:0;border-top:1px solid #e9e9e9;list-style:none} -#memo_list_ul li {position:relative;padding:10px 0;border-bottom:1px solid #e9e9e9} -#memo_list_ul .memo_link {} -#memo_list_ul .memo_send {display:block;margin-top:4px} -#memo_list_ul .memo_send a{color:#777} -#memo_list_ul .memo_read {font-size:0.95em;color:#666} -#memo_list_ul .memo_del {position:absolute;top:10px;right:0} +#memo_list_ul {} +#memo_list_ul li {position:relative;background:#fff;margin:10px 0;border-radius:3px;padding:10px 15px; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} -#memo_write #me_recv_mb_id {width:98%} -#memo_write textarea {width:99%;height:100px} +#memo_list_ul .memo_link {display:block;font-weight:bold;font-size:1.083em;margin:0 0 5px} +#memo_list_ul .memo_date{font-size:0.92em;color:#777;font-style:italic} +#memo_list_ul .memo_del{display:block;position:absolute;top:0;right:0;width:40px;height:40px;background:url(./img/btn_del.gif) no-repeat 50% 50%; text-indent:-9999px;overflow:hidden} + +#memo_write #me_recv_mb_id {width:100%} +#memo_write textarea {width:100%;height:100px} +#memo_write .win_btn{margin:10px;} /* 스크랩 */ -#scrap_ul {margin:0 20px;padding:0;border-top:1px solid #e9e9e9;list-style:none} -#scrap_ul li {position:relative;padding:10px 35px 10px 0;border-bottom:1px solid #e9e9e9} -#scrap_ul .scrap_board {display:inline-block;margin:0 10px 0 0;font-weight:bold} -#scrap_ul .scrap_del {position:absolute;top:10px;right:0} - -#scrap_do table {margin:0 0 10px;width:100%} -#scrap_do textarea {width:99%;height:100px} +#scrap_ul li{position:relative;} +#scrap_ul .scrap_board {display:block;color:#4162ff;margin:0 0 5px} +#scrap_ul .scrap_del {display:block;position:absolute;top:0;right:0;width:40px;height:40px;background:url(./img/btn_del.gif) no-repeat 50% 50%; text-indent:-9999px;overflow:hidden} +#scrap_ul .scrap_link{font-weight:bold;font-size:1.083em;} +.scrap_tit{font-weight:bold;border-bottom:1px solid #d7d7d7;padding:0 0 10px;font-size:1.167em} +#scrap_do #wr_content{margin-top:5px} +#scrap_do label{color:#666} /* 포인트 */ -#point_ul {margin:0 20px;padding:0;border-top:1px solid #e9e9e9;list-style:none} -#point_ul li {position:relative;padding:10px 0;border-bottom:1px solid #e9e9e9} -#point_ul .point_wrap01 {position:relative;padding:0 0 0 90px} -#point_ul .point_wrap02 {margin:7px 0 0;text-align:right} -#point_ul .point_date {position:absolute;top:0;left:0} +#point_ul {;padding:0;border-top:1px solid #e9e9e9;list-style:none} +#point_ul li {position:relative;} +#point_ul li:after {display:block;visibility:hidden;clear:both;content:""} +#point_ul .point_wrap01 {float:left} +#point_ul .point_wrap02 {float:right;text-align:right} +#point_ul .point_log{display:block;font-weight:bold;margin:0 0 5px;font-size:1.083em} +#point_ul .point_inout{display:block;font-weight:bold;margin:0 0 5px;color:#4162ff;font-size:1.083em} +#point_ul .point_date{font-style:italic} -#point_sum {margin:0 20px} -#point_sum .sum_row {margin:0 0 1px;background:#f2f5f9} -#point_sum .sum_row:after {display:block;visibility:hidden;clear:both;content:''} +#point_sum{margin:10px 0 20px} +#point_sum:after {display:block;visibility:hidden;clear:both;content:''} +#point_sum .sum_row {float:left;width:33.333%;text-align:center;background:#939db8;color:#fff;} +#point_sum .sum_row:nth-child(even){background:#8490af} #point_sum .sum_tit, #point_sum .sum_val {display:block;margin:0 0 1px;padding:10px} -#point_sum .sum_tit {clear:both;float:left;width:100px} -#point_sum .sum_val {float:right} +#point_sum .sum_tit {} +#point_sum .sum_val {} /* 회원 비밀번호 확인 */ #mb_confirm {margin:30px 0} #mb_confirm h1 {margin:0 0 15px;padding:0 10px;font-size:1.3em} #mb_confirm p {padding:15px 10px;border-bottom:1px solid #cfded8;border-bottom:0;background:#fff} #mb_confirm p strong {display:block} -#mb_confirm fieldset {position:relative;margin:0 0 5px;padding:20px 10px;border-bottom:1px solid #cfded8;background:#f7f7f7} -#mb_confirm_pw {display:block;margin-top:10px;padding:0;width:88%;line-height:1.8em !important} -#mb_confirm .btn_submit {position:absolute;bottom:20px;right:10px;width:10%;height:1.9em !important;line-height:1.9em} +#mb_confirm fieldset {position:relative;margin:20px 0;text-align:left;color:#555} +#mb_confirm_id{font-weight:bold;display:block;font-size:1.083em;margin:5px 0} +#mb_confirm_pw {display:block;margin-top:10px;width:100%} +#mb_confirm .btn_submit {width:100%;height:40px;border-radius:3px;margin:10px 0} /* 비밀글 비밀번호 확인 */ -#pw_confirm {margin:30px 0} -#pw_confirm h1 {margin:0 0 15px;padding:0 10px;font-size:1.3em} -#pw_confirm p {padding:15px 10px;border-bottom:1px solid #cfded8;border-bottom:0;background:#fff} -#pw_confirm p strong {display:block} -#pw_confirm fieldset {position:relative;margin:0 0 5px;padding:5px 5px 10px;border-bottom:1px solid #cfded8;background:#f7f7f7} -#pw_wr_password {display:block;margin-top:10px;padding:0;width:88%;line-height:1.8em !important} -#pw_confirm .btn_submit {position:absolute;bottom:10px;right:5px;width:10%;height:1.9em !important;line-height:1.9em} +#pw_confirm fieldset {position:relative;margin:0 0 5px;padding:15px 0;border-top:1px solid #fffefe} +#pw_wr_password {width:100%} +#pw_confirm .btn_submit {margin:5px 0;width:100%;border-radius:3px;height:45px;font-weight:bold;font-size:1.083em} /* 폼메일 */ -#formmail #subject {width:98%} -#formmail textarea {width:99%;height:100px} +#formmail #subject {width:100%} +#formmail textarea {width:100%;height:100px} +#formmail .frm_file{padding-left:50px;} +#formmail .file_wr{border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;height:40px;} +#formmail .lb_icon{position:absolute;top:0px;left:0px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;overflow:hidden;text-indent:-999px;background:url(./img/icon_file.gif) no-repeat 50% 50% #eee} /* 자기소개 */ -#profile table {margin-bottom:0} -#profile section {padding:10px 20px} +#profile section {margin:10px; } #profile h2 {margin:0} -#profile .sv_wrap a {margin:0 0 5px;padding:0;font-weight:bold;line-height:10px} \ No newline at end of file +#profile .sv_wrap a {color:#fdff2f} +#profile table{width:100%;border-collapse:collapse} +#profile table th{background:#fff;padding:10px;width:90px;text-align:left;border-bottom:1px solid #eee} +#profile table td{background:#fff;padding:10px;border-bottom:1px solid #eee} +#profile p{background:#fff;padding:10px;margin:10px 0; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} \ No newline at end of file diff --git a/mobile/skin/new/basic/new.skin.php b/mobile/skin/new/basic/new.skin.php index 9055d2b52..e7263f92f 100644 --- a/mobile/skin/new/basic/new.skin.php +++ b/mobile/skin/new/basic/new.skin.php @@ -16,8 +16,8 @@ add_stylesheet('', 0);
    + + +
    - - - - - -
    -

    연락처정보

    -
    - -
    이메일
    -
    - - -
    휴대폰
    -
    - -
    -
    - - +
    -
    -

    본문

    - - \n"; - - for ($i=0; $i<$view['img_count']; $i++) { - //echo $view['img_file'][$i]; - echo get_view_thumbnail($view['img_file'][$i], $qaconfig['qa_image_width']); - } - - echo "
    \n"; - } - ?> - - -
    - - - - - - - - ', 0);

    연관질문

    -
    - - - - - - - - - - +
    + +
      -
    - - - - - - - -
    분류제목상태등록일
    - - - -
    + for($i=0; $i<$view['rel_count']; $i++) { + ?> +
  • +
    + + + + + +
    +
    + + +
    +
  • + +
    - -
    - -
    - + diff --git a/mobile/skin/qa/basic/write.skin.php b/mobile/skin/qa/basic/write.skin.php index adbcbdfbb..3d19ca931 100644 --- a/mobile/skin/qa/basic/write.skin.php +++ b/mobile/skin/qa/basic/write.skin.php @@ -27,92 +27,82 @@ add_stylesheet('', 0); echo $option_hidden; ?> -
    - - - - - - - - + + - - - - - - + +
  • + 옵션 + +
  • + - - - - - - + + - - - - - - + + - - - - +
  • + + +
  • - - - - +
  • + +
    + +
    +
  • - - - - +
  • +
    + 파일 #1 + + + + +
    +
  • - - - - +
  • +
    + 파일 #2 + + + + +
    +
  • - -
    +
    +
      + +
    • + -
    옵션
    - class="frm_input email" maxlength="100"> + +
  • + + class="frm_input full_input email" maxlength="100" placeholder="이메일"> > -
  • - class="frm_input" size="30"> + +
  • + + class="frm_input full_input" size="30" placeholder="휴대폰"> > 답변등록 SMS알림 수신 -
  • - -
    - -
    파일 #1 - - - - -
    파일 #2 - - - - -
    +
    -
    - - 목록 +
    + 목록 +
    diff --git a/mobile/skin/search/basic/search.skin.php b/mobile/skin/search/basic/search.skin.php index c1ae64ec8..d4229ec77 100644 --- a/mobile/skin/search/basic/search.skin.php +++ b/mobile/skin/search/basic/search.skin.php @@ -9,7 +9,7 @@ add_stylesheet('',
    상세검색 -
    +
    @@ -21,11 +21,10 @@ add_stylesheet('', -
    -
    + - - + + + + +
    +
    \ No newline at end of file diff --git a/mobile/skin/social/social_outlogin.skin.1.php b/mobile/skin/social/social_outlogin.skin.1.php new file mode 100644 index 000000000..43260475d --- /dev/null +++ b/mobile/skin/social/social_outlogin.skin.1.php @@ -0,0 +1,85 @@ +', 10); +?> + + \ No newline at end of file diff --git a/mobile/skin/social/social_register.skin.php b/mobile/skin/social/social_register.skin.php new file mode 100644 index 000000000..66ee7d886 --- /dev/null +++ b/mobile/skin/social/social_register.skin.php @@ -0,0 +1,87 @@ +', 10); +?> +
    + +
    \ No newline at end of file diff --git a/mobile/skin/social/social_register_member.skin.php b/mobile/skin/social/social_register_member.skin.php new file mode 100644 index 000000000..e0a150434 --- /dev/null +++ b/mobile/skin/social/social_register_member.skin.php @@ -0,0 +1,201 @@ +', 11); +add_stylesheet('', 12); +add_stylesheet('', 13); +add_javascript('', 10); + +$email_msg = $is_exists_email ? '등록할 이메일이 중복되었습니다.다른 이메일을 입력해 주세요.' : ''; +?> + + +
    + + + + +
    + + + + + + + + + + +
    +
    + 자세히보기 + +
    +
    +

    +
    +
    +
    +
    + 자세히보기 + +
    +
    +

    +
    +
    +
    + +
    + +
    + + + + + + + + + +
    개인정보 입력
    + + +
    +
    + +
    + 취소 + +
    +
    + + + + + + +
    +

    혹시 기존 회원이신가요?

    + +
    + + + + + +
    + \ No newline at end of file diff --git a/mobile/skin/social/social_u_register_form.skin.php b/mobile/skin/social/social_u_register_form.skin.php new file mode 100644 index 000000000..c9a14c752 --- /dev/null +++ b/mobile/skin/social/social_u_register_form.skin.php @@ -0,0 +1,167 @@ +', 10); +?> + +
  • + +
    +
    + + $provider_name ){ + + if( !option_array_checked($social, $config['cf_social_servicelist'])) { + continue; + } + + $social_nonce = social_nonce_create($social, $session_id); + $add_class=''; + $title=''; + if( in_array($social, $my_provides) ){ + + $link_href = G5_SOCIAL_LOGIN_URL.'/unlink.php?provider='.$social.'&social_nonce='.$social_nonce; + + $title = $provider_name.' 연결해제하기'; + } else { + $add_class = ' sns-icon-not'; + + $link_href = $self_url.'?provider='.$social.'&mylink=1&url='.$urlencode; + + $title = $provider_name.' 연결하기'; + + } + ?> + + + + + +
    +
    +
  • + + \ No newline at end of file diff --git a/mobile/skin/social/style.css b/mobile/skin/social/style.css new file mode 100644 index 000000000..10c35de0f --- /dev/null +++ b/mobile/skin/social/style.css @@ -0,0 +1,155 @@ +@charset "utf-8"; + +.social_info_guide{background:#f3f3f3;border:1px solid #ddd;margin:0 10px 10px;padding:10px 15px;line-height:1.5em} +.bg-warning{margin:0 10px 10px;padding:10px 15px;line-height:1.5em} +.bg-warning1{background:#f7dfe4;border:1px solid #eac3cb} +.bg-warning2{background:#deeabf;border:1px solid #bde498} +.bg-warning3{background:#fff8dc;border:1px solid #f1e4b2} + +/* SNS LOGIN */ +.login-sns{padding-bottom:10px;margin-top:5px;;clear:both;} +.login-sns h3{padding-top:10px;text-align:center;color:#b2b2b2;;margin-top:15px;font-weight:normal} +.sns-wrap {margin:10px 0 0;text-align:center} +.sns-icon {display:inline-block;vertical-align:middle;text-decoration:none} +.sns-icon:hover {text-decoration:none} +.sns-icon .ico {display:block;vertical-align:middle} +.sns-icon .txt i {font-style:normal} + +#fregisterform .form_01 .reg-form {margin-bottom:20px} +#fregisterform .form_01 .reg-form .sns-wrap {margin:10px 0 0;text-align:left} +.reg-form .sns-icon {display:inline-block;vertical-align:middle;text-decoration:none;border-width:1px;border-style:solid;overflow:hidden;margin:0 1px} +.reg-form .sns-icon:hover {text-decoration:none} +.reg-form .sns-icon .ico {display:block;background:url('./img/sns_logo.png') no-repeat;vertical-align:middle;width:24px;height:24px} +.reg-form .sns-icon-not .ico {display:block;background:url('./img/sns_logo_not.png') no-repeat;vertical-align:middle} +.reg-form .sns-icon .txt {position:absolute;line-height:0;font-size:0;vertical-align:middle;overflow:hidden} +.reg-form .sns-icon .txt i {font-style:normal} + +.sns-wrap-reg .sns-naver {border-color:#18a400;background:#2db400} +.sns-wrap-reg .sns-naver .ico {background-position:-29px 0; } +.sns-wrap-reg .sns-google {border-color:#ca2c19;background:#dd5443} +.sns-wrap-reg .sns-google .ico {background-position:-58px 0} +.sns-wrap-reg .sns-facebook {border-color:#2e5393;background:#3a5897} +.sns-wrap-reg .sns-facebook .ico {background-position:0 0 } + +.sns-wrap-reg .sns-icon {border-color:#dcdcdc} +.sns-wrap-reg .sns-icon-not {border-color:#8b8b8b} +.sns-wrap-reg .sns-naver{border-color:#18a400} +.sns-wrap-reg .sns-naver .ico {background-position:-29px 0; } +.sns-wrap-reg .sns-google .ico {background-position:-58px 0} +.sns-wrap-reg .sns-google {border-color:#ca2c19} +.sns-wrap-reg .sns-facebook .ico {background-position:0 0 } +.sns-wrap-reg .sns-facebook {border-color:#2e5393} +.sns-wrap-reg .sns-kakao .ico {background-position:-87px 0} +.sns-wrap-reg .sns-twitter {border-color:#488FC9} +.sns-wrap-reg .sns-twitter .ico {background-position:-145px 0} +.sns-wrap-reg .sns-payco {border-color:#C44646} +.sns-wrap-reg .sns-payco .ico {background-position:-116px 0} +.sns-wrap-reg .sns-kakao {border-color:#f2df00} + +/* SNS by COLOR */ +.sns-wrap-over .sns-naver{background:url('./img/sns_naver_s.png') no-repeat} +.sns-wrap-over .sns-google {background:url('./img/sns_gp_s.png') no-repeat} +.sns-wrap-over .sns-facebook {background:url('./img/sns_fb_s.png') no-repeat} +.sns-wrap-over .sns-twitter {background:url('./img/sns_twitter_s.png') no-repeat} +.sns-wrap-over .sns-payco {background:url('./img/sns_payco_s.png') no-repeat} +.sns-wrap-over .sns-kakao {background:url('./img/sns_kakao_s.png') no-repeat} +.reg-form .sns-icon-not {border-color:#8b8b8b} + + +/* 아웃로그인 */ +#sns_outlogin {clear:both;} +#sns_outlogin .sns-icon {overflow:hidden;margin:0 1px} +#sns_outlogin .sns-icon .txt {position:absolute;line-height:0;font-size:0;vertical-align:middle;overflow:hidden} +#sns_outlogin .sns-icon .ico {width:30px;height:30px} + +/*로그인 */ +#sns_login{border:0;margin-top:15px;padding:0; border-top:1px solid #edeaea} +#sns_login h3{padding: 0;font-weight:bold;color:#888;text-align:center} +#sns_login .sns-icon{display:block;height:40px;line-height:40px;width:100%;margin:0 0 5px;padding-left:40px;text-align:left;color:#fff;border-radius:2px} +#sns_login .sns-naver{background-color:#1fc800;background-position:5px 5px;border-bottom:1px solid #1ea505} +#sns_login .sns-kakao{background-color:#ffeb00;background-position:5px 5px;border-bottom:1px solid #e2c10a} +#sns_login .sns-kakao {color:#3c1e1e} +#sns_login .sns-facebook{background-color:#3b579d;background-position:5px 5px;border-bottom:1px solid #28458f} +#sns_login .sns-google{background-color:#db4a3a;background-position:5px 5px;border-bottom:1px solid #c03121} +#sns_login .sns-twitter{background-color:#1ea1f2;background-position:5px 5px;border-bottom:1px solid #1e82c0} +#sns_login .sns-payco{background-color:#df0b00;background-position:5px 5px;border-bottom:1px solid #9d0800} +#sns_login .txt{text-align:left;padding-left:10px;border-left:1px solid rgba(0,0,0,0.1);display:block;font-weight:bold} + +/*회원가입 */ +#sns_register{margin:0 0 10px;padding:0;text-align:center;background:#fff;border: 1px solid #dbdbdb; +-webkit-box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2); +-moz-box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2); +box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2);} +#sns_register h2{font-size: 1.167em;text-align: left;padding: 15px 20px;border-bottom: 1px solid #dbdbdb;} +#sns_register .sns-wrap:after {display:block;visibility:hidden;clear:both;content:""} +#sns_register .sns-wrap{display:inline-block;padding:20px;vertical-align:top;margin:0} +#sns_register .sns-icon{display:inline-block;height:40px;line-height:40px;width:100%;margin:0 0 5px;padding-left:40px;text-align:left;color:#fff;border-radius:2px;float:left} +#sns_register .sns-icon:nth-child(3n+1){clear:both} +#sns_register .sns-naver{background-color:#1fc800;background-position:5px 5px;border-bottom:1px solid #1ea505} +#sns_register .sns-kakao{background-color:#ffeb00;background-position:5px 5px;border-bottom:1px solid #e2c10a} +#sns_register .sns-kakao {color:#3c1e1e} +#sns_register .sns-facebook{background-color:#3b579d;background-position:5px 5px;border-bottom:1px solid #28458f} +#sns_register .sns-google{background-color:#db4a3a;background-position:5px 5px;border-bottom:1px solid #c03121} +#sns_register .sns-twitter{background-color:#1ea1f2;background-position:5px 5px;border-bottom:1px solid #1e82c0} +#sns_register .sns-payco{background-color:#df0b00;background-position:5px 5px;border-bottom:1px solid #9d0800} +#sns_register .txt{text-align:;padding-left:10px;border-left:1px solid rgba(0,0,0,0.1);display:block;font-weight:bold} + + +/* LOGIN LOADING */ +.social-login-loading{width:100%;height:auto;text-align:center} +.social-login-loading p{display:inline-block;margin-top:10px;padding:40px 0 0;line-height:30px} + +/*기존 계정에 연결하기*/ + +/* Styles for Accordion */ +.mbskin .toggle{position:relative;display:block;border:1px solid #c6cacc;margin-top:-1px;background-color: #fcfcfc;margin:0 0 5px} +.mbskin .toggle .toggle-title{padding:13px 15px;line-height:20px} +.mbskin .toggle .title-name{display:block} +.mbskin .toggle .toggle-inner{padding:15px;line-height:1.5em;display:none;background:#fff;border-top:1px solid #e2e2e2;} +.mbskin .toggle .toggle-inner div{max-width:100%} +.mbskin .right_i{position:absolute;font-size:0.92em;top:10px;right:10px;padding:0 10px 0 0;border-radius:3px;display:inline-block;z-index: 2;background: #3497d9;color: #fff;border-bottom-color: #1977b5;} +.mbskin .toggle .toggle-title .right_i i{background:url("./img/plus_minus.png") 0 -24px no-repeat;width:20px;height:24px;display:inline-block;vertical-align:middle} +.mbskin .toggle .toggle-title.active .right_i i{background:url("./img/plus_minus.png") 0 0 no-repeat} +.mbskin .all_agree{position:relative;display:block;;margin-bottom:6px;background:#d9d9d9;border-radius:3px;border-top:0;padding:13px 15px;line-height:20px} + +#register_member .sns_tbl{background:#fff;;margin:10px 0;border:1px solid #c6cacc;} +.sns_tbl table{border:0} +.sns_tbl caption{ padding: 0 20px;line-height: 45px;font-size: 1.083em;border-bottom: 1px solid #e2e2e2;color:#4162ff;background: #fff;} +.sns_tbl th{width:80px;text-align:right;vertical-align:top;line-height:40px;padding:10px;} +.sns_tbl td{padding:10px;} +.sns_tbl .email_msg{color:#777;margin:5px 0 0} +.sns_tbl .frm_input {width:100%} +#fregisterform{margin:10px} +#fregisterform .btn_confirm{text-align:center;margin:20px 0} +#fregisterform .btn_confirm .btn_submit{height:45px;;padding:0 30px;font-weight:bold;font-size:1.083em} +#fregisterform .btn_confirm .btn_cancel{line-height:45px;height:45px;padding:0 30px;font-weight:bold;font-size:1.083em} + +#sns-link-pnl.remodal{border-radius:5px;max-width:400px; +-webkit-box-shadow:0 0 10px rgba(0, 0, 0,0.8); +-moz-box-shadow:0 0 10px rgba(0, 0, 0,0.8); +box-shadow:0 0 10px rgba(0, 0, 0,0.8);} +#sns-link-pnl .connect-close {position:absolute;top:10px;right:10px;margin:0;padding:0;width:30px;height:30px;border:0;background:transparent;color:#383838;cursor:pointer;font-size:15px} +#sns-link-pnl .connect-close:hover {color:#ff5191} +#sns-link-pnl .connect-close .fa {margin:0 0 0 1px} +#sns-link-pnl .connect-close .txt {position:absolute;line-height:0;font-size:0;overflow:hidden} + +#sns-link-pnl #login_fs{margin:0 auto;width:100%;text-align:left} +#sns-link-pnl #login_fs label{display:block;display: block;font-size: 0.93em;color: #7a7a7a;margin: 5px 0;} +#sns-link-pnl #login_fs .lg_id,#sns-link-pnl #login_fs .lg_pw{width:100%;margin-bottom:5px;} +#sns-link-pnl #login_id,#sns-link-pnl #login_pw{width:100%} +#sns-link-pnl #login_fs .login_submit{width: 100%;height: 44px;font-size:1.167em;margin:10px auto 0;font-weight:bold;cursor:pointer;display:block;} +#sns-link-pnl .connect-fg {height:320px;text-align:left} +#sns-link-pnl .login_fs {margin:0 auto;width:260px} +#sns-link-pnl .connect-fg .connect-desc {margin:0 0 10px;padding:15px;border:1px solid #d6e9c6;background:#dff0d8;color:#3c763d} +#sns-link-pnl .connect-fg .connect-title {margin-top:25px;margin-bottom:10px;font-size:1.667em;font-weight:bold;text-align:center} + +.mbskin .member_connect:after {display:block;visibility:hidden;clear:both;content:""} +.mbskin .member_connect{margin-top:1em;border: 2px solid #cacaca;margin:10px;padding:10px;text-align:left} +.mbskin .member_connect .strong{font-weight:bold;margin:0 0 10px;font-size:0.97em} +.mbskin .member_connect button{color: #fff;border:0;padding:7px 13px;border:1px solid #6446e7;font-weight:bold;background: #6f50e7;border-radius:3px;font-size:0.92em} +.mbskin .member_connect button:hover{background:#6446e7} + +.mbskin .btn_group_trigger{margin:10px;text-align:center} +.mbskin .btn_group_trigger .btn_submit_trigger{display:inline-block;height:45px;line-height:45px;color:#fff;padding:0 30px;font-weight:bold;font-size:1.083em;background:#253dbe} + +.mbskin .member_connect{margin-top:50px} \ No newline at end of file diff --git a/mobile/skin/visit/basic/style.css b/mobile/skin/visit/basic/style.css index 5a9c00719..26ee1ad6e 100644 --- a/mobile/skin/visit/basic/style.css +++ b/mobile/skin/visit/basic/style.css @@ -1,11 +1,15 @@ @charset "utf-8"; -/* SIR 지운아빠 */ -#visit {border-bottom:1px dotted #dde4e9} -#visit div {zoom:1} -#visit div:after {display:block;visibility:hidden;clear:both;content:""} -#visit h2 {float:left;padding:10px} -#visit dl {float:left;margin:0 0 0 5px;padding:0} -#visit dt {float:left;margin:0;padding:10px 5px;letter-spacing:-0.1em} -#visit dd {float:left;margin:0 3px 0 0;padding:10px 5px} +#visit {margin:30px 10px} +#visit h2 {display:inline-block;background: #4162ff;color: #fff;border-radius: 13px;line-height: 24px;padding: 0 10px;margin:0 0 10px; +-webkit-box-shadow: 0 0 5px rgba(65,98,255,0.8); +-moz-box-shadow: 0 0 5px rgba(65,98,255,0.8); +box-shadow: 0 0 8px rgba(65,98,255,0.8); } +#visit dl{background:#fff;padding:10px;border-radius:3px;line-height:20px; +-webkit-box-shadow: 0 1px 4px #cbd1df; + -moz-box-shadow: 0 1px 4px #cbd1df; + box-shadow: 0 1px 4px #cbd1df;} +#visit dl:after {display:block;visibility:hidden;clear:both;content:""} +#visit dt {float:left;width:50%} +#visit dd {float:left;width:50%;text-align:right} #visit a {display:inline-block;padding:10px 3px;text-decoration:none} \ No newline at end of file diff --git a/mobile/skin/visit/basic/visit.skin.php b/mobile/skin/visit/basic/visit.skin.php index 04027bdec..3e4bf3430 100644 --- a/mobile/skin/visit/basic/visit.skin.php +++ b/mobile/skin/visit/basic/visit.skin.php @@ -8,18 +8,16 @@ add_stylesheet('', 0 ?> diff --git a/mobile/tail.php b/mobile/tail.php index 3a7ef7018..74335a2af 100644 --- a/mobile/tail.php +++ b/mobile/tail.php @@ -9,15 +9,13 @@ if(defined('G5_THEME_PATH')) {
    -
    + + -
    - -
    회사소개 @@ -25,25 +23,50 @@ if(defined('G5_THEME_PATH')) { 서비스이용약관
    Copyright © 소유하신 도메인. All rights reserved.
    - 상단으로
    + + + PC 버전으로 보기 +
    - -PC 버전으로 보기 - diff --git a/plugin/editor/smarteditor2/css/smart_editor2.css b/plugin/editor/smarteditor2/css/smart_editor2.css index 6fde2758d..881272d8d 100644 --- a/plugin/editor/smarteditor2/css/smart_editor2.css +++ b/plugin/editor/smarteditor2/css/smart_editor2.css @@ -3,6 +3,7 @@ /* COMMON */ body,#smart_editor2,#smart_editor2 p,#smart_editor2 h1,#smart_editor2 h2,#smart_editor2 h3,#smart_editor2 h4,#smart_editor2 h5,#smart_editor2 h6,#smart_editor2 ul,#smart_editor2 ol,#smart_editor2 li,#smart_editor2 dl,#smart_editor2 dt,#smart_editor2 dd,#smart_editor2 table,#smart_editor2 th,#smart_editor2 td,#smart_editor2 form,#smart_editor2 fieldset,#smart_editor2 legend,#smart_editor2 input,#smart_editor2 textarea,#smart_editor2 button,#smart_editor2 select{margin:0;padding:0} #smart_editor2,#smart_editor2 h1,#smart_editor2 h2,#smart_editor2 h3,#smart_editor2 h4,#smart_editor2 h5,#smart_editor2 h6,#smart_editor2 input,#smart_editor2 textarea,#smart_editor2 select,#smart_editor2 table,#smart_editor2 button{font-family:'돋움',Dotum,Helvetica,sans-serif;font-size:12px;color:#666} +#smart_editor2{background:#fff} #smart_editor2 span,#smart_editor2 em{font-size:12px} #smart_editor2 em,#smart_editor2 address{font-style:normal} #smart_editor2 img,#smart_editor2 fieldset{border:0} diff --git a/plugin/jquery-ui/datepicker.php b/plugin/jquery-ui/datepicker.php index f351816bc..18988b2d8 100644 --- a/plugin/jquery-ui/datepicker.php +++ b/plugin/jquery-ui/datepicker.php @@ -1,11 +1,11 @@ ', 0); +add_stylesheet('', 0); add_stylesheet('', 0); ?> - + '; + $html .= ''; + $html .= '
    '; + $html .= ''; + + return $html; +} + +// 캡챠 사용시 자바스크립트에서 입력된 캡챠를 검사함 +function chk_captcha_js() +{ + return "if (!chk_captcha()) return false;\n"; +} + +function chk_captcha(){ + + global $config; + + $resp = null; + + if ( isset($_POST["g-recaptcha-response"]) && !empty($_POST["g-recaptcha-response"]) ) { + + $reCaptcha = new ReCaptcha_GNU( $config['cf_recaptcha_secret_key'] ); + + $resp = $reCaptcha->verify($_POST["g-recaptcha-response"], $_SERVER["REMOTE_ADDR"]); + } + + if( ! $resp ){ + return false; + } + + if ($resp != null && $resp->success) { + return true; + } + + return false; +} +?> \ No newline at end of file diff --git a/plugin/recaptcha_inv/_common.php b/plugin/recaptcha_inv/_common.php new file mode 100644 index 000000000..bad54a5d7 --- /dev/null +++ b/plugin/recaptcha_inv/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/plugin/recaptcha_inv/captcha.lib.php b/plugin/recaptcha_inv/captcha.lib.php new file mode 100644 index 000000000..9eec82f03 --- /dev/null +++ b/plugin/recaptcha_inv/captcha.lib.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/plugin/recaptcha_inv/recaptcha.class.php b/plugin/recaptcha_inv/recaptcha.class.php new file mode 100644 index 000000000..781c13d3c --- /dev/null +++ b/plugin/recaptcha_inv/recaptcha.class.php @@ -0,0 +1,147 @@ +secret = $secret; + } + + public function get_content($url, $data=array()) { + + $curlsession = curl_init(); + curl_setopt ($curlsession, CURLOPT_URL, $url); + curl_setopt ($curlsession, CURLOPT_POST, 1); + curl_setopt ($curlsession, CURLOPT_POSTFIELDS, http_build_query($data, '', '&')); + curl_setopt ($curlsession, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); + curl_setopt ($curlsession, CURLINFO_HEADER_OUT, false); + curl_setopt ($curlsession, CURLOPT_HEADER, false); + curl_setopt ($curlsession, CURLOPT_RETURNTRANSFER, 1); + curl_setopt ($curlsession, CURLOPT_SSL_VERIFYPEER, 1); + curl_setopt ($curlsession, CURLOPT_TIMEOUT, 3); + + $response = curl_exec($curlsession); + $cinfo = curl_getinfo($curlsession); + curl_close($curlsession); + + if ($cinfo['http_code'] != 200){ + return ''; + } + return $response; + } + + /** + * Submits an HTTP GET to a reCAPTCHA server. + * + * @param string $path url path to recaptcha server. + * @param array $data array of parameters to be sent. + * + * @return array response + */ + private function submit($url, $data) + { + $response = $this->get_content($url, $data); + return $response; + } + + /** + * Calls the reCAPTCHA siteverify API to verify whether the user passes + * CAPTCHA test. + * + * @param string $remoteIp IP address of end user. + * @param string $response response string from recaptcha verification. + * + * @return ReCaptchaResponse_v + */ + public function verify($response, $remoteIp = null) + { + // Discard empty solution submissions + if ($response == null || strlen($response) == 0) { + $recaptchaResponse = new ReCaptchaResponse_v(); + $recaptchaResponse->success = false; + $recaptchaResponse->errorCodes = 'missing-input'; + return $recaptchaResponse; + } + $getResponse = $this->submit( + self::$_siteVerifyUrl, + array ( + 'secret' => $this->secret, + 'remoteip' => $remoteIp, + 'version' => self::VERSION, + 'response' => $response + ) + ); + $answers = $getResponse ? json_decode($getResponse, true) : array(); + $recaptchaResponse = new ReCaptchaResponse_v(); + if (isset($answers['success']) && $answers['success'] == true) { + $recaptchaResponse->success = true; + } else { + $recaptchaResponse->success = false; + $recaptchaResponse->errorCodes = isset($answers['error-codes']) ? $answers['error-codes'] : 'http_error'; + } + return $recaptchaResponse; + } +} +?> \ No newline at end of file diff --git a/plugin/recaptcha_inv/recaptcha.js b/plugin/recaptcha_inv/recaptcha.js new file mode 100644 index 000000000..8aac8389f --- /dev/null +++ b/plugin/recaptcha_inv/recaptcha.js @@ -0,0 +1,20 @@ +function chk_captcha() +{ + if ( ! jQuery('#g-recaptcha-response').val()) { + grecaptcha.execute(); + return false; + } + + return true; +} + +function recaptcha_validate(token) { + var $form = jQuery("#g-recaptcha-response").closest("form"), + form_id = $form.attr("id"); + + + if( $form.length ){ + $form.submit(); + } + +} diff --git a/plugin/recaptcha_inv/recaptcha.user.lib.php b/plugin/recaptcha_inv/recaptcha.user.lib.php new file mode 100644 index 000000000..cd6e6bcc4 --- /dev/null +++ b/plugin/recaptcha_inv/recaptcha.user.lib.php @@ -0,0 +1,52 @@ +'; + $html .= ''; + $html .= ''; + $html .= '
    '; + $html .= ''; + $html .= ''; + + return $html; +} + +// 캡챠 사용시 자바스크립트에서 입력된 캡챠를 검사함 +function chk_captcha_js() +{ + return "if (!chk_captcha()) return false;\n"; +} + +function chk_captcha(){ + + global $config; + + $resp = null; + + if ( isset($_POST["g-recaptcha-response"]) && !empty($_POST["g-recaptcha-response"]) ) { + + $reCaptcha = new ReCaptcha_GNU( $config['cf_recaptcha_secret_key'] ); + + $resp = $reCaptcha->verify($_POST["g-recaptcha-response"], $_SERVER["REMOTE_ADDR"]); + } + + if( ! $resp ){ + return false; + } + + if ($resp != null && $resp->success) { + return true; + } + + return false; +} +?> \ No newline at end of file diff --git a/plugin/sns/icon/facebook.png b/plugin/sns/icon/facebook.png index b9d733963..cf737d633 100644 Binary files a/plugin/sns/icon/facebook.png and b/plugin/sns/icon/facebook.png differ diff --git a/plugin/sns/icon/gplus.png b/plugin/sns/icon/gplus.png index 993cce991..8ab2fa6bc 100644 Binary files a/plugin/sns/icon/gplus.png and b/plugin/sns/icon/gplus.png differ diff --git a/plugin/sns/icon/kakaotalk.png b/plugin/sns/icon/kakaotalk.png index 78fe26ca7..07de029ef 100644 Binary files a/plugin/sns/icon/kakaotalk.png and b/plugin/sns/icon/kakaotalk.png differ diff --git a/plugin/sns/icon/twitter.png b/plugin/sns/icon/twitter.png index 9962ded1e..8fbf0914b 100644 Binary files a/plugin/sns/icon/twitter.png and b/plugin/sns/icon/twitter.png differ diff --git a/plugin/sns/view.sns.skin.php b/plugin/sns/view.sns.skin.php index aa1cc0ba4..a798cfd0e 100644 --- a/plugin/sns/view.sns.skin.php +++ b/plugin/sns/view.sns.skin.php @@ -30,12 +30,15 @@ $gplus_url = $sns_send.'&sns=gplus'; Kakao.init(""); +
    +
      -
    • 페이스북으로 보내기
    • -
    • 트위터로 보내기
    • -
    • 구글플러스로 보내기
    • +
    • 트위터로 보내기
    • +
    • 페이스북으로 보내기
    • +
    • 구글플러스로 보내기
    • -
    • 카카오톡으로 보내기
    • +
    • 카카오톡으로 보내기
    +
    diff --git a/plugin/sns/view_comment_write.sns.skin.php b/plugin/sns/view_comment_write.sns.skin.php index 75584ba35..44457ec20 100644 --- a/plugin/sns/view_comment_write.sns.skin.php +++ b/plugin/sns/view_comment_write.sns.skin.php @@ -1,7 +1,7 @@
      @@ -30,17 +30,16 @@ if ($config['cf_facebook_appid']) { } } - echo '
    • '; + echo '
    • '; if ($facebook_user) { echo ''; echo ''; echo ''; } else { $facebook_url = $facebook->getLoginUrl(array("redirect_uri"=>G5_SNS_URL."/facebook/callback.php", "scope"=>"publish_stream,read_stream,offline_access", "display"=>"popup")); - - echo ''; - echo ''; echo ''; + echo ''; + echo ''; echo ''; } echo '
    • '; @@ -90,15 +89,15 @@ if ($config['cf_twitter_key']) { } } - echo '
    • '; + echo '
    • '; if ($twitter_user) { echo ''; echo ''; echo ''; } else { - echo ''; echo ''; echo ''; + echo ''; echo ''; } echo '
    • '; diff --git a/plugin/social/Hybrid/Auth.php b/plugin/social/Hybrid/Auth.php new file mode 100644 index 000000000..5642b5091 --- /dev/null +++ b/plugin/social/Hybrid/Auth.php @@ -0,0 +1,414 @@ +getSessionData()); + Hybrid_Logger::info("Hybrid_Auth initialize: check if any error is stored on the endpoint..."); + + if (Hybrid_Error::hasError()) { + $m = Hybrid_Error::getErrorMessage(); + $c = Hybrid_Error::getErrorCode(); + $p = Hybrid_Error::getErrorPrevious(); + + Hybrid_Logger::error("Hybrid_Auth initialize: A stored Error found, Throw an new Exception and delete it from the store: Error#$c, '$m'"); + + Hybrid_Error::clearError(); + + // try to provide the previous if any + // Exception::getPrevious (PHP 5 >= 5.3.0) http://php.net/manual/en/exception.getprevious.php + if (version_compare(PHP_VERSION, '5.3.0', '>=') && ($p instanceof Exception)) { + throw new Exception($m, $c, $p); + } else { + throw new Exception($m, $c); + } + } + + Hybrid_Logger::info("Hybrid_Auth initialize: no error found. initialization succeed."); + } + + /** + * Hybrid storage system accessor + * + * Users sessions are stored using HybridAuth storage system ( HybridAuth 2.0 handle PHP Session only) and can be accessed directly by + * Hybrid_Auth::storage()->get($key) to retrieves the data for the given key, or calling + * Hybrid_Auth::storage()->set($key, $value) to store the key => $value set. + * + * @return Hybrid_Storage + */ + public static function storage() { + return Hybrid_Auth::$store; + } + + /** + * Get hybridauth session data + * @return string|null + */ + function getSessionData() { + return Hybrid_Auth::storage()->getSessionData(); + } + + /** + * Restore hybridauth session data + * + * @param string $sessiondata Serialized session data + * @retun void + */ + function restoreSessionData($sessiondata = null) { + Hybrid_Auth::storage()->restoreSessionData($sessiondata); + } + + /** + * Try to authenticate the user with a given provider. + * + * If the user is already connected we just return and instance of provider adapter, + * ELSE, try to authenticate and authorize the user with the provider. + * + * $params is generally an array with required info in order for this provider and HybridAuth to work, + * like : + * hauth_return_to: URL to call back after authentication is done + * openid_identifier: The OpenID identity provider identifier + * google_service: can be "Users" for Google user accounts service or "Apps" for Google hosted Apps + * + * @param string $providerId ID of the provider + * @param array $params Params + * @return + */ + public static function authenticate($providerId, $params = null) { + Hybrid_Logger::info("Enter Hybrid_Auth::authenticate( $providerId )"); + + if (!Hybrid_Auth::storage()->get("hauth_session.$providerId.is_logged_in")) { + // if user not connected to $providerId then try setup a new adapter and start the login process for this provider + Hybrid_Logger::info("Hybrid_Auth::authenticate( $providerId ), User not connected to the provider. Try to authenticate.."); + $provider_adapter = Hybrid_Auth::setup($providerId, $params); + $provider_adapter->login(); + } else { + // else, then return the adapter instance for the given provider + Hybrid_Logger::info("Hybrid_Auth::authenticate( $providerId ), User is already connected to this provider. Return the adapter instance."); + return Hybrid_Auth::getAdapter($providerId); + } + } + + /** + * Return the adapter instance for an authenticated provider + * + * @param string $providerId ID of the provider + * @return Hybrid_Provider_Adapter + */ + public static function getAdapter($providerId = null) { + Hybrid_Logger::info("Enter Hybrid_Auth::getAdapter( $providerId )"); + return Hybrid_Auth::setup($providerId); + } + + /** + * Setup an adapter for a given provider + * + * @param string $providerId ID of the provider + * @param array $params Adapter params + * @return Hybrid_Provider_Adapter + */ + public static function setup($providerId, $params = null) { + Hybrid_Logger::debug("Enter Hybrid_Auth::setup( $providerId )", $params); + + if (!$params) { + $params = Hybrid_Auth::storage()->get("hauth_session.$providerId.id_provider_params"); + + Hybrid_Logger::debug("Hybrid_Auth::setup( $providerId ), no params given. Trying to get the stored for this provider.", $params); + } + + if (!$params) { + $params = array(); + Hybrid_Logger::info("Hybrid_Auth::setup( $providerId ), no stored params found for this provider. Initialize a new one for new session"); + } + + if (is_array($params) && !isset($params["hauth_return_to"])) { + $params["hauth_return_to"] = Hybrid_Auth::getCurrentUrl(); + Hybrid_Logger::debug("Hybrid_Auth::setup( $providerId ). HybridAuth Callback URL set to: ", $params["hauth_return_to"]); + } + + # instantiate a new IDProvider Adapter + $provider = new Hybrid_Provider_Adapter(); + $provider->factory($providerId, $params); + return $provider; + } + + /** + * Check if the current user is connected to a given provider + * + * @param string $providerId ID of the provider + * @return bool + */ + public static function isConnectedWith($providerId) { + return (bool) Hybrid_Auth::storage()->get("hauth_session.{$providerId}.is_logged_in"); + } + + /** + * Return array listing all authenticated providers + * @return array + */ + public static function getConnectedProviders() { + $idps = array(); + + foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) { + if (Hybrid_Auth::isConnectedWith($idpid)) { + $idps[] = $idpid; + } + } + + return $idps; + } + + /** + * Return array listing all enabled providers as well as a flag if you are connected + * + * + * array( + * 'Facebook' => array( + * 'connected' => true + * ) + * ) + * + * @return array + */ + public static function getProviders() { + $idps = array(); + + foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) { + if ($params['enabled']) { + $idps[$idpid] = array('connected' => false); + + if (Hybrid_Auth::isConnectedWith($idpid)) { + $idps[$idpid]['connected'] = true; + } + } + } + + return $idps; + } + + /** + * A generic function to logout all connected provider at once + * @return void + */ + public static function logoutAllProviders() { + $idps = Hybrid_Auth::getConnectedProviders(); + + foreach ($idps as $idp) { + $adapter = Hybrid_Auth::getAdapter($idp); + $adapter->logout(); + } + } + + /** + * Utility function, redirect to a given URL with php header or using javascript location.href + * + * @param string $url URL to redirect to + * @param string $mode PHP|JS + */ + public static function redirect($url, $mode = "PHP") { + if(!$mode){ + $mode = 'PHP'; + } + Hybrid_Logger::info("Enter Hybrid_Auth::redirect( $url, $mode )"); + + // Ensure session is saved before sending response, see https://github.com/symfony/symfony/pull/12341 + if ((PHP_VERSION_ID >= 50400 && PHP_SESSION_ACTIVE === session_status()) || (PHP_VERSION_ID < 50400 && isset($_SESSION) && session_id())) { + session_write_close(); + } + + if ($mode == "PHP") { + header("Location: $url"); + } elseif ($mode == "JS") { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo 'Redirecting, please wait...'; + echo ''; + echo ''; + } + + die(); + } + + /** + * Utility function, return the current url + * + * @param bool $request_uri true to get $_SERVER['REQUEST_URI'], false for $_SERVER['PHP_SELF'] + * @return string + */ + public static function getCurrentUrl($request_uri = true) { + if (php_sapi_name() == 'cli') { + return ''; + } + + $protocol = 'http://'; + + if ((isset($_SERVER['HTTPS']) && ( $_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1 )) + || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) + { + $protocol = 'https://'; + } + + $url = $protocol . $_SERVER['HTTP_HOST']; + + if ($request_uri) { + $url .= $_SERVER['REQUEST_URI']; + } else { + $url .= $_SERVER['PHP_SELF']; + } + + // return current url + return $url; + } + +} diff --git a/plugin/social/Hybrid/Endpoint.php b/plugin/social/Hybrid/Endpoint.php new file mode 100644 index 000000000..7813fee05 --- /dev/null +++ b/plugin/social/Hybrid/Endpoint.php @@ -0,0 +1,222 @@ +here we need to parse $_SERVER[QUERY_STRING] + $request = $_REQUEST; + if (isset($_SERVER["QUERY_STRING"]) && strrpos($_SERVER["QUERY_STRING"], '?')) { + $_SERVER["QUERY_STRING"] = str_replace("?", "&", $_SERVER["QUERY_STRING"]); + parse_str($_SERVER["QUERY_STRING"], $request); + } + } + + // Setup request variable + $this->request = $request; + + // If openid_policy requested, we return our policy document + if (isset($this->request["get"]) && $this->request["get"] == "openid_policy") { + $this->processOpenidPolicy(); + } + + // If openid_xrds requested, we return our XRDS document + if (isset($this->request["get"]) && $this->request["get"] == "openid_xrds") { + $this->processOpenidXRDS(); + } + + // If we get a hauth.start + if (isset($this->request["hauth_start"]) && $this->request["hauth_start"]) { + $this->processAuthStart(); + } + // Else if hauth.done + elseif (isset($this->request["hauth_done"]) && $this->request["hauth_done"]) { + $this->processAuthDone(); + } + // Else we advertise our XRDS document, something supposed to be done from the Realm URL page + else { + $this->processOpenidRealm(); + } + } + + /** + * Process the current request + * + * @param array $request The current request parameters. Leave as null to default to use $_REQUEST. + * @return Hybrid_Endpoint + */ + public static function process($request = null) { + // Trick for PHP 5.2, because it doesn't support late static binding + $class = function_exists('get_called_class') ? get_called_class() : __CLASS__; + new $class($request); + } + + /** + * Process OpenID policy request + * @return void + */ + protected function processOpenidPolicy() { + $output = file_get_contents(dirname(__FILE__) . "/resources/openid_policy.html"); + print $output; + die(); + } + + /** + * Process OpenID XRDS request + * @return void + */ + protected function processOpenidXRDS() { + header("Content-Type: application/xrds+xml"); + + $output = str_replace("{RETURN_TO_URL}", str_replace( + array("<", ">", "\"", "'", "&"), array("<", ">", """, "'", "&"), Hybrid_Auth::getCurrentUrl(false) + ), file_get_contents(dirname(__FILE__) . "/resources/openid_xrds.xml")); + print $output; + die(); + } + + /** + * Process OpenID realm request + * @return void + */ + protected function processOpenidRealm() { + $output = str_replace("{X_XRDS_LOCATION}", htmlentities(Hybrid_Auth::getCurrentUrl(false), ENT_QUOTES, 'UTF-8') + . "?get=openid_xrds&v=" + . Hybrid_Auth::$version, file_get_contents(dirname(__FILE__) . "/resources/openid_realm.html")); + print $output; + die(); + } + + /** + * Define: endpoint step 3 + * @return void + * @throws Hybrid_Exception + */ + protected function processAuthStart() { + $this->authInit(); + + $provider_id = trim(strip_tags($this->request["hauth_start"])); + + // check if page accessed directly + if (!Hybrid_Auth::storage()->get("hauth_session.$provider_id.hauth_endpoint")) { + Hybrid_Logger::error("Endpoint: hauth_endpoint parameter is not defined on hauth_start, halt login process!"); + + throw new Hybrid_Exception("You cannot access this page directly."); + } + + // define:hybrid.endpoint.php step 2. + $hauth = Hybrid_Auth::setup($provider_id); + + // if REQUESTed hauth_idprovider is wrong, session not created, etc. + if (!$hauth) { + Hybrid_Logger::error("Endpoint: Invalid parameter on hauth_start!"); + throw new Hybrid_Exception("Invalid parameter! Please return to the login page and try again."); + } + + try { + Hybrid_Logger::info("Endpoint: call adapter [{$provider_id}] loginBegin()"); + + $hauth->adapter->loginBegin(); + } catch (Exception $e) { + Hybrid_Logger::error("Exception:" . $e->getMessage(), $e); + Hybrid_Error::setError($e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e->getPrevious()); + + $hauth->returnToCallbackUrl(); + } + + die(); + } + + /** + * Define: endpoint step 3.1 and 3.2 + * @return void + * @throws Hybrid_Exception + */ + protected function processAuthDone() { + $this->authInit(); + + $provider_id = trim(strip_tags($this->request["hauth_done"])); + + $hauth = Hybrid_Auth::setup($provider_id); + + if (!$hauth) { + Hybrid_Logger::error("Endpoint: Invalid parameter on hauth_done!"); + + $hauth->adapter->setUserUnconnected(); + + throw new Hybrid_Exception("Invalid parameter! Please return to the login page and try again."); + } + + try { + Hybrid_Logger::info("Endpoint: call adapter [{$provider_id}] loginFinish() "); + $hauth->adapter->loginFinish(); + } catch (Exception $e) { + Hybrid_Logger::error("Exception:" . $e->getMessage(), $e); + Hybrid_Error::setError($e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e->getPrevious()); + + $hauth->adapter->setUserUnconnected(); + } + + Hybrid_Logger::info("Endpoint: job done. return to callback url."); + + $hauth->returnToCallbackUrl(); + die(); + } + + /** + * Initializes authentication + * @throws Hybrid_Exception + */ + protected function authInit() { + if (!$this->initDone) { + $this->initDone = true; + + // Init Hybrid_Auth + try { + if (!class_exists("Hybrid_Storage", false)) { + require_once realpath(dirname(__FILE__)) . "/Storage.php"; + } + if (!class_exists("Hybrid_Exception", false)) { + require_once realpath(dirname(__FILE__)) . "/Exception.php"; + } + if (!class_exists("Hybrid_Logger", false)) { + require_once realpath(dirname(__FILE__)) . "/Logger.php"; + } + + $storage = new Hybrid_Storage(); + + // Check if Hybrid_Auth session already exist + if (!$storage->config("CONFIG")) { + throw new Hybrid_Exception("You cannot access this page directly."); + } + + Hybrid_Auth::initialize($storage->config("CONFIG")); + } catch (Exception $e) { + Hybrid_Logger::error("Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage()); + throw new Hybrid_Exception( "Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage(), $e->getCode(), $e ); + } + } + } + +} diff --git a/plugin/social/Hybrid/Error.php b/plugin/social/Hybrid/Error.php new file mode 100644 index 000000000..e9c319c68 --- /dev/null +++ b/plugin/social/Hybrid/Error.php @@ -0,0 +1,88 @@ +set("hauth_session.error.status", 1); + Hybrid_Auth::storage()->set("hauth_session.error.message", $message); + Hybrid_Auth::storage()->set("hauth_session.error.code", $code); + Hybrid_Auth::storage()->set("hauth_session.error.trace", $trace); + Hybrid_Auth::storage()->set("hauth_session.error.previous", $previous); + } + + /** + * Clear the last error + * @return void + */ + public static function clearError() { + Hybrid_Logger::info("Enter Hybrid_Error::clearError()"); + + Hybrid_Auth::storage()->delete("hauth_session.error.status"); + Hybrid_Auth::storage()->delete("hauth_session.error.message"); + Hybrid_Auth::storage()->delete("hauth_session.error.code"); + Hybrid_Auth::storage()->delete("hauth_session.error.trace"); + Hybrid_Auth::storage()->delete("hauth_session.error.previous"); + } + + /** + * Checks to see if there is a an error. + * @return boolean true if there is an error. + */ + public static function hasError() { + return (bool) Hybrid_Auth::storage()->get("hauth_session.error.status"); + } + + /** + * Return error message + * @return string + */ + public static function getErrorMessage() { + return Hybrid_Auth::storage()->get("hauth_session.error.message"); + } + + /** + * Return error code + * @return int + */ + public static function getErrorCode() { + return Hybrid_Auth::storage()->get("hauth_session.error.code"); + } + + /** + * Return string detailed error backtrace as string + * @return string + */ + public static function getErrorTrace() { + return Hybrid_Auth::storage()->get("hauth_session.error.trace"); + } + + /** + * Detailed error backtrace as string + * @return string + */ + public static function getErrorPrevious() { + return Hybrid_Auth::storage()->get("hauth_session.error.previous"); + } + +} diff --git a/plugin/social/Hybrid/Exception.php b/plugin/social/Hybrid/Exception.php new file mode 100644 index 000000000..8c8c2d1fa --- /dev/null +++ b/plugin/social/Hybrid/Exception.php @@ -0,0 +1,17 @@ +format(DATE_ATOM), + $message, + print_r($object, true) . PHP_EOL, + )), FILE_APPEND + ); + } + } + + /** + * Logs an info message + * + * @param string $message Info message + * @return void + */ + public static function info($message) { + if (in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info'), true)) { + $dt = new DateTime('now', new DateTimeZone( 'UTC' )); + file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array( + "INFO", + $_SERVER['REMOTE_ADDR'], + $dt->format(DATE_ATOM), + $message . PHP_EOL, + )), FILE_APPEND); + } + } + + /** + * Logs an error message with an object dump + * + * @param string $message Error message + * @param stdClass $object Object being debugged + * @return void + */ + public static function error($message, $object = null) { + if (isset(Hybrid_Auth::$config["debug_mode"]) && in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info', 'error'), true)) { + $dt = new DateTime('now', new DateTimeZone( 'UTC' )); + file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array( + 'ERROR', + $_SERVER['REMOTE_ADDR'], + $dt->format(DATE_ATOM), + $message, + print_r($object, true) . PHP_EOL + )), FILE_APPEND); + } + } + + /** + * Dumps the data in the way suitable to be output in log files for debug purposes + * + * @param mixed $data + * + * @return string + */ + public static function dumpData($data) { + return var_export($data, true); + } + +} diff --git a/plugin/social/Hybrid/Provider_Adapter.php b/plugin/social/Hybrid/Provider_Adapter.php new file mode 100644 index 000000000..aeeb30bb2 --- /dev/null +++ b/plugin/social/Hybrid/Provider_Adapter.php @@ -0,0 +1,340 @@ +id = $id; + $this->params = $params; + $this->id = $this->getProviderCiId($this->id); + $this->config = $this->getConfigById($this->id); + + # check the IDp id + if (!$this->id) { + throw new Exception("No provider ID specified.", 2); + } + + # check the IDp config + if (!$this->config) { + throw new Exception("Unknown Provider ID, check your configuration file.", 3); + } + + # check the IDp adapter is enabled + if (!$this->config["enabled"]) { + throw new Exception("The provider '{$this->id}' is not enabled.", 3); + } + + # include the adapter wrapper + if (isset($this->config["wrapper"]) && is_array($this->config["wrapper"])) { + if (isset($this->config["wrapper"]["path"])) { + require_once $this->config["wrapper"]["path"]; + } + + if (!class_exists($this->config["wrapper"]["class"])) { + throw new Exception("Unable to load the adapter class.", 3); + } + + $this->wrapper = $this->config["wrapper"]["class"]; + } else { + require_once Hybrid_Auth::$config["path_providers"] . $this->id . ".php"; + + $this->wrapper = "Hybrid_Providers_" . $this->id; + } + + # create the adapter instance, and pass the current params and config + $this->adapter = new $this->wrapper($this->id, $this->config, $this->params); + + return $this; + } + + /** + * Hybrid_Provider_Adapter::login(), prepare the user session and the authentication request + * for index.php + * @return void + * @throw Exception + */ + function login() { + Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::login( {$this->id} ) "); + + if (!$this->adapter) { + throw new Exception("Hybrid_Provider_Adapter::login() should not directly used."); + } + + // clear all unneeded params + foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) { + Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.hauth_return_to"); + Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.hauth_endpoint"); + Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.id_provider_params"); + } + + // make a fresh start + $this->logout(); + + # get hybridauth base url + if (empty(Hybrid_Auth::$config["base_url"])) { + // the base url wasn't provide, so we must use the current + // url (which makes sense actually) + $url = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off' ? 'http' : 'https'; + $url .= '://' . $_SERVER['HTTP_HOST']; + $url .= $_SERVER['REQUEST_URI']; + $HYBRID_AUTH_URL_BASE = $url; + } else { + $HYBRID_AUTH_URL_BASE = Hybrid_Auth::$config["base_url"]; + } + + // make sure params is array + if (!is_array($this->params)) { + $this->params = array(); + } + + # we make use of session_id() as storage hash to identify the current user + # using session_regenerate_id() will be a problem, but .. + $this->params["hauth_token"] = session_id(); + + # set request timestamp + $this->params["hauth_time"] = time(); + + # for default HybridAuth endpoint url hauth_login_start_url + # auth.start required the IDp ID + # auth.time optional login request timestamp + if (!isset($this->params["login_start"]) ) { + $this->params["login_start"] = $HYBRID_AUTH_URL_BASE . ( strpos($HYBRID_AUTH_URL_BASE, '?') ? '&' : '?' ) . "hauth.start={$this->id}&hauth.time={$this->params["hauth_time"]}"; + } + + # for default HybridAuth endpoint url hauth_login_done_url + # auth.done required the IDp ID + if (!isset($this->params["login_done"]) ) { + $this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos($HYBRID_AUTH_URL_BASE, '?') ? '&' : '?' ) . "hauth.done={$this->id}"; + } + + # workaround to solve windows live authentication since microsoft disallowed redirect urls to contain any parameters + # http://mywebsite.com/path_to_hybridauth/?hauth.done=Live will not work + if ($this->id=="Live") { + $this->params["login_done"] = $HYBRID_AUTH_URL_BASE."live.php"; + } + + # Workaround to fix broken callback urls for the Facebook OAuth client + if ($this->adapter->useSafeUrls) { + $this->params['login_done'] = str_replace('hauth.done', 'hauth_done', $this->params['login_done']); + } + + if (isset($this->params["hauth_return_to"])) { + Hybrid_Auth::storage()->set("hauth_session.{$this->id}.hauth_return_to", $this->params["hauth_return_to"]); + } + if (isset($this->params["login_done"])) { + Hybrid_Auth::storage()->set("hauth_session.{$this->id}.hauth_endpoint", $this->params["login_done"]); + } + Hybrid_Auth::storage()->set("hauth_session.{$this->id}.id_provider_params", $this->params); + + // store config to be used by the end point + Hybrid_Auth::storage()->config("CONFIG", Hybrid_Auth::$config); + + // move on + Hybrid_Logger::debug("Hybrid_Provider_Adapter::login( {$this->id} ), redirect the user to login_start URL."); + + // redirect + if (empty($this->params["redirect_mode"])) { + Hybrid_Auth::redirect($this->params["login_start"]); + } else { + Hybrid_Auth::redirect($this->params["login_start"],$this->params["redirect_mode"]); + } + } + + /** + * Let hybridauth forget all about the user for the current provider + * @return bool + */ + function logout() { + $this->adapter->logout(); + } + + // -------------------------------------------------------------------- + + /** + * Return true if the user is connected to the current provider + * @return bool + */ + public function isUserConnected() { + return $this->adapter->isUserConnected(); + } + + // -------------------------------------------------------------------- + + /** + * Call adapter methods defined in the adapter model: + * getUserProfile() + * getUserContacts() + * getUserActivity() + * setUserStatus() + * + * @param string $name Method name + * @param array $arguments Call arguments + * @return mixed + * @throws Exception + */ + public function __call($name, $arguments) { + Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::$name(), Provider: {$this->id}"); + + if (!$this->isUserConnected()) { + throw new Exception("User not connected to the provider {$this->id}.", 7); + } + + if (!method_exists($this->adapter, $name)) { + throw new Exception("Call to undefined function Hybrid_Providers_{$this->id}::$name()."); + } + + return call_user_func_array(array($this->adapter, $name), $arguments); + } + + /** + * If the user is connected, then return the access_token and access_token_secret + * if the provider api use oauth + * + * + * array( + * 'access_token' => '', + * 'access_token_secret' => '', + * 'refresh_token' => '', + * 'expires_in' => '', + * 'expires_at' => '', + * ) + * + * @return array + */ + public function getAccessToken() { + if (!$this->adapter->isUserConnected()) { + Hybrid_Logger::error("User not connected to the provider."); + throw new Exception("User not connected to the provider.", 7); + } + + return array( + "access_token" => $this->adapter->token("access_token"), // OAuth access token + "access_token_secret" => $this->adapter->token("access_token_secret"), // OAuth access token secret + "refresh_token" => $this->adapter->token("refresh_token"), // OAuth refresh token + "expires_in" => $this->adapter->token("expires_in"), // OPTIONAL. The duration in seconds of the access token lifetime + "expires_at" => $this->adapter->token("expires_at"), // OPTIONAL. Timestamp when the access_token expire. if not provided by the social api, then it should be calculated: expires_at = now + expires_in + ); + } + + /** + * Naive getter of the current connected IDp API client + * @return stdClass + * @throws Exception + */ + function api() { + if (!$this->adapter->isUserConnected()) { + Hybrid_Logger::error("User not connected to the provider."); + + throw new Exception("User not connected to the provider.", 7); + } + return $this->adapter->api; + } + + /** + * Redirect the user to hauth_return_to (the callback url) + * @return void + */ + function returnToCallbackUrl() { + // get the stored callback url + $callback_url = Hybrid_Auth::storage()->get("hauth_session.{$this->id}.hauth_return_to"); + + // if the user presses the back button in the browser and we already deleted the hauth_return_to from + // the session in the previous request, we will redirect to '/' instead of displaying a blank page. + if (!$callback_url) { + $callback_url = '/'; + } + + // remove some unneeded stored data + Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.hauth_return_to"); + Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.hauth_endpoint"); + Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.id_provider_params"); + + // back to home + Hybrid_Auth::redirect($callback_url); + } + + /** + * Return the provider config by id + * + * @param string $id Config key + * @return mixed + */ + function getConfigById($id) { + if (isset(Hybrid_Auth::$config["providers"][$id])) { + return Hybrid_Auth::$config["providers"][$id]; + } + return null; + } + + /** + * Return the provider config by id; case insensitive + * + * @param string $id Provider id + * @return mixed + */ + function getProviderCiId($id) { + foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) { + if (strtolower($idpid) == strtolower($id)) { + return $idpid; + } + } + return null; + } + +} diff --git a/plugin/social/Hybrid/Provider_Model.php b/plugin/social/Hybrid/Provider_Model.php new file mode 100644 index 000000000..320cee9e1 --- /dev/null +++ b/plugin/social/Hybrid/Provider_Model.php @@ -0,0 +1,247 @@ +params = Hybrid_Auth::storage()->get("hauth_session.$providerId.id_provider_params"); + } else { + $this->params = $params; + } + + // idp id + $this->providerId = $providerId; + + // set HybridAuth endpoint for this provider + $this->endpoint = Hybrid_Auth::storage()->get("hauth_session.$providerId.hauth_endpoint"); + + // idp config + $this->config = $config; + + // new user instance + $this->user = new Hybrid_User(); + $this->user->providerId = $providerId; + + // initialize the current provider adapter + $this->initialize(); + + Hybrid_Logger::debug("Hybrid_Provider_Model::__construct( $providerId ) initialized. dump current adapter instance: ", serialize($this)); + } + + /** + * IDp wrappers initializer + * + * The main job of wrappers initializer is to performs (depend on the IDp api client it self): + * - include some libs needed by this provider, + * - check IDp key and secret, + * - set some needed parameters (stored in $this->params) by this IDp api client + * - create and setup an instance of the IDp api client on $this->api + * + * @return void + * @throws Exception + */ + abstract protected function initialize(); + + /** + * Begin login + * + * @return void + * @throws Exception + */ + abstract public function loginBegin(); + + /** + * Finish login + * @return void + * @throws Exception + */ + abstract public function loginFinish(); + + /** + * Generic logout, just erase current provider adapter stored data to let Hybrid_Auth all forget about it + * @return bool + */ + function logout() { + Hybrid_Logger::info("Enter [{$this->providerId}]::logout()"); + $this->clearTokens(); + return true; + } + + /** + * Grab the user profile from the IDp api client + * @return Hybrid_User_Profile + * @throws Exception + */ + function getUserProfile() { + Hybrid_Logger::error("HybridAuth do not provide users contacts list for {$this->providerId} yet."); + throw new Exception("Provider does not support this feature.", 8); + } + + /** + * Load the current logged in user contacts list from the IDp api client + * @return Hybrid_User_Contact[] + * @throws Exception + */ + function getUserContacts() { + Hybrid_Logger::error("HybridAuth do not provide users contacts list for {$this->providerId} yet."); + throw new Exception("Provider does not support this feature.", 8); + } + + /** + * Return the user activity stream + * @return Hybrid_User_Activity[] + * @throws Exception + */ + function getUserActivity($stream) { + Hybrid_Logger::error("HybridAuth do not provide user's activity stream for {$this->providerId} yet."); + throw new Exception("Provider does not support this feature.", 8); + } + + /** + * Set user status + * @return mixed Provider response + * @throws Exception + */ + function setUserStatus($status) { + Hybrid_Logger::error("HybridAuth do not provide user's activity stream for {$this->providerId} yet."); + throw new Exception("Provider does not support this feature.", 8); + } + + /** + * Return the user status + * @return mixed Provider response + * @throws Exception + */ + function getUserStatus($statusid) { + Hybrid_Logger::error("HybridAuth do not provide user's status for {$this->providerId} yet."); + throw new Exception("Provider does not support this feature.", 8); + } + + /** + * Return true if the user is connected to the current provider + * @return bool + */ + public function isUserConnected() { + return (bool) Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.is_logged_in"); + } + + /** + * Set user to connected + * @return void + */ + public function setUserConnected() { + Hybrid_Logger::info("Enter [{$this->providerId}]::setUserConnected()"); + Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.is_logged_in", 1); + } + + /** + * Set user to unconnected + * @return void + */ + public function setUserUnconnected() { + Hybrid_Logger::info("Enter [{$this->providerId}]::setUserUnconnected()"); + Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.is_logged_in", 0); + } + + /** + * Get or set a token + * @return string + */ + public function token($token, $value = null) { + if ($value === null) { + return Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.token.$token"); + } else { + Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.token.$token", $value); + } + } + + /** + * Delete a stored token + * @return void + */ + public function deleteToken($token) { + Hybrid_Auth::storage()->delete("hauth_session.{$this->providerId}.token.$token"); + } + + /** + * Clear all existent tokens for this provider + * @return void + */ + public function clearTokens() { + Hybrid_Auth::storage()->deleteMatch("hauth_session.{$this->providerId}."); + } + +} diff --git a/plugin/social/Hybrid/Provider_Model_OAuth1.php b/plugin/social/Hybrid/Provider_Model_OAuth1.php new file mode 100644 index 000000000..6f5f239ae --- /dev/null +++ b/plugin/social/Hybrid/Provider_Model_OAuth1.php @@ -0,0 +1,174 @@ + "OK: Success!", + 304 => "Not Modified: There was no new data to return.", + 400 => "Bad Request: The request was invalid.", + 401 => "Unauthorized.", + 403 => "Forbidden: The request is understood, but it has been refused.", + 404 => "Not Found: The URI requested is invalid or the resource requested does not exists.", + 406 => "Not Acceptable.", + 500 => "Internal Server Error: Something is broken.", + 502 => "Bad Gateway.", + 503 => "Service Unavailable." + ); + + if (!$code && $this->api) { + $code = $this->api->http_code; + } + + if (isset($http_status_codes[$code])) { + return $code . " " . $http_status_codes[$code]; + } + } + + /** + * {@inheritdoc} + */ + function initialize() { + // 1 - check application credentials + if (!$this->config["keys"]["key"] || !$this->config["keys"]["secret"]) { + throw new Exception("Your application key and secret are required in order to connect to {$this->providerId}.", 4); + } + + // 2 - include OAuth lib and client + if (! class_exists('OAuthConsumer') ) { + require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth.php"; + } + require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth1Client.php"; + + // 3.1 - setup access_token if any stored + if ($this->token("access_token")) { + $this->api = new OAuth1Client( + $this->config["keys"]["key"], $this->config["keys"]["secret"], $this->token("access_token"), $this->token("access_token_secret") + ); + } + + // 3.2 - setup request_token if any stored, in order to exchange with an access token + elseif ($this->token("request_token")) { + $this->api = new OAuth1Client( + $this->config["keys"]["key"], $this->config["keys"]["secret"], $this->token("request_token"), $this->token("request_token_secret") + ); + } + + // 3.3 - instanciate OAuth client with client credentials + else { + $this->api = new OAuth1Client($this->config["keys"]["key"], $this->config["keys"]["secret"]); + } + + // Set curl proxy if exist + if (isset(Hybrid_Auth::$config["proxy"])) { + $this->api->curl_proxy = Hybrid_Auth::$config["proxy"]; + } + } + + /** + * {@inheritdoc} + */ + function loginBegin() { + $tokens = $this->api->requestToken($this->endpoint); + + // request tokens as received from provider + $this->request_tokens_raw = $tokens; + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5); + } + + if (!isset($tokens["oauth_token"])) { + throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth token.", 5); + } + + $this->token("request_token", $tokens["oauth_token"]); + $this->token("request_token_secret", $tokens["oauth_token_secret"]); + + # redirect the user to the provider authentication url + Hybrid_Auth::redirect($this->api->authorizeUrl($tokens)); + } + + /** + * {@inheritdoc} + */ + function loginFinish() { + $oauth_token = (array_key_exists('oauth_token', $_REQUEST)) ? $_REQUEST['oauth_token'] : ""; + $oauth_verifier = (array_key_exists('oauth_verifier', $_REQUEST)) ? $_REQUEST['oauth_verifier'] : ""; + + if (!$oauth_token || !$oauth_verifier) { + throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth verifier.", 5); + } + + // request an access token + $tokens = $this->api->accessToken($oauth_verifier); + + // access tokens as received from provider + $this->access_tokens_raw = $tokens; + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5); + } + + // we should have an access_token, or else, something has gone wrong + if (!isset($tokens["oauth_token"])) { + throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5); + } + + // we no more need to store request tokens + $this->deleteToken("request_token"); + $this->deleteToken("request_token_secret"); + + // store access_token for later user + $this->token("access_token", $tokens['oauth_token']); + $this->token("access_token_secret", $tokens['oauth_token_secret']); + + // set user as logged in to the current provider + $this->setUserConnected(); + } + +} diff --git a/plugin/social/Hybrid/Provider_Model_OAuth2.php b/plugin/social/Hybrid/Provider_Model_OAuth2.php new file mode 100644 index 000000000..17a2103bd --- /dev/null +++ b/plugin/social/Hybrid/Provider_Model_OAuth2.php @@ -0,0 +1,184 @@ + "OK: Success!", + 304 => "Not Modified: There was no new data to return.", + 400 => "Bad Request: The request was invalid.", + 401 => "Unauthorized.", + 403 => "Forbidden: The request is understood, but it has been refused.", + 404 => "Not Found: The URI requested is invalid or the resource requested does not exists.", + 406 => "Not Acceptable.", + 500 => "Internal Server Error: Something is broken.", + 502 => "Bad Gateway.", + 503 => "Service Unavailable." + ); + + if (!$code && $this->api) { + $code = $this->api->http_code; + } + + if (isset($http_status_codes[$code])) { + return $code . " " . $http_status_codes[$code]; + } + } + + /** + * Adapter initializer + */ + function initialize() { + if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) { + throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4); + } + + // override requested scope + if (isset($this->config["scope"]) && !empty($this->config["scope"])) { + $this->scope = $this->config["scope"]; + } + + // include OAuth2 client + require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth2Client.php"; + + // create a new OAuth2 client instance + $this->api = new OAuth2Client($this->config["keys"]["id"], $this->config["keys"]["secret"], $this->endpoint, $this->compressed); + + // If we have an access token, set it + if ($this->token("access_token")) { + $this->api->access_token = $this->token("access_token"); + $this->api->refresh_token = $this->token("refresh_token"); + $this->api->access_token_expires_in = $this->token("expires_in"); + $this->api->access_token_expires_at = $this->token("expires_at"); + } + + // Set curl proxy if exist + if (isset(Hybrid_Auth::$config["proxy"])) { + $this->api->curl_proxy = Hybrid_Auth::$config["proxy"]; + } + } + + /** + * {@inheritdoc} + */ + function loginBegin() { + // redirect the user to the provider authentication url + Hybrid_Auth::redirect($this->api->authorizeUrl(array("scope" => $this->scope))); + } + + /** + * {@inheritdoc} + */ + function loginFinish() { + $error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : ""; + + // check for errors + if ($error) { + throw new Exception("Authentication failed! {$this->providerId} returned an error: $error", 5); + } + + // try to authenticate user + $code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : ""; + + try { + $this->api->authenticate($code); + } catch (Exception $e) { + throw new Exception("User profile request failed! {$this->providerId} returned an error: " . $e->getMessage(), 6); + } + + // check if authenticated + if (!$this->api->access_token) { + throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5); + } + + // store tokens + $this->token("access_token", $this->api->access_token); + $this->token("refresh_token", $this->api->refresh_token); + $this->token("expires_in", $this->api->access_token_expires_in); + $this->token("expires_at", $this->api->access_token_expires_at); + + // set user connected locally + $this->setUserConnected(); + } + + /** + * {@inheritdoc} + */ + function refreshToken() { + // have an access token? + if ($this->api->access_token) { + + // have to refresh? + if ($this->api->refresh_token && $this->api->access_token_expires_at) { + + // expired? + if ($this->api->access_token_expires_at <= time()) { + $response = $this->api->refreshToken(array("refresh_token" => $this->api->refresh_token)); + + if (!isset($response->access_token) || !$response->access_token) { + // set the user as disconnected at this point and throw an exception + $this->setUserUnconnected(); + + throw new Exception("The Authorization Service has return an invalid response while requesting a new access token. " . (string) $response->error); + } + + // set new access_token + $this->api->access_token = $response->access_token; + + if (isset($response->refresh_token)) + $this->api->refresh_token = $response->refresh_token; + + if (isset($response->expires_in)) { + $this->api->access_token_expires_in = $response->expires_in; + + // even given by some idp, we should calculate this + $this->api->access_token_expires_at = time() + $response->expires_in; + } + } + } + + // re store tokens + $this->token("access_token", $this->api->access_token); + $this->token("refresh_token", $this->api->refresh_token); + $this->token("expires_in", $this->api->access_token_expires_in); + $this->token("expires_at", $this->api->access_token_expires_at); + } + } + +} diff --git a/plugin/social/Hybrid/Provider_Model_OpenID.php b/plugin/social/Hybrid/Provider_Model_OpenID.php new file mode 100644 index 000000000..d3ec7cab5 --- /dev/null +++ b/plugin/social/Hybrid/Provider_Model_OpenID.php @@ -0,0 +1,170 @@ +public $openidIdentifier = ""; + * + * Hybrid_Provider_Model_OpenID use LightOpenID lib which can be found on + * Hybrid/thirdparty/OpenID/LightOpenID.php + */ +class Hybrid_Provider_Model_OpenID extends Hybrid_Provider_Model { + + /** + * Provider API client + * @var LightOpenID + */ + public $api = null; + + /** + * Openid provider identifier + * @var string + */ + public $openidIdentifier = ""; + + /** + * {@inheritdoc} + */ + function initialize() { + if (isset($this->params["openid_identifier"])) { + $this->openidIdentifier = $this->params["openid_identifier"]; + } + + // include LightOpenID lib + require_once Hybrid_Auth::$config["path_libraries"] . "OpenID/LightOpenID.php"; + + // An error was occurring when proxy wasn't set. Not sure where proxy was meant to be set/initialized. + Hybrid_Auth::$config['proxy'] = isset(Hybrid_Auth::$config['proxy']) ? Hybrid_Auth::$config['proxy'] : ''; + + $hostPort = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_PORT); + $hostUrl = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_HOST); + + // Check for port on url + if ($hostPort) { + $hostUrl .= ':' . $hostPort; + } + + $this->api = new LightOpenID($hostUrl, Hybrid_Auth::$config["proxy"]); + } + + /** + * {@inheritdoc} + */ + function loginBegin() { + if (empty($this->openidIdentifier)) { + throw new Exception("OpenID adapter require the identity provider identifier 'openid_identifier' as an extra parameter.", 4); + } + + $this->api->identity = $this->openidIdentifier; + $this->api->returnUrl = $this->endpoint; + $this->api->required = array( + 'namePerson/first', + 'namePerson/last', + 'namePerson/friendly', + 'namePerson', + 'contact/email', + 'birthDate', + 'birthDate/birthDay', + 'birthDate/birthMonth', + 'birthDate/birthYear', + 'person/gender', + 'pref/language', + 'contact/postalCode/home', + 'contact/city/home', + 'contact/country/home', + 'media/image/default', + ); + + # redirect the user to the provider authentication url + Hybrid_Auth::redirect($this->api->authUrl()); + } + + /** + * {@inheritdoc} + */ + function loginFinish() { + # if user don't grant access of their data to your site, halt with an Exception + if ($this->api->mode == 'cancel') { + throw new Exception("Authentication failed! User has canceled authentication!", 5); + } + + # if something goes wrong + if (!$this->api->validate()) { + throw new Exception("Authentication failed. Invalid request received!", 5); + } + + # fetch received user data + $response = $this->api->getAttributes(); + + # store the user profile + $this->user->profile->identifier = $this->api->identity; + + $this->user->profile->firstName = (array_key_exists("namePerson/first", $response)) ? $response["namePerson/first"] : ""; + $this->user->profile->lastName = (array_key_exists("namePerson/last", $response)) ? $response["namePerson/last"] : ""; + $this->user->profile->displayName = (array_key_exists("namePerson", $response)) ? $response["namePerson"] : ""; + $this->user->profile->email = (array_key_exists("contact/email", $response)) ? $response["contact/email"] : ""; + $this->user->profile->language = (array_key_exists("pref/language", $response)) ? $response["pref/language"] : ""; + $this->user->profile->country = (array_key_exists("contact/country/home", $response)) ? $response["contact/country/home"] : ""; + $this->user->profile->zip = (array_key_exists("contact/postalCode/home", $response)) ? $response["contact/postalCode/home"] : ""; + $this->user->profile->gender = (array_key_exists("person/gender", $response)) ? $response["person/gender"] : ""; + $this->user->profile->photoURL = (array_key_exists("media/image/default", $response)) ? $response["media/image/default"] : ""; + + $this->user->profile->birthDay = (array_key_exists("birthDate/birthDay", $response)) ? $response["birthDate/birthDay"] : ""; + $this->user->profile->birthMonth = (array_key_exists("birthDate/birthMonth", $response)) ? $response["birthDate/birthMonth"] : ""; + $this->user->profile->birthYear = (array_key_exists("birthDate/birthDate", $response)) ? $response["birthDate/birthDate"] : ""; + + if (isset($response['namePerson/friendly']) && !empty($response['namePerson/friendly']) && !$this->user->profile->displayName) { + $this->user->profile->displayName = $response["namePerson/friendly"]; + } + + if (isset($response['birthDate']) && !empty($response['birthDate']) && !$this->user->profile->birthDay) { + list( $birthday_year, $birthday_month, $birthday_day ) = $response['birthDate']; + + $this->user->profile->birthDay = (int) $birthday_day; + $this->user->profile->birthMonth = (int) $birthday_month; + $this->user->profile->birthYear = (int) $birthday_year; + } + + if (!$this->user->profile->displayName) { + $this->user->profile->displayName = trim($this->user->profile->firstName . " " . $this->user->profile->lastName); + } + + if ($this->user->profile->gender == "f") { + $this->user->profile->gender = "female"; + } + + if ($this->user->profile->gender == "m") { + $this->user->profile->gender = "male"; + } + + // set user as logged in + $this->setUserConnected(); + + // with openid providers we get the user profile only once, so store it + Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.user", $this->user); + } + + /** + * {@inheritdoc} + */ + function getUserProfile() { + // try to get the user profile from stored data + $this->user = Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.user"); + + // if not found + if (!is_object($this->user)) { + throw new Exception("User profile request failed! User is not connected to {$this->providerId} or his session has expired.", 6); + } + + return $this->user->profile; + } + +} diff --git a/plugin/social/Hybrid/Providers/Facebook.php b/plugin/social/Hybrid/Providers/Facebook.php new file mode 100644 index 000000000..d71d68a9b --- /dev/null +++ b/plugin/social/Hybrid/Providers/Facebook.php @@ -0,0 +1,335 @@ +api->api_base_url = 'https://graph.facebook.com/'; + $this->api->authorize_url = 'https://www.facebook.com/dialog/oauth'; + $this->api->token_url = 'https://graph.facebook.com/v2.3/oauth/access_token'; + $this->api->token_debug = 'https://graph.facebook.com/debug_token'; + + if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) { + throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4); + } + + // redirect uri mismatches when authenticating with Facebook. + if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) { + $this->api->redirect_uri = $this->config['redirect_uri']; + } + } + /** + * {@inheritdoc} + */ + function loginBegin() { + + $token = md5(uniqid(mt_rand(), true)); + Hybrid_Auth::storage()->set('fb_auth_nonce', $token); + + $parameters = array( + "response_type" => "code", + "client_id" => $this->api->client_id, + "redirect_uri" => $this->api->redirect_uri, + "state" => $token, + "scope" => $this->scope, + ); + + Hybrid_Auth::redirect($this->api->authorizeUrl($parameters)); + } + /** + * {@inheritdoc} + */ + function loginFinish() { + + // in case we get error_reason=user_denied&error=access_denied + if (isset($_REQUEST['error']) && $_REQUEST['error'] == "access_denied") { + throw new Exception("Authentication failed! The user denied your request.", 5); + } + + // try to authenicate user + $code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : ""; + try{ + $response = $this->api->authenticate( $code ); + } + catch( Exception $e ){ + throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 ); + } + + // check if authenticated + if ( ! $this->api->authenticated() ){ + throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 ); + } + // store tokens + $this->token("access_token", $this->api->access_token); + $this->token("refresh_token", $this->api->refresh_token); + $this->token("expires_in", $this->api->access_token_expires_in); + $this->token("expires_at", $this->api->access_token_expires_at); + // set user connected locally + $this->setUserConnected(); + + } + + + /** + * {@inheritdoc} + */ + function logout() { + parent::logout(); + } + /** + * {@inheritdoc} + */ + function getUserProfile() { + // request user profile from fb api + try { + $fields = array( + 'id', 'name', 'first_name', 'last_name', 'link', 'website', + 'gender', 'locale', 'about', 'email', 'hometown', 'location', + 'birthday' + ); + $data = $this->api->api('/me?fields=' . implode(',', $fields).'&access_token='.$this->token('access_token')); + } catch (Exception $e) { + $this->logout(); + throw new Exception("User profile request failed! {$this->providerId} returned an error: {$e->getMessage()}", 6, $e); + } + + if( is_object($data) ){ + $data = json_decode(json_encode($data), true); + } + + // if the provider identifier is not received, we assume the auth has failed + if (!isset($data["id"])) { + $this->logout(); + throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $data ), 6); + } + # store the user profile. + $this->user->profile->identifier = (array_key_exists('id', $data)) ? $data['id'] : ""; + $this->user->profile->username = (array_key_exists('username', $data)) ? $data['username'] : ""; + $this->user->profile->displayName = (array_key_exists('name', $data)) ? $data['name'] : ""; + $this->user->profile->firstName = (array_key_exists('first_name', $data)) ? $data['first_name'] : ""; + $this->user->profile->lastName = (array_key_exists('last_name', $data)) ? $data['last_name'] : ""; + $this->user->profile->photoURL = "https://graph.facebook.com/" . $this->user->profile->identifier . "/picture?width=150&height=150"; + $this->user->profile->coverInfoURL = "https://graph.facebook.com/" . $this->user->profile->identifier . "?fields=cover&access_token=" . $this->token('access_token'); + $this->user->profile->profileURL = (array_key_exists('link', $data)) ? $data['link'] : ""; + $this->user->profile->webSiteURL = (array_key_exists('website', $data)) ? $data['website'] : ""; + $this->user->profile->gender = (array_key_exists('gender', $data)) ? $data['gender'] : ""; + $this->user->profile->language = (array_key_exists('locale', $data)) ? $data['locale'] : ""; + $this->user->profile->description = (array_key_exists('about', $data)) ? $data['about'] : ""; + $this->user->profile->email = (array_key_exists('email', $data)) ? $data['email'] : ""; + $this->user->profile->emailVerified = (array_key_exists('email', $data)) ? $data['email'] : ""; + $this->user->profile->region = (array_key_exists("location", $data) && array_key_exists("name", $data['location'])) ? $data['location']["name"] : ""; + if (!empty($this->user->profile->region)) { + $regionArr = explode(',', $this->user->profile->region); + if (count($regionArr) > 1) { + $this->user->profile->city = trim($regionArr[0]); + $this->user->profile->country = trim($regionArr[1]); + } + } + if (array_key_exists('birthday', $data)) { + list($birthday_month, $birthday_day, $birthday_year) = explode("/", $data['birthday']); + $this->user->profile->birthDay = (int) $birthday_day; + $this->user->profile->birthMonth = (int) $birthday_month; + $this->user->profile->birthYear = (int) $birthday_year; + } + + $this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId ); + + return $this->user->profile; + } + /** + * Attempt to retrieve the url to the cover image given the coverInfoURL + * + * @param string $coverInfoURL coverInfoURL variable + * @return string url to the cover image OR blank string + */ + function getCoverURL($coverInfoURL) { + try { + $headers = get_headers($coverInfoURL); + if (substr($headers[0], 9, 3) != "404") { + $coverOBJ = json_decode(file_get_contents($coverInfoURL)); + if (array_key_exists('cover', $coverOBJ)) { + return $coverOBJ->cover->source; + } + } + } catch (Exception $e) { + } + return ""; + } + /** + * {@inheritdoc} + */ + function getUserContacts() { + $apiCall = '?fields=link,name'; + $returnedContacts = array(); + $pagedList = false; + do { + try { + $response = $this->api->api('/me/friends' . $apiCall); + } catch (Exception $e) { + throw new Exception("User contacts request failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e); + } + // Prepare the next call if paging links have been returned + if (array_key_exists('paging', $response) && array_key_exists('next', $response['paging'])) { + $pagedList = true; + $next_page = explode('friends', $response['paging']['next']); + $apiCall = $next_page[1]; + } else { + $pagedList = false; + } + // Add the new page contacts + $returnedContacts = array_merge($returnedContacts, $response['data']); + } while ($pagedList == true); + $contacts = array(); + foreach ($returnedContacts as $item) { + $uc = new Hybrid_User_Contact(); + $uc->identifier = (array_key_exists("id", $item)) ? $item["id"] : ""; + $uc->displayName = (array_key_exists("name", $item)) ? $item["name"] : ""; + $uc->profileURL = (array_key_exists("link", $item)) ? $item["link"] : "https://www.facebook.com/profile.php?id=" . $uc->identifier; + $uc->photoURL = "https://graph.facebook.com/" . $uc->identifier . "/picture?width=150&height=150"; + $contacts[] = $uc; + } + return $contacts; + } + /** + * Update user status + * + * @param mixed $status An array describing the status, or string + * @param string $pageid (optional) User page id + * @return array + * @throw Exception + */ + function setUserStatus($status, $pageid = null) { + if (!is_array($status)) { + $status = array('message' => $status); + } + if (is_null($pageid)) { + $pageid = 'me'; + // if post on page, get access_token page + } else { + $access_token = null; + foreach ($this->getUserPages(true) as $p) { + if (isset($p['id']) && intval($p['id']) == intval($pageid)) { + $access_token = $p['access_token']; + break; + } + } + if (is_null($access_token)) { + throw new Exception("Update user page failed, page not found or not writable!"); + } + $status['access_token'] = $access_token; + } + try { + $response = $this->api->api('/' . $pageid . '/feed', 'post', $status); + } catch (Exception $e) { + throw new Exception("Update user status failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e); + } + return $response; + } + /** + * {@inheridoc} + */ + function getUserStatus($postid) { + try { + $postinfo = $this->api->api("/" . $postid); + } catch (Exception $e) { + throw new Exception("Cannot retrieve user status! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e); + } + return $postinfo; + } + /** + * {@inheridoc} + */ + function getUserPages($writableonly = false) { + if (( isset($this->config['scope']) && strpos($this->config['scope'], 'manage_pages') === false ) || (!isset($this->config['scope']) && strpos($this->scope, 'manage_pages') === false )) + throw new Exception("User status requires manage_page permission!"); + try { + $pages = $this->api->api("/me/accounts", 'get'); + } catch (Exception $e) { + throw new Exception("Cannot retrieve user pages! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e); + } + if (!isset($pages['data'])) { + return array(); + } + if (!$writableonly) { + return $pages['data']; + } + $wrpages = array(); + foreach ($pages['data'] as $p) { + if (isset($p['perms']) && in_array('CREATE_CONTENT', $p['perms'])) { + $wrpages[] = $p; + } + } + return $wrpages; + } + /** + * load the user latest activity + * - timeline : all the stream + * - me : the user activity only + * {@inheritdoc} + */ + function getUserActivity($stream) { + try { + if ($stream == "me") { + $response = $this->api->api('/me/feed'); + } else { + $response = $this->api->api('/me/home'); + } + } catch (Exception $e) { + throw new Exception("User activity stream request failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e); + } + if (!$response || !count($response['data'])) { + return array(); + } + $activities = array(); + foreach ($response['data'] as $item) { + if ($stream == "me" && $item["from"]["id"] != $this->api->getUser()) { + continue; + } + $ua = new Hybrid_User_Activity(); + $ua->id = (array_key_exists("id", $item)) ? $item["id"] : ""; + $ua->date = (array_key_exists("created_time", $item)) ? strtotime($item["created_time"]) : ""; + if ($item["type"] == "video") { + $ua->text = (array_key_exists("link", $item)) ? $item["link"] : ""; + } + if ($item["type"] == "link") { + $ua->text = (array_key_exists("link", $item)) ? $item["link"] : ""; + } + if (empty($ua->text) && isset($item["story"])) { + $ua->text = (array_key_exists("link", $item)) ? $item["link"] : ""; + } + if (empty($ua->text) && isset($item["message"])) { + $ua->text = (array_key_exists("message", $item)) ? $item["message"] : ""; + } + if (!empty($ua->text)) { + $ua->user->identifier = (array_key_exists("id", $item["from"])) ? $item["from"]["id"] : ""; + $ua->user->displayName = (array_key_exists("name", $item["from"])) ? $item["from"]["name"] : ""; + $ua->user->profileURL = "https://www.facebook.com/profile.php?id=" . $ua->user->identifier; + $ua->user->photoURL = "https://graph.facebook.com/" . $ua->user->identifier . "/picture?type=square"; + $activities[] = $ua; + } + } + return $activities; + } +} \ No newline at end of file diff --git a/plugin/social/Hybrid/Providers/Google.php b/plugin/social/Hybrid/Providers/Google.php new file mode 100644 index 000000000..adb2d5a22 --- /dev/null +++ b/plugin/social/Hybrid/Providers/Google.php @@ -0,0 +1,308 @@ + more infos on google APIs: http://developer.google.com (official site) + * or here: http://discovery-check.appspot.com/ (unofficial but up to date) + * default permissions + * {@inheritdoc} + */ + public $scope = "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.profile.emails.read https://www.google.com/m8/feeds/"; + + /** + * {@inheritdoc} + */ + function initialize() { + parent::initialize(); + + // Provider api end-points + $this->api->authorize_url = "https://accounts.google.com/o/oauth2/auth"; + $this->api->token_url = "https://accounts.google.com/o/oauth2/token"; + $this->api->token_info_url = "https://www.googleapis.com/oauth2/v2/tokeninfo"; + + // Google POST methods require an access_token in the header + $this->api->curl_header = array("Authorization: OAuth " . $this->api->access_token); + + // Override the redirect uri when it's set in the config parameters. This way we prevent + // redirect uri mismatches when authenticating with Google. + if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) { + $this->api->redirect_uri = $this->config['redirect_uri']; + } + } + + /** + * {@inheritdoc} + */ + function loginBegin() { + $parameters = array("scope" => $this->scope, "access_type" => "offline"); + $optionals = array("scope", "access_type", "redirect_uri", "approval_prompt", "hd", "state"); + + foreach ($optionals as $parameter) { + if (isset($this->config[$parameter]) && !empty($this->config[$parameter])) { + $parameters[$parameter] = $this->config[$parameter]; + } + if (isset($this->config["scope"]) && !empty($this->config["scope"])) { + $this->scope = $this->config["scope"]; + } + } + + if (isset($this->config['force']) && $this->config['force'] === true) { + $parameters['approval_prompt'] = 'force'; + } + + Hybrid_Auth::redirect($this->api->authorizeUrl($parameters)); + } + + /** + * {@inheritdoc} + */ + function getUserProfile() { + // refresh tokens if needed + $this->refreshToken(); + + // ask google api for user infos + if (strpos($this->scope, '/auth/plus.profile.emails.read') !== false) { + $verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me"); + + if (!isset($verified->id) || isset($verified->error)) + $verified = new stdClass(); + } else { + $verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me/openIdConnect"); + + if (!isset($verified->sub) || isset($verified->error)) + $verified = new stdClass(); + } + + $response = $this->api->api("https://www.googleapis.com/plus/v1/people/me"); + if (!isset($response->id) || isset($response->error)) { + throw new Exception("User profile request failed! {$this->providerId} returned an invalid response:" . Hybrid_Logger::dumpData( $response ), 6); + } + + $this->user->profile->identifier = (property_exists($verified, 'id')) ? $verified->id : ((property_exists($response, 'id')) ? $response->id : ""); + $this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name->givenName : ""; + $this->user->profile->lastName = (property_exists($response, 'name')) ? $response->name->familyName : ""; + $this->user->profile->displayName = (property_exists($response, 'displayName')) ? $response->displayName : ""; + $this->user->profile->photoURL = (property_exists($response, 'image')) ? ((property_exists($response->image, 'url')) ? substr($response->image->url, 0, -2) . "200" : '') : ''; + $this->user->profile->profileURL = (property_exists($response, 'url')) ? $response->url : ""; + $this->user->profile->description = (property_exists($response, 'aboutMe')) ? $response->aboutMe : ""; + $this->user->profile->gender = (property_exists($response, 'gender')) ? $response->gender : ""; + $this->user->profile->language = (property_exists($response, 'locale')) ? $response->locale : ((property_exists($verified, 'locale')) ? $verified->locale : ""); + $this->user->profile->email = (property_exists($response, 'email')) ? $response->email : ((property_exists($verified, 'email')) ? $verified->email : ""); + $this->user->profile->emailVerified = (property_exists($verified, 'email')) ? $verified->email : ""; + if (property_exists($response, 'emails')) { + if (count($response->emails) == 1) { + $this->user->profile->email = $response->emails[0]->value; + } else { + foreach ($response->emails as $email) { + if ($email->type == 'account') { + $this->user->profile->email = $email->value; + break; + } + } + } + if (property_exists($verified, 'emails')) { + if (count($verified->emails) == 1) { + $this->user->profile->emailVerified = $verified->emails[0]->value; + } else { + foreach ($verified->emails as $email) { + if ($email->type == 'account') { + $this->user->profile->emailVerified = $email->value; + break; + } + } + } + } + } + $this->user->profile->phone = (property_exists($response, 'phone')) ? $response->phone : ""; + $this->user->profile->country = (property_exists($response, 'country')) ? $response->country : ""; + $this->user->profile->region = (property_exists($response, 'region')) ? $response->region : ""; + $this->user->profile->zip = (property_exists($response, 'zip')) ? $response->zip : ""; + if (property_exists($response, 'placesLived')) { + $this->user->profile->city = ""; + $this->user->profile->address = ""; + foreach ($response->placesLived as $c) { + if (property_exists($c, 'primary')) { + if ($c->primary == true) { + $this->user->profile->address = $c->value; + $this->user->profile->city = $c->value; + break; + } + } else { + if (property_exists($c, 'value')) { + $this->user->profile->address = $c->value; + $this->user->profile->city = $c->value; + } + } + } + } + + // google API returns multiple urls, but a "website" only if it is verified + // see http://support.google.com/plus/answer/1713826?hl=en + if (property_exists($response, 'urls')) { + foreach ($response->urls as $u) { + if (property_exists($u, 'primary') && $u->primary == true) + $this->user->profile->webSiteURL = $u->value; + } + } else { + $this->user->profile->webSiteURL = ''; + } + // google API returns age ranges min and/or max as of https://developers.google.com/+/web/api/rest/latest/people#resource + if (property_exists($response, 'ageRange')) { + if (property_exists($response->ageRange, 'min') && property_exists($response->ageRange, 'max')) { + $this->user->profile->age = $response->ageRange->min . ' - ' . $response->ageRange->max; + } else { + if (property_exists($response->ageRange, 'min')) { + $this->user->profile->age = '>= ' . $response->ageRange->min; + } else { + if (property_exists($response->ageRange, 'max')) { + $this->user->profile->age = '<= ' . $response->ageRange->max; + } else { + $this->user->profile->age = ''; + } + } + } + } else { + $this->user->profile->age = ''; + } + // google API returns birthdays only if a user set 'show in my account' + if (property_exists($response, 'birthday')) { + list($birthday_year, $birthday_month, $birthday_day) = explode('-', $response->birthday); + + $this->user->profile->birthDay = (int) $birthday_day; + $this->user->profile->birthMonth = (int) $birthday_month; + $this->user->profile->birthYear = (int) $birthday_year; + } else { + $this->user->profile->birthDay = 0; + $this->user->profile->birthMonth = 0; + $this->user->profile->birthYear = 0; + } + + $this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId ); + + return $this->user->profile; + } + + /** + * {@inheritdoc} + */ + function getUserContacts() { + // refresh tokens if needed + $this->refreshToken(); + + $contacts = array(); + if (!isset($this->config['contacts_param'])) { + $this->config['contacts_param'] = array("max-results" => 500); + } + + // Google Gmail and Android contacts + if (strpos($this->scope, '/m8/feeds/') !== false) { + + $response = $this->api->api("https://www.google.com/m8/feeds/contacts/default/full?" + . http_build_query(array_merge(array('alt' => 'json'), $this->config['contacts_param']))); + + if (!$response) { + return array(); + } + + if (isset($response->feed->entry)) { + foreach ($response->feed->entry as $idx => $entry) { + $uc = new Hybrid_User_Contact(); + $uc->email = isset($entry->{'gd$email'}[0]->address) ? (string) $entry->{'gd$email'}[0]->address : ''; + $uc->displayName = isset($entry->title->{'$t'}) ? (string) $entry->title->{'$t'} : ''; + $uc->identifier = ($uc->email != '') ? $uc->email : ''; + $uc->description = ''; + if (property_exists($entry, 'link')) { + /** + * sign links with access_token + */ + if (is_array($entry->link)) { + foreach ($entry->link as $l) { + if (property_exists($l, 'gd$etag') && $l->type == "image/*") { + $uc->photoURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token)); + } else if ($l->type == "self") { + $uc->profileURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token)); + } + } + } + } else { + $uc->profileURL = ''; + } + if (property_exists($response, 'website')) { + if (is_array($response->website)) { + foreach ($response->website as $w) { + if ($w->primary == true) + $uc->webSiteURL = $w->value; + } + } else { + $uc->webSiteURL = $response->website->value; + } + } else { + $uc->webSiteURL = ''; + } + + $contacts[] = $uc; + } + } + } + + // Google social contacts + if (strpos($this->scope, '/auth/plus.login') !== false) { + + $response = $this->api->api("https://www.googleapis.com/plus/v1/people/me/people/visible?" + . http_build_query($this->config['contacts_param'])); + + if (!$response) { + return array(); + } + + foreach ($response->items as $idx => $item) { + $uc = new Hybrid_User_Contact(); + $uc->email = (property_exists($item, 'email')) ? $item->email : ''; + $uc->displayName = (property_exists($item, 'displayName')) ? $item->displayName : ''; + $uc->identifier = (property_exists($item, 'id')) ? $item->id : ''; + + $uc->description = (property_exists($item, 'objectType')) ? $item->objectType : ''; + $uc->photoURL = (property_exists($item, 'image')) ? ((property_exists($item->image, 'url')) ? $item->image->url : '') : ''; + $uc->profileURL = (property_exists($item, 'url')) ? $item->url : ''; + $uc->webSiteURL = ''; + + $contacts[] = $uc; + } + } + + return $contacts; + } + + /** + * Add query parameters to the $url + * + * @param string $url URL + * @param array $params Parameters to add + * @return string + */ + function addUrlParam($url, array $params){ + $query = parse_url($url, PHP_URL_QUERY); + + // Returns the URL string with new parameters + if ($query) { + $url .= '&' . http_build_query($params); + } else { + $url .= '?' . http_build_query($params); + } + return $url; + } + +} + diff --git a/plugin/social/Hybrid/Providers/Kakao.php b/plugin/social/Hybrid/Providers/Kakao.php new file mode 100644 index 000000000..1b1130768 --- /dev/null +++ b/plugin/social/Hybrid/Providers/Kakao.php @@ -0,0 +1,177 @@ + + * http://facebook.com/chuckoh + * + * Date: 11 10, 2014 + * Time: 01:51 AM + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/txt/copying/ for more details. + * + */ + +//https://github.com/jinseokoh/additional-providers +class Hybrid_Providers_Kakao extends Hybrid_Provider_Model_OAuth2 +{ + /** + * initialization + */ + function initialize() + { + parent::initialize(); + + // Provider API end-points + $this->api->api_base_url = "https://kapi.kakao.com/v1/"; + $this->api->authorize_url = "https://kauth.kakao.com/oauth/authorize"; + $this->api->token_url = "https://kauth.kakao.com/oauth/token"; + + // redirect uri mismatches when authenticating with Kakao. + if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) { + $this->api->redirect_uri = $this->config['redirect_uri']; + } + } + + /** + * finish login step + */ + function loginFinish() + { + $error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : ""; + // check for errors + if ( $error ){ + throw new Exception( "Authentication failed! {$this->providerId} returned an error: $error", 5 ); + } + // try to authenicate user + $code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : ""; + try{ + $this->authenticate( $code ); + } + catch( Exception $e ){ + throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 ); + } + // check if authenticated + if ( ! $this->api->access_token ){ + throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 ); + } + // store tokens + $this->token("access_token", $this->api->access_token); + $this->token("refresh_token", $this->api->refresh_token); + $this->token("expires_in", $this->api->access_token_expires_in); + $this->token("expires_at", $this->api->access_token_expires_at); + // set user connected locally + $this->setUserConnected(); + } + + /** + * load the user profile + */ + function getUserProfile() + { + $params = array('property_keys'=>'kaccount_email'); + + $this->api->decode_json = false; + $this->api->curl_header = array( 'Authorization: Bearer ' . $this->api->access_token ); + + $data = $this->api->api("user/me", "POST", $params); + + if ( ! isset( $data->id ) ) { + throw new Exception("User profile request failed! {$this->providerId} returned an invalid response.", 6); + } + # store the user profile. + $this->user->profile->identifier = @ $data->id; + $this->user->profile->displayName = @ $data->properties->nickname; + $this->user->profile->photoURL = @ $data->properties->thumbnail_image; + $email = @ $data->kaccount_email; + + if( $email ){ + $this->user->profile->email = $email; + } + + $this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId ); + + return $this->user->profile; + } + + private function authenticate($code) + { + $params = array( + "grant_type" => "authorization_code", + "client_id" => $this->api->client_id, + "redirect_uri" => $this->api->redirect_uri, + "code" => $code + ); + + if( $this->api->client_secret && ($this->api->client_secret !== $this->api->client_id) ){ + $params['client_secret'] = $this->api->client_secret; + } + + $response = $this->request($this->api->token_url, $params, $this->api->curl_authenticate_method); + $response = $this->parseRequestResult($response); + if ( ! $response || ! isset($response->access_token) ) { + throw new Exception("The Authorization Service has return: " . $response->error); + } + if ( isset($response->access_token) ) $this->api->access_token = $response->access_token; + if ( isset($response->refresh_token) ) $this->api->refresh_token = $response->refresh_token; + if ( isset($response->expires_in) ) $this->api->access_token_expires_in = $response->expires_in; + + // calculate when the access token expire + if ( isset($response->expires_in) ) { + $this->api->access_token_expires_at = time() + $response->expires_in; + } + + return $response; + } + + private function request($url, $params=false, $type="GET") + { + if(Class_exists('Hybrid_Logger')){ + Hybrid_Logger::info("Enter OAuth2Client::request( $url )"); + Hybrid_Logger::debug("OAuth2Client::request(). dump request params: ", serialize( $params )); + } + $this->http_info = array(); + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL , $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT , $this->api->curl_time_out); + curl_setopt($ch, CURLOPT_USERAGENT , $this->api->curl_useragent); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->api->curl_connect_time_out); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->api->curl_ssl_verifypeer); + curl_setopt($ch, CURLOPT_HTTPHEADER , $this->api->curl_header); + + if ( $this->api->curl_proxy ) { + curl_setopt( $ch, CURLOPT_PROXY, $this->curl_proxy); + } + if ( $type == "POST" ) { + curl_setopt($ch, CURLOPT_POST, 1); + if ($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($params) ); + } + + $response = curl_exec($ch); + if(Class_exists('Hybrid_Logger')){ + Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize(curl_getinfo($ch)) ); + Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize($response )); + } + $this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $this->http_info = array_merge($this->http_info, curl_getinfo($ch)); + curl_close ($ch); + + return $response; + } + + private function parseRequestResult($result) + { + if ( json_decode($result) ) return json_decode($result); + parse_str( $result, $ouput ); + $result = new StdClass(); + foreach( $ouput as $k => $v ) + $result->$k = $v; + + return $result; + } +} \ No newline at end of file diff --git a/plugin/social/Hybrid/Providers/Naver.php b/plugin/social/Hybrid/Providers/Naver.php new file mode 100644 index 000000000..431425b43 --- /dev/null +++ b/plugin/social/Hybrid/Providers/Naver.php @@ -0,0 +1,234 @@ + + * http://facebook.com/chuckoh + * + * Date: 11 11, 2014 + * Time: 11:38 AM + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/txt/copying/ for more details. + * + */ + +//https://github.com/jinseokoh/additional-providers +class Hybrid_Providers_Naver extends Hybrid_Provider_Model_OAuth2 +{ + /** + * initialization + */ + function initialize() + { + parent::initialize(); + + // Provider API end-points + $this->api->api_base_url = "https://apis.naver.com/nidlogin/"; + $this->api->authorize_url = "https://nid.naver.com/oauth2.0/authorize"; + $this->api->token_url = "https://nid.naver.com/oauth2.0/token"; + + // redirect uri mismatches when authenticating with Naver. + if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) { + $this->api->redirect_uri = $this->config['redirect_uri']; + } + } + + /** + * begin login step + */ + function loginBegin() + { + $token = $this->generate_state_token(); + Hybrid_Auth::storage()->set("naver_state_token", $token); + + $parameters = array( + "response_type" => "code", + "client_id" => $this->api->client_id, + "redirect_uri" => $this->api->redirect_uri, + "state" => $token, + ); + + Hybrid_Auth::redirect($this->api->authorizeUrl($parameters)); + } + + /** + * finish login step + */ + function loginFinish() + { + $error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : ""; + // check for errors + if ( $error ){ + throw new Exception( "Authentication failed! {$this->providerId} returned an error: $error", 5 ); + } + // try to authenicate user + $code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : ""; + try{ + $this->authenticate( $code ); + } + catch( Exception $e ){ + throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 ); + } + // check if authenticated + if ( ! $this->api->access_token ){ + throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 ); + } + // store tokens + $this->token("access_token", $this->api->access_token); + $this->token("refresh_token", $this->api->refresh_token); + $this->token("expires_in", $this->api->access_token_expires_in); + $this->token("expires_at", $this->api->access_token_expires_at); + // set user connected locally + $this->setUserConnected(); + } + + /** + * set propper headers + */ + function profile($url) { + $this->api->decode_json = false; + $this->api->curl_header = array( 'Authorization: Bearer ' . $this->api->access_token ); + $response = $this->api->get($url, array(), false); + + return $response; + } + + /** + * load the user profile + */ + //https://developers.naver.com/docs/login/profile/ + function getUserProfile() + { + $response = $this->profile("nid/getUserProfile.xml"); + + $xml = @ new SimpleXMLElement($response); + $data = array(); + if ( $xml->result[0]->resultcode == '00' ) { + foreach ($xml->response->children() as $response => $k) { + $data[(string)$response] = (string) $k; + } + } else { + throw new Exception("User profile request failed! {$this->providerId} returned an invalid response.", 6); + } + + # store the user profile. + //$this->user->profile->identifier = (array_key_exists('enc_id',$data))?$data['enc_id']:""; + $this->user->profile->identifier = (array_key_exists('id',$data))?$data['id']:""; + $this->user->profile->age = (array_key_exists('age',$data))?$data['age']:""; + $this->user->profile->displayName = ''; + /* + if( array_key_exists('email',$data) ){ + $tmp = explode("@", $data['email']); + $this->user->profile->displayName = $tmp[0]; + } + */ + $this->user->profile->displayName = (array_key_exists('nickname',$data))?$data['nickname']:""; + $this->user->profile->birthDay = ''; + $this->user->profile->birthMonth = ''; + if( array_key_exists('birthday',$data) ){ + $tmp = explode("-",$data['birthday']); + if( isset($tmp[0]) ){ + $this->user->profile->birthDay = $tmp[0]; + } + if( isset($tmp[1]) ){ + $this->user->profile->birthMonth = $tmp[1]; + } + } + $this->user->profile->email = (array_key_exists('email',$data))?$data['email']:""; + $this->user->profile->emailVerified = (array_key_exists('email',$data))?$data['email']:""; + $this->user->profile->gender = (array_key_exists('gender',$data))?(($data['gender'] == "M")?"male":"female"):""; + $this->user->profile->photoURL = (array_key_exists('profile_image',$data))?$data['profile_image']:""; + + $this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId ); + + return $this->user->profile; + } + + private function authenticate($code) + { + $token = Hybrid_Auth::storage()->get("naver_state_token"); + $params = array( + "grant_type" => "authorization_code", + "client_id" => $this->api->client_id, + "client_secret" => $this->api->client_secret, + // "redirect_uri" => $this->api->redirect_uri, + "code" => $code, + "state" => $token + ); + Hybrid_Auth::storage()->set("naver_state_token", null); + + $response = $this->request($this->api->token_url, $params, $this->api->curl_authenticate_method); + $response = $this->parseRequestResult($response); + if ( ! $response || ! isset($response->access_token) ) { + throw new Exception("The Authorization Service has return: " . $response->error); + } + if ( isset($response->access_token) ) $this->api->access_token = $response->access_token; + if ( isset($response->refresh_token) ) $this->api->refresh_token = $response->refresh_token; + if ( isset($response->expires_in) ) $this->api->access_token_expires_in = $response->expires_in; + + // calculate when the access token expire + if ( isset($response->expires_in) ) { + $this->api->access_token_expires_at = time() + $response->expires_in; + } + + return $response; + } + + private function request($url, $params=false, $type="GET") + { + if(Class_exists('Hybrid_Logger')){ + Hybrid_Logger::info("Enter OAuth2Client::request( $url )"); + Hybrid_Logger::debug("OAuth2Client::request(). dump request params: ", serialize( $params )); + } + $this->http_info = array(); + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL , $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT , $this->api->curl_time_out); + curl_setopt($ch, CURLOPT_USERAGENT , $this->api->curl_useragent); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->api->curl_connect_time_out); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->api->curl_ssl_verifypeer); + curl_setopt($ch, CURLOPT_HTTPHEADER , $this->api->curl_header); + + if ( $this->api->curl_proxy ) { + curl_setopt( $ch, CURLOPT_PROXY, $this->curl_proxy); + } + if ( $type == "POST" ) { + curl_setopt($ch, CURLOPT_POST, 1); + if ($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($params) ); + } + + $response = curl_exec($ch); + if(Class_exists('Hybrid_Logger')){ + Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize(curl_getinfo($ch)) ); + Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize($response )); + } + $this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $this->http_info = array_merge($this->http_info, curl_getinfo($ch)); + curl_close ($ch); + + return $response; + } + + private function parseRequestResult($result) + { + if ( json_decode($result) ) return json_decode($result); + parse_str( $result, $ouput ); + $result = new StdClass(); + foreach( $ouput as $k => $v ) + $result->$k = $v; + + return $result; + } + + private function generate_state_token() { + $mt = microtime(); + $rand = mt_rand(); + + return md5($mt . $rand); + } +} diff --git a/plugin/social/Hybrid/Providers/Payco.php b/plugin/social/Hybrid/Providers/Payco.php new file mode 100644 index 000000000..c0bb45480 --- /dev/null +++ b/plugin/social/Hybrid/Providers/Payco.php @@ -0,0 +1,212 @@ +api->api_base_url = 'https://id.payco.com/oauth2.0/'; + $this->api->authorize_url = 'https://id.payco.com/oauth2.0/authorize'; + $this->api->token_url = 'https://id.payco.com/oauth2.0/token'; + $this->api->token_info = 'https://apis3.krp.toastoven.net/payco/friends/getIdNoByFriendsToken.json'; + $this->api->profile_url = 'https://apis3.krp.toastoven.net/payco/friends/getMemberProfileByFriendsToken.json'; + + if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) { + throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4); + } + + // redirect uri mismatches when authenticating with Payco. + if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) { + $this->api->redirect_uri = $this->config['redirect_uri']; + } + } + /** + * {@inheritdoc} + */ + function loginBegin() { + + $token = md5(uniqid(mt_rand(), true)); + Hybrid_Auth::storage()->set('payco_auth_token', $token); + + $parameters = array( + "response_type" => "code", + "client_id" => $this->api->client_id, + "redirect_uri" => $this->api->redirect_uri, + "state" => $token, + "userLocale" => "ko_KR", + "serviceProviderCode" => "FRIENDS", + ); + + Hybrid_Auth::redirect($this->api->authorizeUrl($parameters)); + + exit; + + } + /** + * {@inheritdoc} + */ + function loginFinish() { + + // in case we get error_reason=user_denied&error=access_denied + if (isset($_REQUEST['error']) && $_REQUEST['error'] == "access_denied") { + throw new Exception("Authentication failed! The user denied your request.", 5); + } + + // try to authenicate user + $code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : ""; + try{ + $response = $this->api->authenticate( $code ); + } + catch( Exception $e ){ + throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 ); + } + + // check if authenticated + if ( ! $this->api->authenticated() ){ + throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 ); + } + // store tokens + $this->token("access_token", $this->api->access_token); + $this->token("refresh_token", $this->api->refresh_token); + $this->token("expires_in", $this->api->access_token_expires_in); + $this->token("expires_at", $this->api->access_token_expires_at); + + $this->setUserConnected(); + + } + + function check_valid_access_token(){ + + $params = array( + 'body' => array( + 'client_id'=>$this->api->client_id, + 'access_token'=>$this->api->access_token, + ), + ); + + $this->api->curl_header = array( + + 'Content-Type:application/json', + 'client_id: '.$this->api->client_id, + 'access_token: '.$this->api->access_token, + + ); + + $response = $this->api->api( $this->api->token_info, 'POST', $params ); + + if( is_object($response) && !empty($response->idNo) && $response->header->successful ){ + $this->idNo = $response->idNo; + + return true; + } + + return false; + } + + /** + * {@inheritdoc} + */ + function logout() { + parent::logout(); + } + /** + * {@inheritdoc} + */ + + /** + * set propper headers + */ + function getUserProfile() { + + $data = null; + + // request user profile + try { + + if( $this->check_valid_access_token() ){ + $params = array( + 'body' => array( + 'client_id'=>$this->api->client_id, + 'access_token'=>$this->api->access_token, + 'MemberProfile'=>'idNo,id,name', + 'idNo'=>$this->idNo, + ), + ); + + $this->api->curl_header = array( + 'Content-Type:application/json', + 'client_id: '.$this->api->client_id, + 'access_token: '.$this->api->access_token, + 'Authorization: Bearer ' . $this->api->access_token, + ); + + $response = $this->api->api( $this->api->profile_url, 'POST', $params ); + } + + } catch (Exception $e) { + throw new Exception("User profile request failed! {$this->providerId} returned an error: {$e->getMessage()}", 6, $e); + } + + if( ! is_object($response) || property_exists($response, 'error_code') ){ + $this->logout(); + + throw new Exception( "Authentication failed! {$this->providerId} returned an invalid access token.", 5 ); + } + + if( is_object($response) ){ + $result = json_decode(json_encode($response), true); + $data = $result['memberProfile']; + } + + // if the provider identifier is not received, we assume the auth has failed + if (!isset($data["id"])) { + $this->logout(); + throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $data ), 6); + } + + # store the user profile. + $this->user->profile->identifier = (array_key_exists('idNo', $data)) ? $data['idNo'] : ""; + $this->user->profile->username = (array_key_exists('name', $data)) ? $data['name'] : ""; + $this->user->profile->displayName = (array_key_exists('name', $data)) ? $data['name'] : ""; + $this->user->profile->age = (array_key_exists('ageGroup', $data)) ? $data['ageGroup'] : ""; + + include_once(G5_LIB_PATH.'/register.lib.php'); + + $payco_no = substr(base_convert($this->user->profile->identifier, 16, 36), 0, 16); + $email = (array_key_exists('id', $data)) ? $data['id'] : ""; + + $this->user->profile->gender = (array_key_exists('sexCode', $data)) ? $data['sexCode'] : ""; + + $this->user->profile->email = ! valid_mb_email($email) ? $email : ""; + $this->user->profile->emailVerified = ! valid_mb_email($email) ? $email : ""; + + + if (array_key_exists('birthdayMMdd', $data)) { + $this->user->profile->birthMonth = substr($data['birthdayMMdd'], 0, 2); + $this->user->profile->birthDay = substr($data['birthdayMMdd'], 2, 4); + } + + $this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId ); + + return $this->user->profile; + } //end function getUserProfile + +} \ No newline at end of file diff --git a/plugin/social/Hybrid/Providers/Twitter.php b/plugin/social/Hybrid/Providers/Twitter.php new file mode 100644 index 000000000..cb1c1706b --- /dev/null +++ b/plugin/social/Hybrid/Providers/Twitter.php @@ -0,0 +1,266 @@ +api->api_base_url = "https://api.twitter.com/1.1/"; + $this->api->authorize_url = "https://api.twitter.com/oauth/authenticate"; + $this->api->request_token_url = "https://api.twitter.com/oauth/request_token"; + $this->api->access_token_url = "https://api.twitter.com/oauth/access_token"; + + if (isset($this->config['api_version']) && $this->config['api_version']) { + $this->api->api_base_url = "https://api.twitter.com/{$this->config['api_version']}/"; + } + + if (isset($this->config['authorize']) && $this->config['authorize']) { + $this->api->authorize_url = "https://api.twitter.com/oauth/authorize"; + } + + $this->api->curl_auth_header = false; + } + + /** + * {@inheritdoc} + */ + function loginBegin() { + // Initiate the Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth + if (isset($_REQUEST['reverse_auth']) && ($_REQUEST['reverse_auth'] == 'yes')) { + $stage1 = $this->api->signedRequest($this->api->request_token_url, 'POST', array('x_auth_mode' => 'reverse_auth')); + if ($this->api->http_code != 200) { + throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5); + } + $responseObj = array('x_reverse_auth_parameters' => $stage1, 'x_reverse_auth_target' => $this->config["keys"]["key"]); + $response = json_encode($responseObj); + header("Content-Type: application/json", true, 200); + echo $response; + die(); + } + $tokens = $this->api->requestToken($this->endpoint); + + // request tokens as received from provider + $this->request_tokens_raw = $tokens; + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5); + } + + if (!isset($tokens["oauth_token"])) { + throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth token.", 5); + } + + $this->token("request_token", $tokens["oauth_token"]); + $this->token("request_token_secret", $tokens["oauth_token_secret"]); + + // redirect the user to the provider authentication url with force_login + if (( isset($this->config['force_login']) && $this->config['force_login'] ) || ( isset($this->config['force']) && $this->config['force'] === true )) { + Hybrid_Auth::redirect($this->api->authorizeUrl($tokens, array('force_login' => true))); + } + + // else, redirect the user to the provider authentication url + Hybrid_Auth::redirect($this->api->authorizeUrl($tokens)); + } + + /** + * {@inheritdoc} + */ + function loginFinish() { + // in case we are completing a Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth + if (isset($_REQUEST['oauth_token_secret'])) { + $tokens = $_REQUEST; + $this->access_tokens_raw = $tokens; + + // we should have an access_token unless something has gone wrong + if (!isset($tokens["oauth_token"])) { + throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5); + } + + // Get rid of tokens we don't need + $this->deleteToken("request_token"); + $this->deleteToken("request_token_secret"); + + // Store access_token and secret for later use + $this->token("access_token", $tokens['oauth_token']); + $this->token("access_token_secret", $tokens['oauth_token_secret']); + + // set user as logged in to the current provider + $this->setUserConnected(); + return; + } + parent::loginFinish(); + } + + /** + * {@inheritdoc} + */ + function getUserProfile() { + $includeEmail = isset($this->config['includeEmail']) ? (bool) $this->config['includeEmail'] : false; + $response = $this->api->get('account/verify_credentials.json'. ($includeEmail ? '?include_email=true' : '')); + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("User profile request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 6); + } + + if (!is_object($response) || !isset($response->id)) { + throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $response ), 6); + } + + # store the user profile. + $this->user->profile->identifier = (property_exists($response, 'id')) ? $response->id : ""; + $this->user->profile->displayName = (property_exists($response, 'screen_name')) ? $response->screen_name : ""; + $this->user->profile->description = (property_exists($response, 'description')) ? $response->description : ""; + $this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name : ""; + $this->user->profile->photoURL = (property_exists($response, 'profile_image_url')) ? (str_replace('_normal', '', $response->profile_image_url)) : ""; + $this->user->profile->profileURL = (property_exists($response, 'screen_name')) ? ("http://twitter.com/" . $response->screen_name) : ""; + $this->user->profile->webSiteURL = (property_exists($response, 'url')) ? $response->url : ""; + $this->user->profile->region = (property_exists($response, 'location')) ? $response->location : ""; + if($includeEmail) $this->user->profile->email = (property_exists($response, 'email')) ? $response->email : ""; + if($includeEmail) $this->user->profile->emailVerified = (property_exists($response, 'email')) ? $response->email : ""; + + $this->user->profile->sid = get_social_convert_id( $this->user->profile->identifier, $this->providerId ); + + return $this->user->profile; + } + + /** + * {@inheritdoc} + */ + function getUserContacts() { + $parameters = array('cursor' => '-1'); + $response = $this->api->get('friends/ids.json', $parameters); + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); + } + + if (!$response || !count($response->ids)) { + return array(); + } + + // 75 id per time should be okey + $contactsids = array_chunk($response->ids, 75); + + $contacts = array(); + + foreach ($contactsids as $chunk) { + $parameters = array('user_id' => implode(",", $chunk)); + $response = $this->api->get('users/lookup.json', $parameters); + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); + } + + if ($response && count($response)) { + foreach ($response as $item) { + $uc = new Hybrid_User_Contact(); + + $uc->identifier = (property_exists($item, 'id')) ? $item->id : ""; + $uc->displayName = (property_exists($item, 'name')) ? $item->name : ""; + $uc->profileURL = (property_exists($item, 'screen_name')) ? ("http://twitter.com/" . $item->screen_name) : ""; + $uc->photoURL = (property_exists($item, 'profile_image_url')) ? $item->profile_image_url : ""; + $uc->description = (property_exists($item, 'description')) ? $item->description : ""; + + $contacts[] = $uc; + } + } + } + + return $contacts; + } + + /** + * {@inheritdoc} + */ + function setUserStatus($status) { + + if (is_array($status) && isset($status['message']) && isset($status['picture'])) { + $response = $this->api->post('statuses/update_with_media.json', array('status' => $status['message'], 'media[]' => file_get_contents($status['picture'])), null, null, true); + } else { + $response = $this->api->post('statuses/update.json', array('status' => $status)); + } + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("Update user status failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); + } + + return $response; + } + + /** + * {@inheritdoc} + */ + function getUserStatus($tweetid) { + $info = $this->api->get('statuses/show.json?id=' . $tweetid . '&include_entities=true'); + + // check the last HTTP status code returned + if ($this->api->http_code != 200 || !isset($info->id)) { + throw new Exception("Cannot retrieve user status! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); + } + + return $info; + } + + /** + * load the user latest activity + * - timeline : all the stream + * - me : the user activity only + * + * by default return the timeline + * {@inheritdoc} + */ + function getUserActivity($stream) { + if ($stream == "me") { + $response = $this->api->get('statuses/user_timeline.json'); + } else { + $response = $this->api->get('statuses/home_timeline.json'); + } + + // check the last HTTP status code returned + if ($this->api->http_code != 200) { + throw new Exception("User activity stream request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); + } + + if (!$response) { + return array(); + } + + $activities = array(); + + foreach ($response as $item) { + $ua = new Hybrid_User_Activity(); + + $ua->id = (property_exists($item, 'id')) ? $item->id : ""; + $ua->date = (property_exists($item, 'created_at')) ? strtotime($item->created_at) : ""; + $ua->text = (property_exists($item, 'text')) ? $item->text : ""; + + $ua->user->identifier = (property_exists($item->user, 'id')) ? $item->user->id : ""; + $ua->user->displayName = (property_exists($item->user, 'name')) ? $item->user->name : ""; + $ua->user->profileURL = (property_exists($item->user, 'screen_name')) ? ("http://twitter.com/" . $item->user->screen_name) : ""; + $ua->user->photoURL = (property_exists($item->user, 'profile_image_url')) ? $item->user->profile_image_url : ""; + + $activities[] = $ua; + } + + return $activities; + } + +} diff --git a/plugin/social/Hybrid/Storage.php b/plugin/social/Hybrid/Storage.php new file mode 100644 index 000000000..16a2f6cb2 --- /dev/null +++ b/plugin/social/Hybrid/Storage.php @@ -0,0 +1,141 @@ +config("php_session_id", session_id()); + $this->config("version", Hybrid_Auth::$version); + } + + /** + * Saves a value in the config storage, or returns config if value is null + * + * @param string $key Config name + * @param string $value Config value + * @return array|null + */ + public function config($key, $value = null) { + $key = strtolower($key); + + if ($value) { + $_SESSION["HA::CONFIG"][$key] = serialize($value); + } elseif (isset($_SESSION["HA::CONFIG"][$key])) { + return unserialize($_SESSION["HA::CONFIG"][$key]); + } + + return null; + } + + /** + * Returns value from session storage + * + * @param string $key Key + * @return string|null + */ + public function get($key) { + $key = strtolower($key); + + if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) { + return unserialize($_SESSION["HA::STORE"][$key]); + } + + return null; + } + + /** + * Saves a key value pair to the session storage + * + * @param string $key Key + * @param string $value Value + * @return void + */ + public function set($key, $value) { + $key = strtolower($key); + $_SESSION["HA::STORE"][$key] = serialize($value); + } + + /** + * Clear session storage + * @return void + */ + function clear() { + $_SESSION["HA::STORE"] = array(); + } + + /** + * Delete a specific key from session storage + * + * @param string $key Key + * @return void + */ + function delete($key) { + $key = strtolower($key); + + if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) { + $f = $_SESSION['HA::STORE']; + unset($f[$key]); + $_SESSION["HA::STORE"] = $f; + } + } + + /** + * Delete all keys recursively from session storage + * + * @param string $key Key + * @retun void + */ + function deleteMatch($key) { + $key = strtolower($key); + + if (isset($_SESSION["HA::STORE"]) && count($_SESSION["HA::STORE"])) { + $f = $_SESSION['HA::STORE']; + foreach ($f as $k => $v) { + if (strstr($k, $key)) { + unset($f[$k]); + } + } + $_SESSION["HA::STORE"] = $f; + } + } + + /** + * Returns session storage as a serialized string + * @return string|null + */ + function getSessionData() { + if (isset($_SESSION["HA::STORE"])) { + return serialize($_SESSION["HA::STORE"]); + } + return null; + } + + /** + * Restores the session from serialized session data + * + * @param string $sessiondata Serialized session data + * @return void + */ + function restoreSessionData($sessiondata = null) { + $_SESSION["HA::STORE"] = unserialize($sessiondata); + } + +} diff --git a/plugin/social/Hybrid/StorageInterface.php b/plugin/social/Hybrid/StorageInterface.php new file mode 100644 index 000000000..5b171ec3a --- /dev/null +++ b/plugin/social/Hybrid/StorageInterface.php @@ -0,0 +1,29 @@ +timestamp = time(); + $this->profile = new Hybrid_User_Profile(); + } + +} diff --git a/plugin/social/Hybrid/User_Activity.php b/plugin/social/Hybrid/User_Activity.php new file mode 100644 index 000000000..5d0712ab6 --- /dev/null +++ b/plugin/social/Hybrid/User_Activity.php @@ -0,0 +1,55 @@ +user = new stdClass(); + + // typically, we should have a few information about the user who created the event from social apis + $this->user->identifier = null; + $this->user->displayName = null; + $this->user->profileURL = null; + $this->user->photoURL = null; + } + +} diff --git a/plugin/social/Hybrid/User_Contact.php b/plugin/social/Hybrid/User_Contact.php new file mode 100644 index 000000000..976595835 --- /dev/null +++ b/plugin/social/Hybrid/User_Contact.php @@ -0,0 +1,60 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/plugin/social/Hybrid/resources/index.html b/plugin/social/Hybrid/resources/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/plugin/social/Hybrid/resources/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/plugin/social/Hybrid/resources/openid_policy.html b/plugin/social/Hybrid/resources/openid_policy.html new file mode 100644 index 000000000..01462daec --- /dev/null +++ b/plugin/social/Hybrid/resources/openid_policy.html @@ -0,0 +1,10 @@ + + + OpenID Policy + + + + + \ No newline at end of file diff --git a/plugin/social/Hybrid/resources/openid_realm.html b/plugin/social/Hybrid/resources/openid_realm.html new file mode 100644 index 000000000..78b1b1d62 --- /dev/null +++ b/plugin/social/Hybrid/resources/openid_realm.html @@ -0,0 +1,13 @@ + + + HybridAuth Endpoint + + + + +

      HybridAuth

      + Open Source Social Sign On PHP Library. +
      + hybridauth.sourceforge.net/ + + diff --git a/plugin/social/Hybrid/resources/openid_xrds.xml b/plugin/social/Hybrid/resources/openid_xrds.xml new file mode 100644 index 000000000..ab94e5c01 --- /dev/null +++ b/plugin/social/Hybrid/resources/openid_xrds.xml @@ -0,0 +1,12 @@ + + + + + http://specs.openid.net/auth/2.0/return_to + {RETURN_TO_URL} + + + \ No newline at end of file diff --git a/plugin/social/Hybrid/thirdparty/OAuth/OAuth.php b/plugin/social/Hybrid/thirdparty/OAuth/OAuth.php new file mode 100644 index 000000000..876665fae --- /dev/null +++ b/plugin/social/Hybrid/thirdparty/OAuth/OAuth.php @@ -0,0 +1,901 @@ +key = $key; + $this->secret = $secret; + $this->callback_url = $callback_url; + } + + function __toString() { + return "OAuthConsumer[key=$this->key,secret=$this->secret]"; + } +} + +class OAuthToken { + // access tokens and request tokens + public $key; + public $secret; + + /** + * key = the token + * secret = the token secret + */ + function __construct($key, $secret) { + $this->key = $key; + $this->secret = $secret; + } + + /** + * generates the basic string serialization of a token that a server + * would respond to request_token and access_token calls with + */ + function to_string() { + return "oauth_token=" . + OAuthUtil::urlencode_rfc3986($this->key) . + "&oauth_token_secret=" . + OAuthUtil::urlencode_rfc3986($this->secret); + } + + function __toString() { + return $this->to_string(); + } +} + +/** + * A class for implementing a Signature Method + * See section 9 ("Signing Requests") in the spec + */ +abstract class OAuthSignatureMethod { + /** + * Needs to return the name of the Signature Method (ie HMAC-SHA1) + * @return string + */ + abstract public function get_name(); + + /** + * Build up the signature + * NOTE: The output of this function MUST NOT be urlencoded. + * the encoding is handled in OAuthRequest when the final + * request is serialized + * @param OAuthRequest $request + * @param OAuthConsumer $consumer + * @param OAuthToken $token + * @return string + */ + abstract public function build_signature($request, $consumer, $token); + + /** + * Verifies that a given signature is correct + * @param OAuthRequest $request + * @param OAuthConsumer $consumer + * @param OAuthToken $token + * @param string $signature + * @return bool + */ + public function check_signature($request, $consumer, $token, $signature) { + $built = $this->build_signature($request, $consumer, $token); + + // Check for zero length, although unlikely here + if (strlen($built) == 0 || strlen($signature) == 0) { + return false; + } + + if (strlen($built) != strlen($signature)) { + return false; + } + + // Avoid a timing leak with a (hopefully) time insensitive compare + $result = 0; + for ($i = 0; $i < strlen($signature); $i++) { + $result |= ord($built{$i}) ^ ord($signature{$i}); + } + + return $result == 0; + } +} + +/** + * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] + * where the Signature Base String is the text and the key is the concatenated values (each first + * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' + * character (ASCII code 38) even if empty. + * - Chapter 9.2 ("HMAC-SHA1") + */ +class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod { + function get_name() { + return "HMAC-SHA1"; + } + + public function build_signature($request, $consumer, $token) { + $base_string = $request->get_signature_base_string(); + $request->base_string = $base_string; + + $key_parts = array( + $consumer->secret, + ($token) ? $token->secret : "" + ); + + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); + $key = implode('&', $key_parts); + + return base64_encode(hash_hmac('sha1', $base_string, $key, true)); + } +} + +/** + * The PLAINTEXT method does not provide any security protection and SHOULD only be used + * over a secure channel such as HTTPS. It does not use the Signature Base String. + * - Chapter 9.4 ("PLAINTEXT") + */ +class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod { + public function get_name() { + return "PLAINTEXT"; + } + + /** + * oauth_signature is set to the concatenated encoded values of the Consumer Secret and + * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is + * empty. The result MUST be encoded again. + * - Chapter 9.4.1 ("Generating Signatures") + * + * Please note that the second encoding MUST NOT happen in the SignatureMethod, as + * OAuthRequest handles this! + */ + public function build_signature($request, $consumer, $token) { + $key_parts = array( + $consumer->secret, + ($token) ? $token->secret : "" + ); + + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); + $key = implode('&', $key_parts); + $request->base_string = $key; + + return $key; + } +} + +/** + * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in + * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for + * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a + * verified way to the Service Provider, in a manner which is beyond the scope of this + * specification. + * - Chapter 9.3 ("RSA-SHA1") + */ +abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod { + public function get_name() { + return "RSA-SHA1"; + } + + // Up to the SP to implement this lookup of keys. Possible ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // (2) fetch via http using a url provided by the requester + // (3) some sort of specific discovery code based on request + // + // Either way should return a string representation of the certificate + protected abstract function fetch_public_cert(&$request); + + // Up to the SP to implement this lookup of keys. Possible ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // + // Either way should return a string representation of the certificate + protected abstract function fetch_private_cert(&$request); + + public function build_signature($request, $consumer, $token) { + $base_string = $request->get_signature_base_string(); + $request->base_string = $base_string; + + // Fetch the private key cert based on the request + $cert = $this->fetch_private_cert($request); + + // Pull the private key ID from the certificate + $privatekeyid = openssl_get_privatekey($cert); + + // Sign using the key + $ok = openssl_sign($base_string, $signature, $privatekeyid); + + // Release the key resource + openssl_free_key($privatekeyid); + + return base64_encode($signature); + } + + public function check_signature($request, $consumer, $token, $signature) { + $decoded_sig = base64_decode($signature); + + $base_string = $request->get_signature_base_string(); + + // Fetch the public key cert based on the request + $cert = $this->fetch_public_cert($request); + + // Pull the public key ID from the certificate + $publickeyid = openssl_get_publickey($cert); + + // Check the computed signature against the one passed in the query + $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); + + // Release the key resource + openssl_free_key($publickeyid); + + return $ok == 1; + } +} + +class OAuthRequest { + protected $parameters; + protected $http_method; + protected $http_url; + // for debug purposes + public $base_string; + public static $version = '1.0'; + public static $POST_INPUT = 'php://input'; + + function __construct($http_method, $http_url, $parameters=null) { + $parameters = ($parameters) ? $parameters : array(); + $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); + $this->parameters = $parameters; + $this->http_method = $http_method; + $this->http_url = $http_url; + } + + + /** + * attempt to build up a request from what was passed to the server + */ + public static function from_request($http_method=null, $http_url=null, $parameters=null) { + $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") + ? 'http' + : 'https'; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + $scheme = $_SERVER['HTTP_X_FORWARDED_PROTO']; + } + $http_url = ($http_url) ? $http_url : $scheme . + '://' . $_SERVER['SERVER_NAME'] . + ':' . + $_SERVER['SERVER_PORT'] . + $_SERVER['REQUEST_URI']; + $http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD']; + + // We weren't handed any parameters, so let's find the ones relevant to + // this request. + // If you run XML-RPC or similar you should use this to provide your own + // parsed parameter-list + if (!$parameters) { + // Find request headers + $request_headers = OAuthUtil::get_headers(); + + // Parse the query-string to find GET parameters + $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); + + // It's a POST request of the proper content-type, so parse POST + // parameters and add those overriding any duplicates from GET + if ($http_method == "POST" + && isset($request_headers['Content-Type']) + && strstr($request_headers['Content-Type'], + 'application/x-www-form-urlencoded') + ) { + $post_data = OAuthUtil::parse_parameters( + file_get_contents(self::$POST_INPUT) + ); + $parameters = array_merge($parameters, $post_data); + } + + // We have a Authorization-header with OAuth data. Parse the header + // and add those overriding any duplicates from GET or POST + if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') { + $header_parameters = OAuthUtil::split_header( + $request_headers['Authorization'] + ); + $parameters = array_merge($parameters, $header_parameters); + } + + } + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + /** + * pretty much a helper function to set up the request + */ + public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=null) { + $parameters = ($parameters) ? $parameters : array(); + $defaults = array("oauth_version" => OAuthRequest::$version, + "oauth_nonce" => OAuthRequest::generate_nonce(), + "oauth_timestamp" => OAuthRequest::generate_timestamp(), + "oauth_consumer_key" => $consumer->key); + if ($token) + $defaults['oauth_token'] = $token->key; + + $parameters = array_merge($defaults, $parameters); + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + public function set_parameter($name, $value, $allow_duplicates = true) { + if ($allow_duplicates && isset($this->parameters[$name])) { + // We have already added parameter(s) with this name, so add to the list + if (is_scalar($this->parameters[$name])) { + // This is the first duplicate, so transform scalar (string) + // into an array so we can add the duplicates + $this->parameters[$name] = array($this->parameters[$name]); + } + + $this->parameters[$name][] = $value; + } else { + $this->parameters[$name] = $value; + } + } + + public function get_parameter($name) { + return isset($this->parameters[$name]) ? $this->parameters[$name] : null; + } + + public function get_parameters() { + return $this->parameters; + } + + public function unset_parameter($name) { + unset($this->parameters[$name]); + } + + /** + * The request parameters, sorted and concatenated into a normalized string. + * @return string + */ + public function get_signable_parameters() { + // Grab all parameters + $params = $this->parameters; + + // Remove oauth_signature if present + // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") + if (isset($params['oauth_signature'])) { + unset($params['oauth_signature']); + } + + return OAuthUtil::build_http_query($params); + } + + /** + * Returns the base string of this request + * + * The base string defined as the method, the url + * and the parameters (normalized), each urlencoded + * and the concated with &. + */ + public function get_signature_base_string() { + $parts = array( + $this->get_normalized_http_method(), + $this->get_normalized_http_url(), + $this->get_signable_parameters() + ); + + $parts = OAuthUtil::urlencode_rfc3986($parts); + + return implode('&', $parts); + } + + /** + * just uppercases the http method + */ + public function get_normalized_http_method() { + return strtoupper($this->http_method); + } + + /** + * parses the url and rebuilds it to be + * scheme://host/path + */ + public function get_normalized_http_url() { + $parts = parse_url($this->http_url); + + $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http'; + $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80'); + $host = (isset($parts['host'])) ? strtolower($parts['host']) : ''; + $path = (isset($parts['path'])) ? $parts['path'] : ''; + + if (($scheme == 'https' && $port != '443') + || ($scheme == 'http' && $port != '80')) { + $host = "$host:$port"; + } + return "$scheme://$host$path"; + } + + /** + * builds a url usable for a GET request + */ + public function to_url() { + $post_data = $this->to_postdata(); + $out = $this->get_normalized_http_url(); + if ($post_data) { + $out .= '?'.$post_data; + } + return $out; + } + + /** + * builds the data one would send in a POST request + */ + public function to_postdata() { + return OAuthUtil::build_http_query($this->parameters); + } + + /** + * builds the Authorization: header + */ + public function to_header($realm=null) { + $first = true; + if($realm) { + $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; + $first = false; + } else + $out = 'Authorization: OAuth'; + + $total = array(); + foreach ($this->parameters as $k => $v) { + if (substr($k, 0, 5) != "oauth") continue; + if (is_array($v)) { + throw new OAuthException('arrays not supported in headers'); + } + $out .= ($first) ? ' ' : ','; + $out .= OAuthUtil::urlencode_rfc3986($k) . + '="' . + OAuthUtil::urlencode_rfc3986($v) . + '"'; + $first = false; + } + return $out; + } + + public function __toString() { + return $this->to_url(); + } + + + public function sign_request($signature_method, $consumer, $token) { + $this->set_parameter( + "oauth_signature_method", + $signature_method->get_name(), + false + ); + $signature = $this->build_signature($signature_method, $consumer, $token); + $this->set_parameter("oauth_signature", $signature, false); + } + + public function build_signature($signature_method, $consumer, $token) { + $signature = $signature_method->build_signature($this, $consumer, $token); + return $signature; + } + + /** + * util function: current timestamp + */ + private static function generate_timestamp() { + return time(); + } + + /** + * util function: current nonce + */ + private static function generate_nonce() { + $mt = microtime(); + $rand = mt_rand(); + + return md5($mt . $rand); // md5s look nicer than numbers + } +} + +class OAuthServer { + protected $timestamp_threshold = 300; // in seconds, five minutes + protected $version = '1.0'; // hi blaine + protected $signature_methods = array(); + + protected $data_store; + + function __construct($data_store) { + $this->data_store = $data_store; + } + + public function add_signature_method($signature_method) { + $this->signature_methods[$signature_method->get_name()] = + $signature_method; + } + + // high level functions + + /** + * process a request_token request + * returns the request token on success + */ + public function fetch_request_token(&$request) { + $this->get_version($request); + + $consumer = $this->get_consumer($request); + + // no token required for the initial token request + $token = null; + + $this->check_signature($request, $consumer, $token); + + // Rev A change + $callback = $request->get_parameter('oauth_callback'); + $new_token = $this->data_store->new_request_token($consumer, $callback); + + return $new_token; + } + + /** + * process an access_token request + * returns the access token on success + */ + public function fetch_access_token(&$request) { + $this->get_version($request); + + $consumer = $this->get_consumer($request); + + // requires authorized request token + $token = $this->get_token($request, $consumer, "request"); + + $this->check_signature($request, $consumer, $token); + + // Rev A change + $verifier = $request->get_parameter('oauth_verifier'); + $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); + + return $new_token; + } + + /** + * verify an api call, checks all the parameters + */ + public function verify_request(&$request) { + $this->get_version($request); + $consumer = $this->get_consumer($request); + $token = $this->get_token($request, $consumer, "access"); + $this->check_signature($request, $consumer, $token); + return array($consumer, $token); + } + + // Internals from here + /** + * version 1 + */ + private function get_version(&$request) { + $version = $request->get_parameter("oauth_version"); + if (!$version) { + // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. + // Chapter 7.0 ("Accessing Protected Ressources") + $version = '1.0'; + } + if ($version !== $this->version) { + throw new OAuthException("OAuth version '$version' not supported"); + } + return $version; + } + + /** + * figure out the signature with some defaults + */ + private function get_signature_method($request) { + $signature_method = $request instanceof OAuthRequest + ? $request->get_parameter("oauth_signature_method") + : null; + + if (!$signature_method) { + // According to chapter 7 ("Accessing Protected Ressources") the signature-method + // parameter is required, and we can't just fallback to PLAINTEXT + throw new OAuthException('No signature method parameter. This parameter is required'); + } + + if (!in_array($signature_method, + array_keys($this->signature_methods))) { + throw new OAuthException( + "Signature method '$signature_method' not supported " . + "try one of the following: " . + implode(", ", array_keys($this->signature_methods)) + ); + } + return $this->signature_methods[$signature_method]; + } + + /** + * try to find the consumer for the provided request's consumer key + */ + private function get_consumer($request) { + $consumer_key = $request instanceof OAuthRequest + ? $request->get_parameter("oauth_consumer_key") + : null; + + if (!$consumer_key) { + throw new OAuthException("Invalid consumer key"); + } + + $consumer = $this->data_store->lookup_consumer($consumer_key); + if (!$consumer) { + throw new OAuthException("Invalid consumer"); + } + + return $consumer; + } + + /** + * try to find the token for the provided request's token key + */ + private function get_token($request, $consumer, $token_type="access") { + $token_field = $request instanceof OAuthRequest + ? $request->get_parameter('oauth_token') + : null; + + $token = $this->data_store->lookup_token( + $consumer, $token_type, $token_field + ); + if (!$token) { + throw new OAuthException("Invalid $token_type token: $token_field"); + } + return $token; + } + + /** + * all-in-one function to check the signature on a request + * should guess the signature method appropriately + */ + private function check_signature($request, $consumer, $token) { + // this should probably be in a different method + $timestamp = $request instanceof OAuthRequest + ? $request->get_parameter('oauth_timestamp') + : null; + $nonce = $request instanceof OAuthRequest + ? $request->get_parameter('oauth_nonce') + : null; + + $this->check_timestamp($timestamp); + $this->check_nonce($consumer, $token, $nonce, $timestamp); + + $signature_method = $this->get_signature_method($request); + + $signature = $request->get_parameter('oauth_signature'); + $valid_sig = $signature_method->check_signature( + $request, + $consumer, + $token, + $signature + ); + + if (!$valid_sig) { + throw new OAuthException("Invalid signature"); + } + } + + /** + * check that the timestamp is new enough + */ + private function check_timestamp($timestamp) { + if( ! $timestamp ) + throw new OAuthException( + 'Missing timestamp parameter. The parameter is required' + ); + + // verify that timestamp is recentish + $now = time(); + if (abs($now - $timestamp) > $this->timestamp_threshold) { + throw new OAuthException( + "Expired timestamp, yours $timestamp, ours $now" + ); + } + } + + /** + * check that the nonce is not repeated + */ + private function check_nonce($consumer, $token, $nonce, $timestamp) { + if( ! $nonce ) + throw new OAuthException( + 'Missing nonce parameter. The parameter is required' + ); + + // verify that the nonce is uniqueish + $found = $this->data_store->lookup_nonce( + $consumer, + $token, + $nonce, + $timestamp + ); + if ($found) { + throw new OAuthException("Nonce already used: $nonce"); + } + } + +} + +class OAuthDataStore { + function lookup_consumer($consumer_key) { + // implement me + } + + function lookup_token($consumer, $token_type, $token) { + // implement me + } + + function lookup_nonce($consumer, $token, $nonce, $timestamp) { + // implement me + } + + function new_request_token($consumer, $callback = null) { + // return a new token attached to this consumer + } + + function new_access_token($token, $consumer, $verifier = null) { + // return a new access token attached to this consumer + // for the user associated with this token if the request token + // is authorized + // should also invalidate the request token + } + +} + +class OAuthUtil { + public static function urlencode_rfc3986($input) { + if (is_array($input)) { + return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input); + } else if (is_scalar($input)) { + return str_replace( + '+', + ' ', + str_replace('%7E', '~', rawurlencode($input)) + ); + } else { + return ''; + } +} + + + // This decode function isn't taking into consideration the above + // modifications to the encoding process. However, this method doesn't + // seem to be used anywhere so leaving it as is. + public static function urldecode_rfc3986($string) { + return urldecode($string); + } + + // Utility function for turning the Authorization: header into + // parameters, has to do some unescaping + // Can filter out any non-oauth parameters if needed (default behaviour) + // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement. + // see http://code.google.com/p/oauth/issues/detail?id=163 + public static function split_header($header, $only_allow_oauth_parameters = true) { + $params = array(); + if (preg_match_all('/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) { + foreach ($matches[1] as $i => $h) { + $params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]); + } + if (isset($params['realm'])) { + unset($params['realm']); + } + } + return $params; + } + + // helper to try to sort out headers for people who aren't running apache + public static function get_headers() { + if (function_exists('apache_request_headers')) { + // we need this to get the actual Authorization: header + // because apache tends to tell us it doesn't exist + $headers = apache_request_headers(); + + // sanitize the output of apache_request_headers because + // we always want the keys to be Cased-Like-This and arh() + // returns the headers in the same case as they are in the + // request + $out = array(); + foreach ($headers AS $key => $value) { + $key = str_replace( + " ", + "-", + ucwords(strtolower(str_replace("-", " ", $key))) + ); + $out[$key] = $value; + } + } else { + // otherwise we don't have apache and are just going to have to hope + // that $_SERVER actually contains what we need + $out = array(); + if( isset($_SERVER['CONTENT_TYPE']) ) + $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; + if( isset($_ENV['CONTENT_TYPE']) ) + $out['Content-Type'] = $_ENV['CONTENT_TYPE']; + + foreach ($_SERVER as $key => $value) { + if (substr($key, 0, 5) == "HTTP_") { + // this is chaos, basically it is just there to capitalize the first + // letter of every word that is not an initial HTTP and strip HTTP + // code from przemek + $key = str_replace( + " ", + "-", + ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) + ); + $out[$key] = $value; + } + } + } + return $out; + } + + // This function takes a input like a=b&a=c&d=e and returns the parsed + // parameters like this + // array('a' => array('b','c'), 'd' => 'e') + public static function parse_parameters( $input ) { + if (!isset($input) || !$input) return array(); + + $pairs = explode('&', $input); + + $parsed_parameters = array(); + foreach ($pairs as $pair) { + $split = explode('=', $pair, 2); + $parameter = OAuthUtil::urldecode_rfc3986($split[0]); + $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; + + if (isset($parsed_parameters[$parameter])) { + // We have already recieved parameter(s) with this name, so add to the list + // of parameters with this name + + if (is_scalar($parsed_parameters[$parameter])) { + // This is the first duplicate, so transform scalar (string) into an array + // so we can add the duplicates + $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); + } + + $parsed_parameters[$parameter][] = $value; + } else { + $parsed_parameters[$parameter] = $value; + } + } + return $parsed_parameters; + } + + public static function build_http_query($params) { + if (!$params) return ''; + + // Urlencode both keys and values + $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); + $values = OAuthUtil::urlencode_rfc3986(array_values($params)); + $params = array_combine($keys, $values); + + // Parameters are sorted by name, using lexicographical byte value ordering. + // Ref: Spec: 9.1.1 (1) + uksort($params, 'strcmp'); + + $pairs = array(); + foreach ($params as $parameter => $value) { + if (is_array($value)) { + // If two or more parameters share the same name, they are sorted by their value + // Ref: Spec: 9.1.1 (1) + // June 12th, 2010 - changed to sort because of issue 164 by hidetaka + sort($value, SORT_STRING); + foreach ($value as $duplicate_value) { + $pairs[] = $parameter . '=' . $duplicate_value; + } + } else { + $pairs[] = $parameter . '=' . $value; + } + } + // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) + // Each name-value pair is separated by an '&' character (ASCII code 38) + return implode('&', $pairs); + } +} diff --git a/plugin/social/Hybrid/thirdparty/OAuth/OAuth1Client.php b/plugin/social/Hybrid/thirdparty/OAuth/OAuth1Client.php new file mode 100644 index 000000000..64c03c87d --- /dev/null +++ b/plugin/social/Hybrid/thirdparty/OAuth/OAuth1Client.php @@ -0,0 +1,264 @@ +sha1_method = new OAuthSignatureMethod_HMAC_SHA1(); + $this->consumer = new OAuthConsumer( $consumer_key, $consumer_secret ); + $this->token = null; + + if ( $oauth_token && $oauth_token_secret ){ + $this->token = new OAuthConsumer( $oauth_token, $oauth_token_secret ); + } + } + + /** + * Build authorize url + * + * @return string + */ + function authorizeUrl( $token, $extras =array() ) + { + if ( is_array( $token ) ){ + $token = $token['oauth_token']; + } + + $parameters = array( "oauth_token" => $token ); + + if( count($extras) ) + foreach( $extras as $k=>$v ) + $parameters[$k] = $v; + + return $this->authorize_url . "?" . http_build_query( $parameters ); + } + + /** + * Get a request_token from provider + * + * @return array a key/value array containing oauth_token and oauth_token_secret + */ + function requestToken( $callback = null ) + { + $parameters = array(); + + if ( $callback ) { + $this->redirect_uri = $parameters['oauth_callback'] = $callback; + } + + $request = $this->signedRequest( $this->request_token_url, $this->request_token_method, $parameters ); + $token = OAuthUtil::parse_parameters( $request ); + $this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] ); + + return $token; + } + + /** + * Exchange the request token and secret for an access token and secret, to sign API calls. + * + * @return array array('oauth_token' => the access token, 'oauth_token_secret' => the access secret) + */ + function accessToken( $oauth_verifier = false, $oauth_token = false ) + { + $parameters = array(); + + // 1.0a + if ( $oauth_verifier ) { + $parameters['oauth_verifier'] = $oauth_verifier; + } + + $request = $this->signedRequest( $this->access_token_url, $this->access_token_method, $parameters ); + $token = OAuthUtil::parse_parameters( $request ); + $this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] ); + + return $token; + } + + /** + * GET wrapper for provider apis request + */ + function get($url, $parameters = array(), $content_type = null) + { + return $this->api($url, 'GET', $parameters, null, $content_type); + } + + /** + * POST wrapper for provider apis request + */ + function post($url, $parameters = array(), $body = null, $content_type = null, $multipart = false) + { + return $this->api($url, 'POST', $parameters, $body, $content_type, $multipart ); + } + + /** + * Format and sign an oauth for provider api + */ + function api( $url, $method = 'GET', $parameters = array(), $body = null, $content_type = null, $multipart = false ) + { + if ( strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0 ) { + $url = $this->api_base_url . $url; + } + + $response = $this->signedRequest( $url, $method, $parameters, $body, $content_type, $multipart ); + + if( $this->decode_json ){ + $response = json_decode( $response ); + } + + return $this->response = $response; + } + + /** + * Return the response object afer the fact + * + * @return mixed + */ + public function getResponse() + { + return $this->response; + } + + /** + * Make signed request + */ + function signedRequest( $url, $method, $parameters, $body = null, $content_type = null, $multipart = false ) + { + + $signature_parameters = array(); + + // when making a multipart request, use only oauth_* keys for signature + foreach( $parameters AS $key => $value ){ + if( !$multipart || strpos( $key, 'oauth_' ) === 0 ){ + $signature_parameters[$key] = $value; + } + } + + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $signature_parameters); + $request->sign_request($this->sha1_method, $this->consumer, $this->token); + switch ($method) { + case 'GET': return $this->request( $request->to_url(), 'GET', null, null, $content_type ); + default : + if ($body) + return $this->request( $request->to_url(), $method, $body, $request->to_header(), $content_type ); + else + return $this->request( $request->get_normalized_http_url(), $method, ($multipart ? $parameters : $request->to_postdata()), $request->to_header(), $content_type, $multipart ) ; + } + } + + /** + * Make http request + */ + function request( $url, $method, $postfields = null, $auth_header = null, $content_type = null, $multipart = false ) + { + Hybrid_Logger::info( "Enter OAuth1Client::request( $method, $url )" ); + Hybrid_Logger::debug( "OAuth1Client::request(). dump post fields: ", serialize( $postfields ) ); + + $this->http_info = array(); + $ci = curl_init(); + + /* Curl settings */ + curl_setopt( $ci, CURLOPT_USERAGENT , $this->curl_useragent ); + curl_setopt( $ci, CURLOPT_CONNECTTIMEOUT, $this->curl_connect_time_out ); + curl_setopt( $ci, CURLOPT_TIMEOUT , $this->curl_time_out ); + curl_setopt( $ci, CURLOPT_RETURNTRANSFER, true ); + curl_setopt( $ci, CURLOPT_HTTPHEADER , array('Expect:') ); + curl_setopt( $ci, CURLOPT_SSL_VERIFYPEER, $this->curl_ssl_verifypeer ); + curl_setopt( $ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader') ); + curl_setopt( $ci, CURLOPT_HEADER , false ); + + if( $multipart ){ + curl_setopt( $ci, CURLOPT_HTTPHEADER, array( 'Expect:', $auth_header ) ); + + }elseif ($content_type) + curl_setopt( $ci, CURLOPT_HTTPHEADER, array('Expect:', "Content-Type: $content_type") ); + + if($this->curl_proxy){ + curl_setopt( $ci, CURLOPT_PROXY , $this->curl_proxy); + } + + switch ($method){ + case 'POST': + curl_setopt( $ci, CURLOPT_POST, true ); + + if ( !empty($postfields) ){ + curl_setopt( $ci, CURLOPT_POSTFIELDS, $postfields ); + } + + if ( !empty($auth_header) && $this->curl_auth_header && !$multipart ){ + curl_setopt( $ci, CURLOPT_HTTPHEADER, array( 'Content-Type: application/atom+xml', $auth_header ) ); + } + break; + case 'DELETE': + curl_setopt( $ci, CURLOPT_CUSTOMREQUEST, 'DELETE' ); + if ( !empty($postfields) ){ + $url = "{$url}?{$postfields}"; + } + } + + curl_setopt($ci, CURLOPT_URL, $url); + $response = curl_exec($ci); + if( $response === false ) { + Hybrid_Logger::error( "OAuth1Client::request(). curl_exec error: ", curl_error($ci) ); + } + + + Hybrid_Logger::debug( "OAuth1Client::request(). dump request info: ", serialize( curl_getinfo($ci) ) ); + Hybrid_Logger::debug( "OAuth1Client::request(). dump request result: ", serialize( $response ) ); + + $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); + $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); + + curl_close ($ci); + + return $response; + } + + /** + * Get the header info to store. + */ + function getHeader($ch, $header) { + $i = strpos($header, ':'); + + if ( !empty($i) ){ + $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); + $value = trim(substr($header, $i + 2)); + $this->http_header[$key] = $value; + } + + return strlen($header); + } +} diff --git a/plugin/social/Hybrid/thirdparty/OAuth/OAuth2Client.php b/plugin/social/Hybrid/thirdparty/OAuth/OAuth2Client.php new file mode 100644 index 000000000..0046d2c58 --- /dev/null +++ b/plugin/social/Hybrid/thirdparty/OAuth/OAuth2Client.php @@ -0,0 +1,302 @@ +client_id = $client_id; + $this->client_secret = $client_secret; + $this->redirect_uri = $redirect_uri; + $this->curl_compressed = $compressed; + } + + public function authorizeUrl( $extras = array() ) + { + $params = array( + "client_id" => $this->client_id, + "redirect_uri" => $this->redirect_uri, + "response_type" => "code" + ); + + if( count($extras) ) + foreach( $extras as $k=>$v ) + $params[$k] = $v; + + return $this->authorize_url . "?" . http_build_query($params, '', '&'); + } + + public function authenticate( $code ) + { + $params = array( + "client_id" => $this->client_id, + "client_secret" => $this->client_secret, + "grant_type" => "authorization_code", + "redirect_uri" => $this->redirect_uri, + "code" => $code + ); + + $response = $this->request( $this->token_url, $params, $this->curl_authenticate_method ); + + $response = $this->parseRequestResult( $response ); + + if( ! $response || ! isset( $response->access_token ) ){ + throw new Exception( "The Authorization Service has return: " . $response->error ); + } + + if( isset( $response->access_token ) ) $this->access_token = $response->access_token; + if( isset( $response->refresh_token ) ) $this->refresh_token = $response->refresh_token; + if( isset( $response->expires_in ) ) $this->access_token_expires_in = $response->expires_in; + + // calculate when the access token expire + if( isset($response->expires_in)) { + $this->access_token_expires_at = time() + $response->expires_in; + } + + return $response; + } + + public function authenticated() + { + if ( $this->access_token ){ + if ( $this->token_info_url && $this->refresh_token ){ + // check if this access token has expired, + $tokeninfo = $this->tokenInfo( $this->access_token ); + + // if yes, access_token has expired, then ask for a new one + if( $tokeninfo && isset( $tokeninfo->error ) ){ + $response = $this->refreshToken( $this->refresh_token ); + + // if wrong response + if( ! isset( $response->access_token ) || ! $response->access_token ){ + throw new Exception( "The Authorization Service has return an invalid response while requesting a new access token. given up!" ); + } + + // set new access_token + $this->access_token = $response->access_token; + } + } + + return true; + } + + return false; + } + + /** + * Format and sign an oauth for provider api + */ + public function api( $url, $method = "GET", $parameters = array(), $decode_json = true ) + { + if ( strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0 ) { + $url = $this->api_base_url . $url; + } + + $parameters[$this->sign_token_name] = $this->access_token; + $response = null; + + switch( $method ){ + case 'GET' : $response = $this->request( $url, $parameters, "GET" ); break; + case 'POST' : $response = $this->request( $url, $parameters, "POST" ); break; + case 'DELETE' : $response = $this->request( $url, $parameters, "DELETE" ); break; + case 'PATCH' : $response = $this->request( $url, $parameters, "PATCH" ); break; + } + + if( $response && $decode_json ){ + return $this->response = json_decode( $response ); + } + + return $this->response = $response; + } + + /** + * Return the response object afer the fact + * + * @return mixed + */ + public function getResponse() + { + return $this->response; + } + + /** + * GET wrapper for provider apis request + */ + function get( $url, $parameters = array(), $decode_json = true ) + { + return $this->api( $url, 'GET', $parameters, $decode_json ); + } + + /** + * POST wrapper for provider apis request + */ + function post( $url, $parameters = array(), $decode_json = true ) + { + return $this->api( $url, 'POST', $parameters, $decode_json ); + } + + // -- tokens + + public function tokenInfo($accesstoken) + { + $params['access_token'] = $this->access_token; + $response = $this->request( $this->token_info_url, $params ); + return $this->parseRequestResult( $response ); + } + + public function refreshToken( $parameters = array() ) + { + $params = array( + "client_id" => $this->client_id, + "client_secret" => $this->client_secret, + "grant_type" => "refresh_token" + ); + + foreach($parameters as $k=>$v ){ + $params[$k] = $v; + } + + $response = $this->request( $this->token_url, $params, "POST" ); + return $this->parseRequestResult( $response ); + } + + // -- utilities + + private function request( $url, $params=false, $type="GET" ) + { + Hybrid_Logger::info( "Enter OAuth2Client::request( $url )" ); + Hybrid_Logger::debug( "OAuth2Client::request(). dump request params: ", serialize( $params ) ); + + $urlEncodedParams = http_build_query($params, '', '&'); + + if( $type == "GET" ){ + $url = $url . ( strpos( $url, '?' ) ? '&' : '?' ) . $urlEncodedParams; + } + + $this->http_info = array(); + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL , $url ); + curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 ); + curl_setopt($ch, CURLOPT_TIMEOUT , $this->curl_time_out ); + curl_setopt($ch, CURLOPT_USERAGENT , $this->curl_useragent ); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , $this->curl_connect_time_out ); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , $this->curl_ssl_verifypeer ); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , $this->curl_ssl_verifyhost ); + curl_setopt($ch, CURLOPT_HTTPHEADER , $this->curl_header ); + + if ($this->curl_compressed){ + curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate"); + } + + if($this->curl_proxy){ + curl_setopt( $ch, CURLOPT_PROXY , $this->curl_proxy); + } + + if ($type == "POST") { + curl_setopt($ch, CURLOPT_POST, 1); + + // If request body exists then encode it for "application/json". + if (isset($params['body'])) { + $urlEncodedParams = json_encode($params['body']); + } + + // Using URL encoded params here instead of a more convenient array + // cURL will set a wrong HTTP Content-Type header if using an array (cf. http://www.php.net/manual/en/function.curl-setopt.php, Notes section for "CURLOPT_POSTFIELDS") + // OAuth requires application/x-www-form-urlencoded Content-Type (cf. https://tools.ietf.org/html/rfc6749#section-2.3.1) + if ($params) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $urlEncodedParams); + } + } + + if( $type == "DELETE" ){ + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); + } + if( $type == "PATCH" ){ + curl_setopt($ch, CURLOPT_POST, 1); + if($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, $params ); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); + } + $response = curl_exec($ch); + if( $response === false ) { + Hybrid_Logger::error( "OAuth2Client::request(). curl_exec error: ", curl_error($ch) ); + } + Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize( curl_getinfo($ch) ) ); + Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize( $response ) ); + + $this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $this->http_info = array_merge($this->http_info, curl_getinfo($ch)); + + curl_close ($ch); + + return $response; + } + + private function parseRequestResult( $result ) + { + if( json_decode( $result ) ) return json_decode( $result ); + + parse_str( $result, $output ); + + $result = new StdClass(); + + foreach( $output as $k => $v ) + $result->$k = $v; + + return $result; + } + /** + * DELETE wrapper for provider apis request + */ + function delete( $url, $parameters = array() ) + { + return $this->api( $url, 'DELETE', $parameters ); + } + /** + * PATCH wrapper for provider apis request + */ + function patch( $url, $parameters = array() ) + { + return $this->api( $url, 'PATCH', $parameters ); + } +} diff --git a/plugin/social/Hybrid/thirdparty/OpenID/LightOpenID.php b/plugin/social/Hybrid/thirdparty/OpenID/LightOpenID.php new file mode 100644 index 000000000..b1cb41bb3 --- /dev/null +++ b/plugin/social/Hybrid/thirdparty/OpenID/LightOpenID.php @@ -0,0 +1,1051 @@ += 5.1.2 with cURL or HTTP/HTTPS stream wrappers enabled. + * + * @version v1.2.0 (2014-01-14) + * @link https://code.google.com/p/lightopenid/ Project URL + * @link https://github.com/iignatov/LightOpenID GitHub Repo + * @author Mewp + * @copyright Copyright (c) 2013 Mewp + * @license http://opensource.org/licenses/mit-license.php MIT License + */ +class LightOpenID +{ + public $returnUrl + , $required = array() + , $optional = array() + , $verify_peer = null + , $capath = null + , $cainfo = null + , $cnmatch = null + , $data + , $oauth = array() + , $curl_time_out = 30 + , $curl_connect_time_out = 30; + private $identity, $claimed_id; + protected $server, $version, $trustRoot, $aliases, $identifier_select = false + , $ax = false, $sreg = false, $setup_url = null, $headers = array() + , $proxy = null, $user_agent = 'LightOpenID' + , $xrds_override_pattern = null, $xrds_override_replacement = null; + static protected $ax_to_sreg = array( + 'namePerson/friendly' => 'nickname', + 'contact/email' => 'email', + 'namePerson' => 'fullname', + 'birthDate' => 'dob', + 'person/gender' => 'gender', + 'contact/postalCode/home' => 'postcode', + 'contact/country/home' => 'country', + 'pref/language' => 'language', + 'pref/timezone' => 'timezone', + ); + + function __construct($host, $proxy = null) + { + $this->set_realm($host); + $this->set_proxy($proxy); + + $uri = rtrim(preg_replace('#((?<=\?)|&)openid\.[^&]+#', '', $_SERVER['REQUEST_URI']), '?'); + $this->returnUrl = $this->trustRoot . $uri; + + $this->data = ($_SERVER['REQUEST_METHOD'] === 'POST') ? $_POST : $_GET; + + if(!function_exists('curl_init') && !in_array('https', stream_get_wrappers())) { + throw new ErrorException('You must have either https wrappers or curl enabled.'); + } + } + + function __isset($name) + { + return in_array($name, array('identity', 'trustRoot', 'realm', 'xrdsOverride', 'mode')); + } + + function __set($name, $value) + { + switch ($name) { + case 'identity': + if (strlen($value = trim((String) $value))) { + if (preg_match('#^xri:/*#i', $value, $m)) { + $value = substr($value, strlen($m[0])); + } elseif (!preg_match('/^(?:[=@+\$!\(]|https?:)/i', $value)) { + $value = "http://$value"; + } + if (preg_match('#^https?://[^/]+$#i', $value, $m)) { + $value .= '/'; + } + } + $this->$name = $this->claimed_id = $value; + break; + case 'trustRoot': + case 'realm': + $this->trustRoot = trim($value); + break; + case 'xrdsOverride': + if (is_array($value)) { + list($pattern, $replacement) = $value; + $this->xrds_override_pattern = $pattern; + $this->xrds_override_replacement = $replacement; + } else { + trigger_error('Invalid value specified for "xrdsOverride".', E_USER_ERROR); + } + break; + } + } + + function __get($name) + { + switch ($name) { + case 'identity': + # We return claimed_id instead of identity, + # because the developer should see the claimed identifier, + # i.e. what he set as identity, not the op-local identifier (which is what we verify) + return $this->claimed_id; + case 'trustRoot': + case 'realm': + return $this->trustRoot; + case 'mode': + return empty($this->data['openid_mode']) ? null : $this->data['openid_mode']; + } + } + + function set_proxy($proxy) + { + if (!empty($proxy)) { + // When the proxy is a string - try to parse it. + if (!is_array($proxy)) { + $proxy = parse_url($proxy); + } + + // Check if $proxy is valid after the parsing. + if ($proxy && !empty($proxy['host'])) { + // Make sure that a valid port number is specified. + if (array_key_exists('port', $proxy)) { + if (!is_int($proxy['port'])) { + $proxy['port'] = is_numeric($proxy['port']) ? intval($proxy['port']) : 0; + } + + if ($proxy['port'] <= 0) { + throw new ErrorException('The specified proxy port number is invalid.'); + } + } + + $this->proxy = $proxy; + } + } + } + + /** + * Checks if the server specified in the url exists. + * + * @param $url url to check + * @return true, if the server exists; false otherwise + */ + function hostExists($url) + { + if (strpos($url, '/') === false) { + $server = $url; + } else { + $server = @parse_url($url, PHP_URL_HOST); + } + + if (!$server) { + return false; + } + + return !!gethostbynamel($server); + } + + protected function set_realm($uri) + { + $realm = ''; + + # Set a protocol, if not specified. + $realm .= (($offset = strpos($uri, '://')) === false) ? $this->get_realm_protocol() : ''; + + # Set the offset properly. + $offset = (($offset !== false) ? $offset + 3 : 0); + + # Get only the root, without the path. + $realm .= (($end = strpos($uri, '/', $offset)) === false) ? $uri : substr($uri, 0, $end); + + $this->trustRoot = $realm; + } + + protected function get_realm_protocol() + { + if (!empty($_SERVER['HTTPS'])) { + $use_secure_protocol = ($_SERVER['HTTPS'] != 'off'); + } else if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + $use_secure_protocol = ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'); + } else { + $use_secure_protocol = false; + } + + return $use_secure_protocol ? 'https://' : 'http://'; + } + + protected function request_curl($url, $method='GET', $params=array(), $update_claimed_id) + { + $params = http_build_query($params, '', '&'); + $curl = curl_init($url . ($method == 'GET' && $params ? '?' . $params : '')); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_HEADER, false); + curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_time_out); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT , $this->curl_connect_time_out); + + + if ($method == 'POST') { + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded')); + } else { + curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/xrds+xml, */*')); + } + + if (!empty($this->proxy)) { + curl_setopt($curl, CURLOPT_PROXY, $this->proxy['host']); + + if (!empty($this->proxy['port'])) { + curl_setopt($curl, CURLOPT_PROXYPORT, $this->proxy['port']); + } + + if (!empty($this->proxy['user'])) { + curl_setopt($curl, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']); + } + } + + if($this->verify_peer !== null) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verify_peer); + if($this->capath) { + curl_setopt($curl, CURLOPT_CAPATH, $this->capath); + } + + if($this->cainfo) { + curl_setopt($curl, CURLOPT_CAINFO, $this->cainfo); + } + } + + if ($method == 'POST') { + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $params); + } elseif ($method == 'HEAD') { + curl_setopt($curl, CURLOPT_HEADER, true); + curl_setopt($curl, CURLOPT_NOBODY, true); + } else { + curl_setopt($curl, CURLOPT_HEADER, true); + curl_setopt($curl, CURLOPT_HTTPGET, true); + } + $response = curl_exec($curl); + + if($method == 'HEAD' && curl_getinfo($curl, CURLINFO_HTTP_CODE) == 405) { + curl_setopt($curl, CURLOPT_HTTPGET, true); + $response = curl_exec($curl); + $response = substr($response, 0, strpos($response, "\r\n\r\n")); + } + + if($method == 'HEAD' || $method == 'GET') { + $header_response = $response; + + # If it's a GET request, we want to only parse the header part. + if($method == 'GET') { + $header_response = substr($response, 0, strpos($response, "\r\n\r\n")); + } + + $headers = array(); + foreach(explode("\n", $header_response) as $header) { + $pos = strpos($header,':'); + if ($pos !== false) { + $name = strtolower(trim(substr($header, 0, $pos))); + $headers[$name] = trim(substr($header, $pos+1)); + } + } + + if($update_claimed_id) { + # Update the claimed_id value in case of redirections. + $effective_url = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); + # Ignore the fragment (some cURL versions don't handle it well). + if (strtok($effective_url, '#') != strtok($url, '#')) { + $this->identity = $this->claimed_id = $effective_url; + } + } + + if($method == 'HEAD') { + return $headers; + } else { + $this->headers = $headers; + } + } + + if (curl_errno($curl)) { + throw new ErrorException(curl_error($curl), curl_errno($curl)); + } + + return $response; + } + + protected function parse_header_array($array, $update_claimed_id) + { + $headers = array(); + foreach($array as $header) { + $pos = strpos($header,':'); + if ($pos !== false) { + $name = strtolower(trim(substr($header, 0, $pos))); + $headers[$name] = trim(substr($header, $pos+1)); + + # Following possible redirections. The point is just to have + # claimed_id change with them, because the redirections + # are followed automatically. + # We ignore redirections with relative paths. + # If any known provider uses them, file a bug report. + if($name == 'location' && $update_claimed_id) { + if(strpos($headers[$name], 'http') === 0) { + $this->identity = $this->claimed_id = $headers[$name]; + } elseif($headers[$name][0] == '/') { + $parsed_url = parse_url($this->claimed_id); + $this->identity = + $this->claimed_id = $parsed_url['scheme'] . '://' + . $parsed_url['host'] + . $headers[$name]; + } + } + } + } + return $headers; + } + + protected function request_streams($url, $method='GET', $params=array(), $update_claimed_id) + { + if(!$this->hostExists($url)) { + throw new ErrorException("Could not connect to $url.", 404); + } + + if (empty($this->cnmatch)) { + $this->cnmatch = parse_url($url, PHP_URL_HOST); + } + + $params = http_build_query($params, '', '&'); + switch($method) { + case 'GET': + $opts = array( + 'http' => array( + 'method' => 'GET', + 'header' => 'Accept: application/xrds+xml, */*', + 'user_agent' => $this->user_agent, + 'ignore_errors' => true, + ), + 'ssl' => array( + 'CN_match' => $this->cnmatch + ) + ); + $url = $url . ($params ? '?' . $params : ''); + if (!empty($this->proxy)) { + $opts['http']['proxy'] = $this->proxy_url(); + } + break; + case 'POST': + $opts = array( + 'http' => array( + 'method' => 'POST', + 'header' => 'Content-type: application/x-www-form-urlencoded', + 'user_agent' => $this->user_agent, + 'content' => $params, + 'ignore_errors' => true, + ), + 'ssl' => array( + 'CN_match' => $this->cnmatch + ) + ); + if (!empty($this->proxy)) { + $opts['http']['proxy'] = $this->proxy_url(); + } + break; + case 'HEAD': + // We want to send a HEAD request, but since get_headers() doesn't + // accept $context parameter, we have to change the defaults. + $default = stream_context_get_options(stream_context_get_default()); + + // PHP does not reset all options. Instead, it just sets the options + // available in the passed array, therefore set the defaults manually. + $default += array( + 'http' => array(), + 'ssl' => array() + ); + $default['http'] += array( + 'method' => 'GET', + 'header' => '', + 'user_agent' => '', + 'ignore_errors' => false + ); + $default['ssl'] += array( + 'CN_match' => '' + ); + + $opts = array( + 'http' => array( + 'method' => 'HEAD', + 'header' => 'Accept: application/xrds+xml, */*', + 'user_agent' => $this->user_agent, + 'ignore_errors' => true, + ), + 'ssl' => array( + 'CN_match' => $this->cnmatch + ) + ); + + // Enable validation of the SSL certificates. + if ($this->verify_peer) { + $default['ssl'] += array( + 'verify_peer' => false, + 'capath' => '', + 'cafile' => '' + ); + $opts['ssl'] += array( + 'verify_peer' => true, + 'capath' => $this->capath, + 'cafile' => $this->cainfo + ); + } + + // Change the stream context options. + stream_context_get_default($opts); + + $headers = get_headers($url . ($params ? '?' . $params : '')); + + // Restore the stream context options. + stream_context_get_default($default); + + if (!empty($headers)) { + if (intval(substr($headers[0], strlen('HTTP/1.1 '))) == 405) { + // The server doesn't support HEAD - emulate it with a GET. + $args = func_get_args(); + $args[1] = 'GET'; + call_user_func_array(array($this, 'request_streams'), $args); + $headers = $this->headers; + } else { + $headers = $this->parse_header_array($headers, $update_claimed_id); + } + } else { + $headers = array(); + } + + return $headers; + } + + if ($this->verify_peer) { + $opts['ssl'] += array( + 'verify_peer' => true, + 'capath' => $this->capath, + 'cafile' => $this->cainfo + ); + } + + $context = stream_context_create ($opts); + $data = file_get_contents($url, false, $context); + # This is a hack for providers who don't support HEAD requests. + # It just creates the headers array for the last request in $this->headers. + if(isset($http_response_header)) { + $this->headers = $this->parse_header_array($http_response_header, $update_claimed_id); + } + + return $data; + } + + protected function request($url, $method='GET', $params=array(), $update_claimed_id=false) + { + $use_curl = false; + + if (function_exists('curl_init')) { + if (!$use_curl) { + # When allow_url_fopen is disabled, PHP streams will not work. + $use_curl = !ini_get('allow_url_fopen'); + } + + if (!$use_curl) { + # When there is no HTTPS wrapper, PHP streams cannott be used. + $use_curl = !in_array('https', stream_get_wrappers()); + } + + if (!$use_curl) { + # With open_basedir or safe_mode set, cURL can't follow redirects. + $use_curl = !(ini_get('safe_mode') || ini_get('open_basedir')); + } + } + + return + $use_curl + ? $this->request_curl($url, $method, $params, $update_claimed_id) + : $this->request_streams($url, $method, $params, $update_claimed_id); + } + + protected function proxy_url() + { + $result = ''; + + if (!empty($this->proxy)) { + $result = $this->proxy['host']; + + if (!empty($this->proxy['port'])) { + $result = $result . ':' . $this->proxy['port']; + } + + if (!empty($this->proxy['user'])) { + $result = $this->proxy['user'] . ':' . $this->proxy['pass'] . '@' . $result; + } + + $result = 'http://' . $result; + } + + return $result; + } + + protected function build_url($url, $parts) + { + if (isset($url['query'], $parts['query'])) { + $parts['query'] = $url['query'] . '&' . $parts['query']; + } + + $url = $parts + $url; + $url = $url['scheme'] . '://' + . (empty($url['username'])?'' + :(empty($url['password'])? "{$url['username']}@" + :"{$url['username']}:{$url['password']}@")) + . $url['host'] + . (empty($url['port'])?'':":{$url['port']}") + . (empty($url['path'])?'':$url['path']) + . (empty($url['query'])?'':"?{$url['query']}") + . (empty($url['fragment'])?'':"#{$url['fragment']}"); + return $url; + } + + /** + * Helper function used to scan for / tags and extract information + * from them + */ + protected function htmlTag($content, $tag, $attrName, $attrValue, $valueName) + { + preg_match_all("#<{$tag}[^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*$valueName=['\"](.+?)['\"][^>]*/?>#i", $content, $matches1); + preg_match_all("#<{$tag}[^>]*$valueName=['\"](.+?)['\"][^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*/?>#i", $content, $matches2); + + $result = array_merge($matches1[1], $matches2[1]); + return empty($result)?false:$result[0]; + } + + /** + * Performs Yadis and HTML discovery. Normally not used. + * @param $url Identity URL. + * @return String OP Endpoint (i.e. OpenID provider address). + * @throws ErrorException + */ + function discover($url) + { + if (!$url) throw new ErrorException('No identity supplied.'); + # Use xri.net proxy to resolve i-name identities + if (!preg_match('#^https?:#', $url)) { + $url = "https://xri.net/$url"; + } + + # We save the original url in case of Yadis discovery failure. + # It can happen when we'll be lead to an XRDS document + # which does not have any OpenID2 services. + $originalUrl = $url; + + # A flag to disable yadis discovery in case of failure in headers. + $yadis = true; + + # Allows optional regex replacement of the URL, e.g. to use Google Apps + # as an OpenID provider without setting up XRDS on the domain hosting. + if (!is_null($this->xrds_override_pattern) && !is_null($this->xrds_override_replacement)) { + $url = preg_replace($this->xrds_override_pattern, $this->xrds_override_replacement, $url); + } + + # We'll jump a maximum of 5 times, to avoid endless redirections. + for ($i = 0; $i < 5; $i ++) { + if ($yadis) { + $headers = $this->request($url, 'HEAD', array(), true); + + $next = false; + if (isset($headers['x-xrds-location'])) { + $url = $this->build_url(parse_url($url), parse_url(trim($headers['x-xrds-location']))); + $next = true; + } + + if (isset($headers['content-type']) && $this->is_allowed_type($headers['content-type'])) { + # Found an XRDS document, now let's find the server, and optionally delegate. + $content = $this->request($url, 'GET'); + + preg_match_all('#(.*?)#s', $content, $m); + foreach($m[1] as $content) { + $content = ' ' . $content; # The space is added, so that strpos doesn't return 0. + + # OpenID 2 + $ns = preg_quote('http://specs.openid.net/auth/2.0/', '#'); + if(preg_match('#\s*'.$ns.'(server|signon)\s*#s', $content, $type)) { + if ($type[1] == 'server') $this->identifier_select = true; + + preg_match('#(.*)#', $content, $server); + preg_match('#<(Local|Canonical)ID>(.*)#', $content, $delegate); + if (empty($server)) { + return false; + } + # Does the server advertise support for either AX or SREG? + $this->ax = (bool) strpos($content, 'http://openid.net/srv/ax/1.0'); + $this->sreg = strpos($content, 'http://openid.net/sreg/1.0') + || strpos($content, 'http://openid.net/extensions/sreg/1.1'); + + $server = $server[1]; + if (isset($delegate[2])) $this->identity = trim($delegate[2]); + $this->version = 2; + + $this->server = $server; + return $server; + } + + # OpenID 1.1 + $ns = preg_quote('http://openid.net/signon/1.1', '#'); + if (preg_match('#\s*'.$ns.'\s*#s', $content)) { + + preg_match('#(.*)#', $content, $server); + preg_match('#<.*?Delegate>(.*)#', $content, $delegate); + if (empty($server)) { + return false; + } + # AX can be used only with OpenID 2.0, so checking only SREG + $this->sreg = strpos($content, 'http://openid.net/sreg/1.0') + || strpos($content, 'http://openid.net/extensions/sreg/1.1'); + + $server = $server[1]; + if (isset($delegate[1])) $this->identity = $delegate[1]; + $this->version = 1; + + $this->server = $server; + return $server; + } + } + + $next = true; + $yadis = false; + $url = $originalUrl; + $content = null; + break; + } + if ($next) continue; + + # There are no relevant information in headers, so we search the body. + $content = $this->request($url, 'GET', array(), true); + + if (isset($this->headers['x-xrds-location'])) { + $url = $this->build_url(parse_url($url), parse_url(trim($this->headers['x-xrds-location']))); + continue; + } + + $location = $this->htmlTag($content, 'meta', 'http-equiv', 'X-XRDS-Location', 'content'); + if ($location) { + $url = $this->build_url(parse_url($url), parse_url($location)); + continue; + } + } + + if (!$content) $content = $this->request($url, 'GET'); + + # At this point, the YADIS Discovery has failed, so we'll switch + # to openid2 HTML discovery, then fallback to openid 1.1 discovery. + $server = $this->htmlTag($content, 'link', 'rel', 'openid2.provider', 'href'); + $delegate = $this->htmlTag($content, 'link', 'rel', 'openid2.local_id', 'href'); + $this->version = 2; + + if (!$server) { + # The same with openid 1.1 + $server = $this->htmlTag($content, 'link', 'rel', 'openid.server', 'href'); + $delegate = $this->htmlTag($content, 'link', 'rel', 'openid.delegate', 'href'); + $this->version = 1; + } + + if ($server) { + # We found an OpenID2 OP Endpoint + if ($delegate) { + # We have also found an OP-Local ID. + $this->identity = $delegate; + } + $this->server = $server; + return $server; + } + + throw new ErrorException("No OpenID Server found at $url", 404); + } + throw new ErrorException('Endless redirection!', 500); + } + + protected function is_allowed_type($content_type) { + # Apparently, some providers return XRDS documents as text/html. + # While it is against the spec, allowing this here shouldn't break + # compatibility with anything. + $allowed_types = array('application/xrds+xml', 'text/html', 'text/xml'); + + foreach ($allowed_types as $type) { + if (strpos($content_type, $type) !== false) { + return true; + } + } + + return false; + } + + protected function sregParams() + { + $params = array(); + # We always use SREG 1.1, even if the server is advertising only support for 1.0. + # That's because it's fully backwards compatibile with 1.0, and some providers + # advertise 1.0 even if they accept only 1.1. One such provider is myopenid.com + $params['openid.ns.sreg'] = 'http://openid.net/extensions/sreg/1.1'; + if ($this->required) { + $params['openid.sreg.required'] = array(); + foreach ($this->required as $required) { + if (!isset(self::$ax_to_sreg[$required])) continue; + $params['openid.sreg.required'][] = self::$ax_to_sreg[$required]; + } + $params['openid.sreg.required'] = implode(',', $params['openid.sreg.required']); + } + + if ($this->optional) { + $params['openid.sreg.optional'] = array(); + foreach ($this->optional as $optional) { + if (!isset(self::$ax_to_sreg[$optional])) continue; + $params['openid.sreg.optional'][] = self::$ax_to_sreg[$optional]; + } + $params['openid.sreg.optional'] = implode(',', $params['openid.sreg.optional']); + } + return $params; + } + + protected function axParams() + { + $params = array(); + if ($this->required || $this->optional) { + $params['openid.ns.ax'] = 'http://openid.net/srv/ax/1.0'; + $params['openid.ax.mode'] = 'fetch_request'; + $this->aliases = array(); + $counts = array(); + $required = array(); + $optional = array(); + foreach (array('required','optional') as $type) { + foreach ($this->$type as $alias => $field) { + if (is_int($alias)) $alias = strtr($field, '/', '_'); + $this->aliases[$alias] = 'http://axschema.org/' . $field; + if (empty($counts[$alias])) $counts[$alias] = 0; + $counts[$alias] += 1; + ${$type}[] = $alias; + } + } + foreach ($this->aliases as $alias => $ns) { + $params['openid.ax.type.' . $alias] = $ns; + } + foreach ($counts as $alias => $count) { + if ($count == 1) continue; + $params['openid.ax.count.' . $alias] = $count; + } + + # Don't send empty ax.requied and ax.if_available. + # Google and possibly other providers refuse to support ax when one of these is empty. + if($required) { + $params['openid.ax.required'] = implode(',', $required); + } + if($optional) { + $params['openid.ax.if_available'] = implode(',', $optional); + } + } + return $params; + } + + protected function authUrl_v1($immediate) + { + $returnUrl = $this->returnUrl; + # If we have an openid.delegate that is different from our claimed id, + # we need to somehow preserve the claimed id between requests. + # The simplest way is to just send it along with the return_to url. + if($this->identity != $this->claimed_id) { + $returnUrl .= (strpos($returnUrl, '?') ? '&' : '?') . 'openid.claimed_id=' . $this->claimed_id; + } + + $params = array( + 'openid.return_to' => $returnUrl, + 'openid.mode' => $immediate ? 'checkid_immediate' : 'checkid_setup', + 'openid.identity' => $this->identity, + 'openid.trust_root' => $this->trustRoot, + ) + $this->sregParams(); + + return $this->build_url(parse_url($this->server) + , array('query' => http_build_query($params, '', '&'))); + } + + protected function authUrl_v2($immediate) + { + $params = array( + 'openid.ns' => 'http://specs.openid.net/auth/2.0', + 'openid.mode' => $immediate ? 'checkid_immediate' : 'checkid_setup', + 'openid.return_to' => $this->returnUrl, + 'openid.realm' => $this->trustRoot, + ); + + if ($this->ax) { + $params += $this->axParams(); + } + + if ($this->sreg) { + $params += $this->sregParams(); + } + + if (!$this->ax && !$this->sreg) { + # If OP doesn't advertise either SREG, nor AX, let's send them both + # in worst case we don't get anything in return. + $params += $this->axParams() + $this->sregParams(); + } + + if (!empty($this->oauth) && is_array($this->oauth)) { + $params['openid.ns.oauth'] = 'http://specs.openid.net/extensions/oauth/1.0'; + $params['openid.oauth.consumer'] = str_replace(array('http://', 'https://'), '', $this->trustRoot); + $params['openid.oauth.scope'] = implode(' ', $this->oauth); + } + + if ($this->identifier_select) { + $params['openid.identity'] = $params['openid.claimed_id'] + = 'http://specs.openid.net/auth/2.0/identifier_select'; + } else { + $params['openid.identity'] = $this->identity; + $params['openid.claimed_id'] = $this->claimed_id; + } + + return $this->build_url(parse_url($this->server) + , array('query' => http_build_query($params, '', '&'))); + } + + /** + * Returns authentication url. Usually, you want to redirect your user to it. + * @return String The authentication url. + * @param String $select_identifier Whether to request OP to select identity for an user in OpenID 2. Does not affect OpenID 1. + * @throws ErrorException + */ + function authUrl($immediate = false) + { + if ($this->setup_url && !$immediate) return $this->setup_url; + if (!$this->server) $this->discover($this->identity); + + if ($this->version == 2) { + return $this->authUrl_v2($immediate); + } + return $this->authUrl_v1($immediate); + } + + /** + * Performs OpenID verification with the OP. + * @return Bool Whether the verification was successful. + * @throws ErrorException + */ + function validate() + { + # If the request was using immediate mode, a failure may be reported + # by presenting user_setup_url (for 1.1) or reporting + # mode 'setup_needed' (for 2.0). Also catching all modes other than + # id_res, in order to avoid throwing errors. + if(isset($this->data['openid_user_setup_url'])) { + $this->setup_url = $this->data['openid_user_setup_url']; + return false; + } + if($this->mode != 'id_res') { + return false; + } + + $this->claimed_id = isset($this->data['openid_claimed_id'])?$this->data['openid_claimed_id']:$this->data['openid_identity']; + $params = array( + 'openid.assoc_handle' => $this->data['openid_assoc_handle'], + 'openid.signed' => $this->data['openid_signed'], + 'openid.sig' => $this->data['openid_sig'], + ); + + if (isset($this->data['openid_ns'])) { + # We're dealing with an OpenID 2.0 server, so let's set an ns + # Even though we should know location of the endpoint, + # we still need to verify it by discovery, so $server is not set here + $params['openid.ns'] = 'http://specs.openid.net/auth/2.0'; + } elseif (isset($this->data['openid_claimed_id']) + && $this->data['openid_claimed_id'] != $this->data['openid_identity'] + ) { + # If it's an OpenID 1 provider, and we've got claimed_id, + # we have to append it to the returnUrl, like authUrl_v1 does. + $this->returnUrl .= (strpos($this->returnUrl, '?') ? '&' : '?') + . 'openid.claimed_id=' . $this->claimed_id; + } + + if ($this->data['openid_return_to'] != $this->returnUrl) { + # The return_to url must match the url of current request. + # I'm assuing that noone will set the returnUrl to something that doesn't make sense. + return false; + } + + $server = $this->discover($this->claimed_id); + + foreach (explode(',', $this->data['openid_signed']) as $item) { + # Checking whether magic_quotes_gpc is turned on, because + # the function may fail if it is. For example, when fetching + # AX namePerson, it might containg an apostrophe, which will be escaped. + # In such case, validation would fail, since we'd send different data than OP + # wants to verify. stripslashes() should solve that problem, but we can't + # use it when magic_quotes is off. + $value = $this->data['openid_' . str_replace('.','_',$item)]; + $params['openid.' . $item] = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() ? stripslashes($value) : $value; + + } + + $params['openid.mode'] = 'check_authentication'; + + $response = $this->request($server, 'POST', $params); + + return preg_match('/is_valid\s*:\s*true/i', $response); + } + + protected function getAxAttributes() + { + $result = array(); + + if ($alias = $this->getNamespaceAlias('http://openid.net/srv/ax/1.0', 'ax')) { + $prefix = 'openid_' . $alias; + $length = strlen('http://axschema.org/'); + + foreach (explode(',', $this->data['openid_signed']) as $key) { + $keyMatch = $alias . '.type.'; + + if (strncmp($key, $keyMatch, strlen($keyMatch)) !== 0) { + continue; + } + + $key = substr($key, strlen($keyMatch)); + $idv = $prefix . '_value_' . $key; + $idc = $prefix . '_count_' . $key; + $key = substr($this->getItem($prefix . '_type_' . $key), $length); + + if (!empty($key)) { + if (($count = intval($this->getItem($idc))) > 0) { + $value = array(); + + for ($i = 1; $i <= $count; $i++) { + $value[] = $this->getItem($idv . '_' . $i); + } + + $value = ($count == 1) ? reset($value) : $value; + } else { + $value = $this->getItem($idv); + } + + if (!is_null($value)) { + $result[$key] = $value; + } + } + } + } else { + // No alias for the AX schema has been found, + // so there is no AX data in the OP's response. + } + + return $result; + } + + protected function getSregAttributes() + { + $attributes = array(); + $sreg_to_ax = array_flip(self::$ax_to_sreg); + foreach (explode(',', $this->data['openid_signed']) as $key) { + $keyMatch = 'sreg.'; + if (strncmp($key, $keyMatch, strlen($keyMatch)) !== 0) { + continue; + } + $key = substr($key, strlen($keyMatch)); + if (!isset($sreg_to_ax[$key])) { + # The field name isn't part of the SREG spec, so we ignore it. + continue; + } + $attributes[$sreg_to_ax[$key]] = $this->data['openid_sreg_' . $key]; + } + return $attributes; + } + + /** + * Gets AX/SREG attributes provided by OP. should be used only after successful validaton. + * Note that it does not guarantee that any of the required/optional parameters will be present, + * or that there will be no other attributes besides those specified. + * In other words. OP may provide whatever information it wants to. + * * SREG names will be mapped to AX names. + * * @return Array Array of attributes with keys being the AX schema names, e.g. 'contact/email' + * @see http://www.axschema.org/types/ + */ + function getAttributes() + { + if (isset($this->data['openid_ns']) + && $this->data['openid_ns'] == 'http://specs.openid.net/auth/2.0' + ) { # OpenID 2.0 + # We search for both AX and SREG attributes, with AX taking precedence. + return $this->getAxAttributes() + $this->getSregAttributes(); + } + return $this->getSregAttributes(); + } + + /** + * Gets an OAuth request token if the OpenID+OAuth hybrid protocol has been used. + * + * In order to use the OpenID+OAuth hybrid protocol, you need to add at least one + * scope to the $openid->oauth array before you get the call to getAuthUrl(), e.g.: + * $openid->oauth[] = 'https://www.googleapis.com/auth/plus.me'; + * + * Furthermore the registered consumer name must fit the OpenID realm. + * To register an OpenID consumer at Google use: https://www.google.com/accounts/ManageDomains + * + * @return string|bool OAuth request token on success, FALSE if no token was provided. + */ + function getOAuthRequestToken() + { + $alias = $this->getNamespaceAlias('http://specs.openid.net/extensions/oauth/1.0'); + + return !empty($alias) ? $this->data['openid_' . $alias . '_request_token'] : false; + } + + /** + * Gets the alias for the specified namespace, if it's present. + * + * @param string $namespace The namespace for which an alias is needed. + * @param string $hint Common alias of this namespace, used for optimization. + * @return string|null The namespace alias if found, otherwise - NULL. + */ + private function getNamespaceAlias($namespace, $hint = null) + { + $result = null; + + if (empty($hint) || $this->getItem('openid_ns_' . $hint) != $namespace) { + // The common alias is either undefined or points to + // some other extension - search for another alias.. + $prefix = 'openid_ns_'; + $length = strlen($prefix); + + foreach ($this->data as $key => $val) { + if (strncmp($key, $prefix, $length) === 0 && $val === $namespace) { + $result = trim(substr($key, $length)); + break; + } + } + } else { + $result = $hint; + } + + return $result; + } + + /** + * Gets an item from the $data array by the specified id. + * + * @param string $id The id of the desired item. + * @return string|null The item if found, otherwise - NULL. + */ + private function getItem($id) + { + return isset($this->data[$id]) ? $this->data[$id] : null; + } +} diff --git a/plugin/social/Hybrid/thirdparty/index.html b/plugin/social/Hybrid/thirdparty/index.html new file mode 100644 index 000000000..c942a79ce --- /dev/null +++ b/plugin/social/Hybrid/thirdparty/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

      Directory access is forbidden.

      + + + \ No newline at end of file diff --git a/plugin/social/_common.php b/plugin/social/_common.php new file mode 100644 index 000000000..bad54a5d7 --- /dev/null +++ b/plugin/social/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/plugin/social/config.php b/plugin/social/config.php new file mode 100644 index 000000000..c6816b840 --- /dev/null +++ b/plugin/social/config.php @@ -0,0 +1,63 @@ + "http://localhost/hybridauth-git/hybridauth/", + "providers" => array( + // openid providers + "OpenID" => array( + "enabled" => true, + ), + "Yahoo" => array( + "enabled" => true, + "keys" => array("id" => "", "secret" => ""), + ), + "AOL" => array( + "enabled" => true, + ), + "Google" => array( + "enabled" => true, + "keys" => array("id" => "", "secret" => ""), + ), + "Facebook" => array( + "enabled" => true, + "keys" => array("id" => "", "secret" => ""), + "trustForwarded" => false, + ), + "Twitter" => array( + "enabled" => true, + "keys" => array("key" => "", "secret" => ""), + "includeEmail" => false, + ), + // windows live + "Live" => array( + "enabled" => true, + "keys" => array("id" => "", "secret" => ""), + ), + "LinkedIn" => array( + "enabled" => true, + "keys" => array("id" => "", "secret" => ""), + "fields" => array(), + ), + "Foursquare" => array( + "enabled" => true, + "keys" => array("id" => "", "secret" => ""), + ), + ), + // If you want to enable logging, set 'debug_mode' to true. + // You can also set it to + // - "error" To log only error messages. Useful in production + // - "info" To log info and error messages (ignore debug messages) + "debug_mode" => false, + // Path to file writable by the web server. Required if 'debug_mode' is not false + "debug_file" => "", +); diff --git a/plugin/social/error.php b/plugin/social/error.php new file mode 100644 index 000000000..13aa20acf --- /dev/null +++ b/plugin/social/error.php @@ -0,0 +1,68 @@ + + + + + + + 소셜 로그인 - <?php echo $provider; ?> + + + + + +
      +

      Error :

      + +
      + 10) ){ ?> +

      잠시후에 다시 시도해 주세요.

      + + 홈으로 + +
      +
      + + + + \ No newline at end of file diff --git a/plugin/social/img/loading_icon.gif b/plugin/social/img/loading_icon.gif new file mode 100644 index 000000000..3fcf2bd78 Binary files /dev/null and b/plugin/social/img/loading_icon.gif differ diff --git a/plugin/social/includes/functions.php b/plugin/social/includes/functions.php new file mode 100644 index 000000000..ed06441ec --- /dev/null +++ b/plugin/social/includes/functions.php @@ -0,0 +1,1039 @@ +getSessionData(); + + if( defined('G5_SOCIAL_LOGIN_START_PARAM') && G5_SOCIAL_LOGIN_START_PARAM === 'hauth.start' && G5_SOCIAL_LOGIN_DONE_PARAM === 'hauth.done' ){ + return $g5['hybrid_auth']->authenticate($provider); + } + + $base_url = G5_SOCIAL_LOGIN_BASE_URL; + $hauth_time = time(); + + $connect_data = array( + 'login_start' => $base_url . ( strpos($base_url, '?') ? '&' : '?' ) . G5_SOCIAL_LOGIN_START_PARAM.'='.$provider.'&hauth.time='.$hauth_time, + 'login_done' => $base_url . ( strpos($base_url, '?') ? '&' : '?' ) . G5_SOCIAL_LOGIN_DONE_PARAM.'='.$provider, + ); + + return $g5['hybrid_auth']->authenticate($provider, $connect_data); +} + +function social_before_join_check($url=''){ + global $g5, $config; + + if( $provider_name = social_get_request_provider() ){ + //재가입 방지 + if( $user_profile = social_session_exists_check() ){ + + $sql = sprintf("select * from {$g5['social_profile_table']} where provider = '%s' and identifier = '%s' ", $provider_name, $user_profile->identifier); + + $is_exist = false; + + $row = sql_fetch($sql); + + if( $row['provider'] ){ + $is_exist = true; + + $time = time() - (86400 * (int) G5_SOCIAL_DELETE_DAY); + + if( empty($row['mb_id']) && ( 0 == G5_SOCIAL_DELETE_DAY || strtotime($row['mp_latest_day']) < $time) ){ + + $sql = "delete from {$g5['social_profile_table']} where mp_no =".$row['mp_no']; + + sql_query($sql); + + $is_exist = false; + } + } + + if( $is_exist ){ + $msg = sprintf("해당 %s ID 로 연결 또는 가입된 내역이 있기 때문에 다시 가입할수 없습니다. 회원이시면 로그인 후 정보 수정에서 계정 연결을 해 주세요.", social_get_provider_service_name($provider_name) ); + + $url = $url ? $url : G5_URL; + alert($msg, $url); + return false; + } + } + + return true; + } + + return false; +} + +function social_get_data($by='provider', $provider, $user_profile){ + global $g5; + + // 소셜 가입이 되어 있는지 체크 + if( $by == 'provider' ){ + + $sql = sprintf("select * from {$g5['social_profile_table']} where provider = '%s' and identifier = '%s' order by mb_id desc ", $provider, $user_profile->identifier); + + $row = sql_fetch($sql); + + if( !empty($row['mb_id']) ){ + return $row; //mb_id 가 있는 경우에만 데이터를 리턴합니다. + } + + return false; + + } else if ( $by == 'member' ){ // 아이디 또는 이메일이나 별명으로 이미 가입되어 있는지 체크 + + $email = ($user_profile->emailVerified) ? $user_profile->emailVerified : $user_profile->email; + $sid = preg_match("/[^0-9a-z_]+/i", "", $user_profile->sid); + $nick = social_relace_nick($user_profile->displayName); + if( !$nick ){ + $tmp = explode("@", $email); + $nick = $tmp[0]; + } + + $sql = "select mb_nick, mb_email from {$g5['member_table']} where mb_nick = '".$nick."' "; + + if( !empty($email) ){ + $sql .= sprintf(" or mb_email = '%s' ", $email); + } + + $result = sql_query($sql); + + $exists = array(); + + while($row=sql_fetch_array($result)){ + if($row['mb_nick'] && $row['mb_nick'] == $nick){ + $exists['mb_nick'] = $nick; + } + if($row['mb_email'] && $row['mb_email'] == $email){ + $exists['mb_email'] = $email; + } + } + + return $exists; + + } + + return null; +} + +function social_user_profile_replace( $mb_id, $provider, $profile ){ + global $g5; + + if( !$mb_id ) + return; + + // $profile 에 성별, 나이, 생일 등의 정보가 포함되어 있습니다. + + //받아온 정보를 암호화 하여 + $object_sha = sha1( serialize( $profile ) ); + + $provider = strtolower($provider); + + $sql = sprintf("SELECT mp_no, mb_id from {$g5['social_profile_table']} where provider= '%s' and identifier = '%s' ", $provider, $profile->identifier); + $result = sql_query($sql); + for($i=0;$row=sql_fetch_array($result);$i++){ //혹시 맞지 않는 데이터가 있으면 삭제합니다. + if( $row['mb_id'] != $mb_id ){ + sql_query(sprintf("DELETE FROM {$g5['social_profile_table']} where mp_no=%d", $row['mp_no'])); + } + } + + $sql = sprintf("SELECT mp_no, object_sha, mp_register_day from {$g5['social_profile_table']} where mb_id= '%s' and provider= '%s' and identifier = '%s' ", $mb_id, $provider, $profile->identifier); + + $row = sql_fetch($sql); + + $table_data = array( + "mp_no" => ! empty($row) ? $row['mp_no'] : 'NULL', + 'mb_id' => "'". $mb_id. "'", + 'provider' => "'". $provider . "'", + 'object_sha' => "'". $object_sha . "'", + 'mp_register_day' => ! empty($row) ? "'".$row['mp_register_day']."'" : "'". G5_TIME_YMDHIS . "'", + 'mp_latest_day' => "'". G5_TIME_YMDHIS . "'", + ); + + $fields = array( + 'identifier', + 'profileurl', + 'photourl', + 'displayname', + 'description', + ); + + foreach( (array) $profile as $key => $value ){ + $key = strtolower($key); + + if( in_array( $key, $fields ) ) + { + $value = (string) $value; + $table_data[ $key ] = "'". sql_real_escape_string($value). "'"; + } + } + + $fields = '`' . implode( '`, `', array_keys( $table_data ) ) . '`'; + $values = implode( ", ", array_values( $table_data ) ); + + $sql = "REPLACE INTO {$g5['social_profile_table']} ($fields) VALUES ($values) "; + + sql_query($sql); + + return sql_insert_id(); + +} + +function social_build_provider_config($provider){ + $setting = array( + 'base_url' => https_url(G5_PLUGIN_DIR.'/'.G5_SOCIAL_LOGIN_DIR).'/', + 'providers' => array( + $provider => array( + 'enabled' => true, + 'keys' => array( 'id' => null, 'key' => null, 'secret' => null ) + ) + ), + ); + + if( function_exists('social_extends_get_keys') ){ + $setting["providers"][$provider] = social_extends_get_keys($provider); + } + + return $setting; +} + +function social_extends_get_keys($provider){ + + global $config; + + static $r = array(); + + if ( empty($r) ) { + + // Naver + $r['Naver'] = array( + "enabled" => option_array_checked('naver', $config['cf_social_servicelist']) ? true : false, + "redirect_uri" => get_social_callbackurl('naver'), + "keys" => array( + "id" => $config['cf_naver_clientid'], + "secret" => $config['cf_naver_secret'], + ), + ); + + // Kakao + $r['Kakao'] = array( + "enabled" => option_array_checked('kakao', $config['cf_social_servicelist']) ? true : false, + "keys" => array("id" => $config['cf_kakao_rest_key'], + "secret" => $config['cf_kakao_client_secret'] ? $config['cf_kakao_client_secret'] : $config['cf_kakao_rest_key'] + ), + "redirect_uri" => get_social_callbackurl('kakao') + ); + + // Facebook + $r['Facebook'] = array( + "enabled" => option_array_checked('facebook', $config['cf_social_servicelist']) ? true : false, + "keys" => array("id" => $config['cf_facebook_appid'], "secret" => $config['cf_facebook_secret']), + "display" => "popup", + "redirect_uri" => get_social_callbackurl('facebook'), + "scope" => array('email'), // optional + "trustForwarded" => false + ); + + // Google + $r['Google'] = array( + "enabled" => option_array_checked('google', $config['cf_social_servicelist']) ? true : false, + "keys" => array("id" => $config['cf_google_clientid'], + "secret" => $config['cf_google_secret']), + "redirect_uri" => get_social_callbackurl('google'), + "scope" => "https://www.googleapis.com/auth/plus.login ". // optional + "https://www.googleapis.com/auth/plus.me ". // optional + "https://www.googleapis.com/auth/plus.profile.emails.read", // optional + //"access_type" => "offline", // optional + //"approval_prompt" => "force", // optional + ); + + // Twitter + $r['Twitter'] = array( + "enabled" => option_array_checked('twitter', $config['cf_social_servicelist']) ? true : false, + "keys" => array("key" => $config['cf_twitter_key'], "secret" => $config['cf_twitter_secret']), + "redirect_uri" => get_social_callbackurl('twitter'), + "trustForwarded" => false + ); + + // Payco + $r['Payco'] = array( + "enabled" => option_array_checked('payco', $config['cf_social_servicelist']) ? true : false, + "keys" => array("id" => $config['cf_payco_clientid'], "secret" => $config['cf_payco_secret']), + "redirect_uri" => get_social_callbackurl('payco'), + "trustForwarded" => false + ); + } + + return $r[$provider]; +} + +function social_escape_request($request){ + return clean_xss_tags( strip_tags($request) ); +} + +function social_get_request_provider(){ + $provider_name = isset($_REQUEST['provider']) ? ucfirst(social_escape_request($_REQUEST['provider'])) : ''; + + return $provider_name; +} + +function social_login_session_clear($mycf=0){ + $_SESSION["HA::STORE"] = array(); // used by hybridauth library. to clear as soon as the auth process ends. + $_SESSION["HA::CONFIG"] = array(); // used by hybridauth library. to clear as soon as the auth process ends. + set_session('sl_userprofile', ''); + set_session('social_login_redirect', ''); + if(!$mycf){ + set_session('ss_social_provider', ''); + } +} + +function social_session_exists_check(){ + + $provider_name = social_get_request_provider(); + + if(!$provider_name){ + return false; + } + + if( $provider_name && isset($_SESSION['HA::STORE']['hauth_session.'.strtolower($provider_name).'.is_logged_in']) && !empty($_SESSION['sl_userprofile'][$provider_name]) ){ + return json_decode($_SESSION['sl_userprofile'][$provider_name]); + } + + return false; +} + +function social_relace_nick($nick=''){ + + if( empty($nick) ) return ''; + + return preg_replace("/[ #\&\+\-%@=\/\\\:;,\.'\"\^`~\_|\!\?\*$#<>()\[\]\{\}]/i", "", $nick); +} + +function social_get_error_msg($type){ + ob_start(); + + switch( $type ){ + case 0 : echo "지정되지 않은 오류입니다."; break; + case 1 : echo "설정 오류입니다."; break; + case 2 : echo "해당 provider 설정 오류입니다."; break; + case 3 : echo "알수 없거나 비활성화 된 provider 입니다."; break; + case 4 : echo "해당 서비스에 접근할수 있는 권한이 없습니다."; break; + case 5 : echo "인증이 실패되었습니다.. " + . "사용자가 인증을 취소했거나, 공급자가 연결을 거부했습니다."; + break; + case 6 : echo "사용자 프로필 요청이 실패했습니다.사용자가 해당 서비스에 연결되어 있지 않을 경우도 있습니다. " + . "이 경우 다시 인증 요청을 해야 합니다."; + break; + case 7 : echo "사용자가 해당 서비스에 연결되어 있지 않습니다."; + break; + case 8 : echo "해당 서비스가 기능을 지원하지 않습니다."; break; + } + + $get_error = ob_get_clean(); + + return $get_error; +} + +if( !function_exists('replaceQueryParams') ){ + function replaceQueryParams($url, $params) + { + $query = parse_url($url, PHP_URL_QUERY); + parse_str($query, $oldParams); + + if (empty($oldParams)) { + return rtrim($url, '?') . '?' . http_build_query($params); + } + + $params = array_merge($oldParams, $params); + + return preg_replace('#\?.*#', '?' . http_build_query($params), $url); + } +} + +function social_loading_provider_page( $provider ){ + + social_login_session_clear(1); + + define('G5_SOCIAL_IS_LOADING', TRUE ); + + $login_action_url = G5_URL; + + $img_url = G5_SOCIAL_LOGIN_URL.'/img/'; + include_once(G5_SOCIAL_LOGIN_PATH.'/includes/loading.php'); +} + +function social_check_login_before($p_service=''){ + global $is_member, $member; + + $action = isset( $_REQUEST['action'] ) ? social_escape_request($_REQUEST['action']) : ''; + $provider_name = $p_service ? $p_service : social_get_request_provider(); + $url = isset($_REQUEST['url']) ? $_REQUEST['url'] : G5_URL; + $mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : 'login'; + $use_popup = G5_SOCIAL_USE_POPUP ? 1 : 2; + $ss_social_provider = get_session('ss_social_provider'); + + if( $provider_name ){ + + if( ! isset( $_REQUEST["redirect_to_idp"] ) ) + { + return social_loading_provider_page( $provider_name ); + } + + try + { + $adapter = social_login_get_provider_adapter( $provider_name ); + + // then grab the user profile + $user_profile = $adapter->getUserProfile(); + + if( ! (isset($_SESSION['sl_userprofile']) && is_array($_SESSION['sl_userprofile'])) ){ + $_SESSION['sl_userprofile'] = array(); + } + + if( ! $is_member ){ + $_SESSION['sl_userprofile'][$provider_name] = json_encode( $user_profile ); + } + } + + catch( Exception $e ) + { + $get_error = social_get_error_msg( $e->getCode() ); + + if( is_object( $adapter ) ){ + $adapter->logout(); + } + + include_once(G5_SOCIAL_LOGIN_PATH.'/error.php'); + exit; + } + + $register_url = G5_BBS_URL.'/register_form.php?provider='.$provider_name; + $register_action_url = G5_BBS_URL.'/register_form_update.php'; + + $login_action_url = G5_HTTPS_BBS_URL."/login_check.php"; + $mylink = (isset($_REQUEST['mylink']) && !empty($_REQUEST['mylink'])) ? 1 : 0; + + //소셜로 이미 가입 했다면 로그인 처리 합니다. + if( $user_provider = social_get_data('provider', $provider_name, $user_profile) ){ + + if( $is_member ){ + + $msg = "이미 로그인 하셨거나 잘못된 요청입니다."; + + if( $mylink ){ + $msg = "이미 연결된 아이디가 있거나, 잘못된 요청입니다."; + } + + if( $use_popup == 1 || ! $use_popup ){ //팝업이면 + alert_close( $msg ); + } else { + alert( $msg ); + } + + if( is_object( $adapter ) ){ //연결한것은 인증 받은 즉시 로그아웃한다. + social_logout_with_adapter($adapter); + } + exit; + } + + //데이터가 틀리면 데이터를 갱신 후 로그인 처리 합니다. + + $mb_id = $user_provider['mb_id']; + //이미 소셜로 가입된 데이터가 있다면 password를 필요하지 않으니, 패스워드를 무작위 생성하여 넘깁니다. + $mb_password = sha1( str_shuffle( "0123456789abcdefghijklmnoABCDEFGHIJ" ) ); + + echo social_return_from_provider_page( $provider_name, $login_action_url, $mb_id, $mb_password, $url, $use_popup ); + exit; + + //소셜 데이터와 회원데이터가 일치 하는 경우 계정와 연결할지, 새로 계정을 만들지 선택합니다. + } else { + + if( $is_member && !empty($user_profile) ){ //회원이면 + + if( $mylink ){ + + social_user_profile_replace($member['mb_id'], $provider_name, $user_profile); + + if( is_object( $adapter ) ){ //연결한것은 인증 받은 즉시 로그아웃한다. + social_logout_with_adapter($adapter); + } + + // 세션에 소셜정보가 없으면 연결된 소셜서비스를 저장합니다. + if( ! get_session('ss_social_provider') ){ + set_session('ss_social_provider', $provider_name); + } + + if( $use_popup == 1 || ! $use_popup ){ //팝업이면 + ?> + + $provider_name); + + $url = replaceQueryParams($url, $params); + goto_url($url); + } else { + goto_url(G5_URL); + } + } + exit; + } + + goto_url(G5_URL); + } + + if( !( property_exists($user_profile, 'sid') && !empty($user_profile->sid) ) ){ + $msg = '소셜 데이터 오류'; + if( $use_popup == 1 || ! $use_popup ){ //팝업이면 + alert_close($msg); + } else { + alert($msg); + } + } + + /* + * 회원이 아닌 경우에만 아래 실행 + */ + $register_url = G5_SOCIAL_LOGIN_URL.'/register_member.php?provider='.$provider_name; + + if( $url ){ + $register_url .= '&url='.urlencode($url); + } + + if( $use_popup == 1 || ! $use_popup ){ //팝업이면 + ?> + + displayName); + $member['mb_sex'] = $user_profile->gender; + $member['mb_email'] = ($user_profile->emailVerified) ? $user_profile->emailVerified : $user_profile->email; + + } + + return $member; +} + +function social_profile_img_resize($path, $file_url, $width, $height){ + + // getimagesize 경우 php.ini 에서 allow_url_fopen 이 활성화 되어 있어야 원격이미지를 읽어올수 있습니다. + list($w, $h, $ext) = @getimagesize($file_url); + if( $w && $h && $ext ){ + $ratio = max($width/$w, $height/$h); + $h = ceil($height / $ratio); + $x = ($w - $width / $ratio) / 2; + $w = ceil($width / $ratio); + + $tmp = imagecreatetruecolor($width, $height); + + if($ext == 1){ + $image = imagecreatefromgif($file_url); + } else if($ext == 3) { + $image = imagecreatefrompng($file_url); + } else { + $image = imagecreatefromjpeg($file_url); + } + imagecopyresampled($tmp, $image, + 0, 0, + $x, 0, + $width, $height, + $w, $h); + + switch ($ext) { + case '2': + imagejpeg($tmp, $path, 100); + break; + case '3': + imagepng($tmp, $path, 0); + break; + case '1': + imagegif($tmp, $path); + break; + } + + chmod($path, G5_FILE_PERMISSION); + + /* cleanup memory */ + imagedestroy($image); + imagedestroy($tmp); + } +} + +function social_is_login_check(){ + + //소셜 로그인이 맞는지 체크합니다. + if( social_session_exists_check() ){ + return true; + } + + return false; +} + +function social_logout_with_adapter($adapter=null){ + if( is_object( $adapter ) ){ + $adapter->logout(); + } + social_login_session_clear(1); +} + +function social_member_provider_manage(){ + global $member; + + return social_login_link_account($member['mb_id'], false, 'mb_form'); +} + +function social_member_comfirm_redirect(){ + global $is_member; + + if( !$is_member ){ + return; + } + + $provider_name = get_session('ss_social_provider'); + + if( social_get_provider_service_name($provider_name) ){ + + try + { + $adapter = social_login_get_provider_adapter( $provider_name ); + + // then grab the user profile + $user_profile = $adapter->getUserProfile(); + } + + catch( Exception $e ) + { + $get_error = social_get_error_msg( $e->getCode() ); + + if( is_object( $adapter ) ){ + social_logout_with_adapter($adapter); + } + + alert('SNS 사용자 인증에 실패하였습니다.', G5_URL); + } + + if( $user_provider = social_get_data('provider', $provider_name, $user_profile) ){ + + social_login_session_clear(1); + + $url = G5_BBS_URL.'/register_form.php'; + + $social_token = social_nonce_create($provider_name); + set_session('social_link_token', $social_token); + + $params = array('provider'=>$provider_name); + + $url = replaceQueryParams($url, $params); + goto_url($url); + + } + + set_session('ss_social_provider', ''); + alert('잘못된 요청입니다.', G5_URL); + } +} + +function social_is_login_password_check($mb_id){ + global $g5; + + $action = isset($_POST['action']) ? $_POST['action'] : ''; + $provider_name = social_get_request_provider(); + + if(!$mb_id || $action === 'link'){ //아이디가 없거나, 계정 연결이면 + if($action === 'link'){ //계정연결이면 같은 서비스명이 있는 경우 + + $sql = sprintf("select count(*) as num from {$g5['social_profile_table']} where provider = '%s' and mb_id = '%s' ", $provider_name, $mb_id); + + $row = sql_fetch($sql); + if( $row['num'] ){ + alert("해당 계정에 이미 $provider_name ID 가 연결되어 있습니다. 연결을 해제 후 다시 시도해 주세요."); + } + } + return false; + } + + //소셜 로그인이 맞는지 체크합니다. + if( $user_profile = social_session_exists_check() ){ + + // db에 이미 쇼셜 계정이 존재하는 경우에는 + if( $user_provider = social_get_data('provider', $provider_name, $user_profile) ){ + + if($user_provider['mb_id'] == $mb_id) + return true; + } + } + + return false; +} + +//소셜 로그인 후 계정 업데이트 +function social_login_success_after($mb, $link='', $mode='', $tmp_create_info=array()){ + global $g5, $config; + + $provider = social_get_request_provider(); + + if( isset($mb['mb_id']) && !empty($mb['mb_id']) && $provider && $user_profile = social_session_exists_check() ){ + + $mb_id = $mb['mb_id']; + //로그인에 성공 했으면 기존 데이터와 비교하여 틀린 값이 없으면 업데이트 합니다. + social_user_profile_replace($mb_id, $provider, $user_profile); + + //소셜로그인의 provider 이름( naver, kakao, facebook 기타 등등 ) 서비스 이름을 세션에 입력합니다. + set_session('ss_social_provider', $provider); + + //소셜로그인 최초 받아온 세션에 저장된 값을 삭제합니다. + if( isset($_SESSION['sl_userprofile']) && isset($_SESSION['sl_userprofile'][$provider]) ){ + unset($_SESSION['sl_userprofile'][$provider]); + } + + if($mode=='register'){ //회원가입 했다면 + return; + } + + } + + return $link; +} + +function social_login_link_account($mb_id, $is_buffer=false, $is_type=''){ + global $g5, $is_admin, $is_guest, $member, $config; + + if( !$mb_id ) + return; + + $sql = "select * from {$g5['social_profile_table']} where mb_id = '".$mb_id."' "; + + $result = sql_query($sql); + + $my_social_accounts = array(); + + for($i=0;$row=sql_fetch_array($result);$i++){ + $my_social_accounts[] = $row; + } + + if( $is_type === 'get_data' ){ + return $my_social_accounts; + } + + ob_start(); + + if( $is_type === 'mb_form' ) { + + global $urlencode; + + static $social_pop_once; + + $my_provides = array(); + + foreach( $my_social_accounts as $account ){ + $my_provides[] = strtolower($account['provider']); + } + + $self_url = G5_BBS_URL."/login.php"; + + //새창을 사용한다면 + if( G5_SOCIAL_USE_POPUP ) + $self_url = G5_SOCIAL_LOGIN_URL.'/popup.php'; + + include(get_social_skin_path().'/social_u_register_form.skin.php'); + } + + $html = ob_get_clean(); + + if($is_buffer){ + return $html; + } else { + echo $html; + } +} + +function social_get_provider_service_name($provider='', $all=''){ + + $services = array( + 'naver' => '네이버', + 'kakao' => '카카오', + 'daum' => '다음', + 'facebook' => '페이스북', + 'google' => '구글', + 'twitter' => '트위터', + 'payco' => '페이코', + ); + + if( $all ){ + return $services; + } + + $provider = $provider ? strtolower($provider) : ''; + + return ($provider && isset($services[$provider])) ? $services[$provider] : ''; +} + +function social_provider_logout($provider='', $session_delete=1){ + + $provider = $provider ? $provider : get_session('ss_social_provider'); + + if( $provider ){ + + try + { + if( ! class_exists( 'Hybrid_Auth', false ) ) + { + include_once G5_SOCIAL_LOGIN_PATH . "/Hybrid/Auth.php"; + } + + Hybrid_Auth::logoutAllProviders(); + + /* + if( $adapter = social_login_get_provider_adapter( $provider ) ){ + $adapter->logout(); + } + */ + if( $session_delete ) + set_session('ss_social_provider', ''); + } + + catch( Exception $e ){ + if( is_object( $adapter ) ){ + social_logout_with_adapter($adapter); + } + } + } +} + +//회원 연결을 해제하거나 회원 탈퇴시 +function social_member_link_delete($mb_id, $mp_no=''){ + + global $g5; + + if(!$mb_id) + return; + + $mp_no = (int) $mp_no; + + if( G5_SOCIAL_DELETE_DAY > 0 ){ + + //mb_id가 없는 소셜 데이터 중에 해당 기간이 넘어간 db 데이터를 삭제합니다. + $time = date("Y-m-d H:i:s", time() - (86400 * (int) G5_SOCIAL_DELETE_DAY)); + + $sql = "delete from {$g5['social_profile_table']} where mb_id = '' and mp_latest_day < '$time' "; + sql_query($sql); + + $sql = "update {$g5['social_profile_table']} set mb_id='', object_sha='', profileurl='', photourl='', displayname='', mp_latest_day = '".G5_TIME_YMDHIS."' where mb_id= '".$mb_id."'"; + } else { + $sql = "delete from {$g5['social_profile_table']} where mb_id= '".$mb_id."'"; //바로 삭제합니다. + } + + if($mp_no){ + $sql .= " and mp_no=$mp_no"; + } + + sql_query($sql, false); +} + +function social_service_check($provider){ + global $config; + + if( $config['cf_social_servicelist'] && option_array_checked($provider, $config['cf_social_servicelist']) ) { + return true; + } + + return false; +} + +function exist_mb_id_recursive($mb_id){ + static $count = 0; + + $mb_id_add = ($count > 0) ? $mb_id.(string)$count : $mb_id; + + if( ! exist_mb_id($mb_id_add) ){ + return $mb_id_add; + } + + $count++; + return exist_mb_id_recursive($mb_id); +} + +function exist_mb_nick_recursive($mb_nick){ + static $count = 0; + + $mb_nick_add = ($count > 0) ? $mb_nick.(string)$count : $mb_nick; + + if( ! exist_mb_nick($mb_nick_add, '') ){ + return $mb_nick_add; + } + + $count++; + return exist_mb_nick_recursive($mb_nick); +} + +function social_get_nonce($key=''){ + if( $key == 'd' ){ //nonce_duration + return 7200; + } else if ($key == 'n' ){ //nonce_name + return '_nonce'; + } else { + + if( empty($key) ) + $key = social_get_request_provider(); + + $setting = social_build_provider_config($key); + try{ + return sha1($setting['providers'][$key]['secret']); + } catch(Exception $e) { + return ''; + } + } + + return ''; +} + +function social_nonce_create_query_string( $action = '' , $user = '', $provider = '' ){ + if($nonce_key=social_get_nonce('n')){ + return $nonce_key."=".social_nonce_create( $action , $user, $provider ); + } + return ''; +} + +function social_nonce_create( $action = '' , $user='' , $provider = '' ){ + return substr( social_nonce_generate_hash( $action , $user, $provider ), -12, 10); +} + +function social_nonce_is_valid( $nonce , $action = '' , $user='' , $provider = '' ){ + // Nonce generated 0-12 hours ago + if ( substr(social_nonce_generate_hash( $action , $user, $provider ), -12, 10) == $nonce ){ + return true; + } + return false; +} + +function social_nonce_generate_hash( $action='' , $user='', $provider = '' ){ + $i = ceil( time() / ( social_get_nonce('d') / 2 ) ); + return md5( $i . $action . $user . social_get_nonce($provider) ); +} +?> \ No newline at end of file diff --git a/plugin/social/includes/g5_endpoint.php b/plugin/social/includes/g5_endpoint.php new file mode 100644 index 000000000..0eda8063a --- /dev/null +++ b/plugin/social/includes/g5_endpoint.php @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/plugin/social/includes/g5_endpoint_class.php b/plugin/social/includes/g5_endpoint_class.php new file mode 100644 index 000000000..29c8f4304 --- /dev/null +++ b/plugin/social/includes/g5_endpoint_class.php @@ -0,0 +1,32 @@ +dieError( "412 Precondition Failed", $e->getMessage(), $e ); + } + } + + protected function processAuthDone() + { + try { + parent::processAuthDone(); + } + catch( Exception $e ){ + $this->dieError( "410 Gone", $e->getMessage(), $e ); + } + } + + public function dieError( $code, $message, $e ) + { + $get_error = $message; + include_once(G5_SOCIAL_LOGIN_PATH.'/error.php'); + die(); + } +} +?> \ No newline at end of file diff --git a/plugin/social/includes/index.php b/plugin/social/includes/index.php new file mode 100644 index 000000000..e69de29bb diff --git a/plugin/social/includes/loading.php b/plugin/social/includes/loading.php new file mode 100644 index 000000000..61a428427 --- /dev/null +++ b/plugin/social/includes/loading.php @@ -0,0 +1,68 @@ + + + + + + + 소셜 로그인 - <?php echo $provider; ?> + + + + + + + + + + + + +

      Loading...


      에 연결중입니다. 잠시만 기다려주세요.
      + + + + +
      + + + + +
      + + + + + \ No newline at end of file diff --git a/plugin/social/includes/providers.php b/plugin/social/includes/providers.php new file mode 100644 index 000000000..ce196085b --- /dev/null +++ b/plugin/social/includes/providers.php @@ -0,0 +1,244 @@ + "Facebook", + "provider_name" => "Facebook", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "https://developers.facebook.com/apps", + "default_api_scope" => "email, public_profile, user_friends", + + "default_network" => true, + "cat" => "socialnetworks", + ), + ARRAY( + "provider_id" => "Google", + "provider_name" => "Google", + "callback" => true, + "require_client_id" => true, + "new_app_link" => "https://console.developers.google.com", + "default_api_scope" => "profile https://www.googleapis.com/auth/plus.profile.emails.read", + + "default_network" => true, + "cat" => "socialnetworks", + ), + ARRAY( + "provider_id" => "Twitter", + "provider_name" => "Twitter", + "callback" => true, + "new_app_link" => "https://dev.twitter.com/apps", + + "default_network" => true, + "cat" => "microblogging", + ), + ARRAY( + "provider_id" => "WordPress", + "provider_name" => "WordPress", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "https://developer.wordpress.com/apps/new/", + + "cat" => "blogging", + ), + ARRAY( + "provider_id" => "Yahoo", + "provider_name" => "Yahoo!", + "new_app_link" => null, + + "cat" => "pleasedie", + ), + ARRAY( + "provider_id" => "LinkedIn", + "provider_name" => "LinkedIn", + "new_app_link" => "https://www.linkedin.com/secure/developer", + + "cat" => "professional", + ), + ARRAY( + "provider_id" => "Disqus", + "provider_name" => "Disqus", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "https://disqus.com/api/applications/", + + "cat" => "misc", + ), + ARRAY( + "provider_id" => "Instagram", + "provider_name" => "Instagram", + "callback" => true, + "require_client_id" => true, + "new_app_link" => "http://instagr.am/developer/clients/manage/", + + "cat" => "media", + ), + ARRAY( + "provider_id" => "Reddit", + "provider_name" => "Reddit", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "https://ssl.reddit.com/prefs/apps", + + "cat" => "socialnetworks", + ), + ARRAY( + "provider_id" => "Foursquare", + "provider_name" => "Foursquare", + "callback" => true, + "require_client_id" => true, + "new_app_link" => "https://www.foursquare.com/oauth/", + + "cat" => "microblogging", + ), + ARRAY( + "provider_id" => "LastFM", + "provider_name" => "Last.FM", + "new_app_link" => "http://www.lastfm.com/api/account", + + "cat" => "media", + ), + ARRAY( + "provider_id" => "Tumblr", + "provider_name" => "Tumblr", + "new_app_link" => "http://www.tumblr.com/oauth/apps", + + "cat" => "microblogging", // o well + ), + ARRAY( + "provider_id" => "Goodreads", + "provider_name" => "Goodreads", + "callback" => true, + "new_app_link" => "http://www.goodreads.com/api", + + "cat" => "media", + ), + ARRAY( + "provider_id" => "Stackoverflow", + "provider_name" => "Stackoverflow", + "new_app_link" => null, + + "cat" => "programmers", + ), + ARRAY( + "provider_id" => "GitHub", + "provider_name" => "GitHub", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "https://github.com/settings/applications/new", + "default_api_scope" => "user:email", + + "cat" => "programmers", + ), + ARRAY( + "provider_id" => "Dribbble", + "provider_name" => "Dribbble", + "require_client_id" => true, + "custom_callback" => true, + "new_app_link" => "https://dribbble.com/account/applications/new", + + "cat" => "designers", + ), + ARRAY( + "provider_id" => "500px", + "provider_name" => "px500", + "new_app_link" => "http://developers.500px.com/", + + "cat" => "media", + ), + ARRAY( + "provider_id" => "Skyrock", + "provider_name" => "Skyrock", + "callback" => true, + "new_app_link" => "https://www.skyrock.com/developer/application", + + "cat" => "socialnetworks", + ), + ARRAY( + "provider_id" => "Mixi", + "provider_name" => "Mixi", + "new_app_link" => null, + + "cat" => "socialnetworks", + ), + ARRAY( + "provider_id" => "Steam", + "provider_name" => "Steam", + "new_app_link" => "http://steamcommunity.com/dev/apikey", + "require_api_key" => true, + + "cat" => "gamers", + ), + ARRAY( + "provider_id" => "TwitchTV", + "provider_name" => "Twitch.tv", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "http://www.twitch.tv/settings?section=applications", + + "cat" => "gamers", + ), + ARRAY( + "provider_id" => "Vkontakte", + "provider_name" => "ВКонтакте", + "callback" => true, + "require_client_id" => true, + "new_app_link" => "http://vk.com/developers.php", + + "cat" => "socialnetworks", + ), + ARRAY( + "provider_id" => "Mailru", + "provider_name" => "Mailru", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "http://api.mail.ru/", + + "cat" => "misc", + ), + ARRAY( + "provider_id" => "Yandex", + "provider_name" => "Yandex", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "https://oauth.yandex.ru", + + "cat" => "misc", + ), + ARRAY( + "provider_id" => "Odnoklassniki", + "provider_name" => "Odnoklassniki", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "http://dev.odnoklassniki.ru/", + + "cat" => "socialnetworks", + ), + ARRAY( + "provider_id" => "AOL", + "provider_name" => "AOL", + "new_app_link" => null, + + "cat" => "pleasedie", + ), + ARRAY( + "provider_id" => "Live", + "provider_name" => "Windows Live", + "require_client_id" => true, + "new_app_link" => "https://account.live.com/developers/applications/create", + + "cat" => "pleasedie", + ), + ARRAY( + "provider_id" => "PixelPin", + "provider_name" => "PixelPin", + "require_client_id" => true, + "callback" => true, + "new_app_link" => "https://login.pixelpin.co.uk/", + + "cat" => "misc", + ), +); + +?> \ No newline at end of file diff --git a/plugin/social/index.php b/plugin/social/index.php new file mode 100644 index 000000000..eb3b1288c --- /dev/null +++ b/plugin/social/index.php @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/plugin/social/register_member.php b/plugin/social/register_member.php new file mode 100644 index 000000000..4451c3b61 --- /dev/null +++ b/plugin/social/register_member.php @@ -0,0 +1,52 @@ +displayName); +$user_email = isset($user_profile->emailVerified) ? $user_profile->emailVerified : $user_profile->email; +$user_id = $user_profile->sid ? preg_replace("/[^0-9a-z_]+/i", "", $user_profile->sid) : get_social_convert_id($user_profile->identifier, $provider_name); + +//$is_exists_id = exist_mb_id($user_id); +//$is_exists_name = exist_mb_nick($user_nick, ''); +$user_id = exist_mb_id_recursive($user_id); +$user_nick = exist_mb_nick_recursive($user_nick, ''); +$is_exists_email = $user_email ? exist_mb_email($user_email, '') : false; + +// 불법접근을 막도록 토큰생성 +$token = md5(uniqid(rand(), true)); +set_session("ss_token", $token); + +$g5['title'] = '소셜 회원 가입 - '.social_get_provider_service_name($provider_name); + +include_once(G5_BBS_PATH.'/_head.php'); + +$register_action_url = https_url(G5_PLUGIN_DIR.'/'.G5_SOCIAL_LOGIN_DIR, true).'/register_member_update.php'; +$login_action_url = G5_HTTPS_BBS_URL."/login_check.php"; +$req_nick = !isset($member['mb_nick_date']) || (isset($member['mb_nick_date']) && $member['mb_nick_date'] <= date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400))); +$required = ($w=='') ? 'required' : ''; +$readonly = ($w=='u') ? 'readonly' : ''; + +include_once(get_social_skin_path().'/social_register_member.skin.php'); + +include_once(G5_BBS_PATH.'/_tail.php'); +?> diff --git a/plugin/social/register_member_update.php b/plugin/social/register_member_update.php new file mode 100644 index 000000000..2fbec2f98 --- /dev/null +++ b/plugin/social/register_member_update.php @@ -0,0 +1,191 @@ +sid; +$mb_id = trim($_POST['mb_id']); +$mb_password = trim($_POST['mb_password']); +$mb_password_re = trim($_POST['mb_password_re']); +$mb_nick = trim(strip_tags($_POST['mb_nick'])); +$mb_email = trim($_POST['mb_email']); +$mb_name = clean_xss_tags(trim(strip_tags($_POST['mb_name']))); +$mb_email = get_email_address($mb_email); + +// 이름, 닉네임에 utf-8 이외의 문자가 포함됐다면 오류 +// 서버환경에 따라 정상적으로 체크되지 않을 수 있음. +$tmp_mb_name = iconv('UTF-8', 'UTF-8//IGNORE', $mb_name); +if($tmp_mb_name != $mb_name) { + $mb_name = $tmp_mb_name; +} +$tmp_mb_nick = iconv('UTF-8', 'UTF-8//IGNORE', $mb_nick); +if($tmp_mb_nick != $mb_nick) { + $mb_nick = $tmp_mb_nick; +} + +if( ! $mb_nick || ! $mb_name ){ + $tmp = explode('@', $mb_email); + $mb_nick = $mb_nick ? $mb_nick : $tmp[0]; + $mb_name = $mb_name ? $mb_name : $tmp[0]; +} + +if( ! isset($mb_password) || ! $mb_password ){ + + $mb_password = md5(pack('V*', rand(), rand(), rand(), rand())); + +} + +if ($msg = empty_mb_name($mb_name)) alert($msg, "", true, true); +if ($msg = empty_mb_nick($mb_nick)) alert($msg, "", true, true); +if ($msg = empty_mb_email($mb_email)) alert($msg, "", true, true); +if ($msg = reserve_mb_id($mb_id)) alert($msg, "", true, true); +if ($msg = reserve_mb_nick($mb_nick)) alert($msg, "", true, true); +// 이름에 한글명 체크를 하지 않는다. +//if ($msg = valid_mb_name($mb_name)) alert($msg, "", true, true); +if ($msg = valid_mb_nick($mb_nick)) alert($msg, "", true, true); +if ($msg = valid_mb_email($mb_email)) alert($msg, "", true, true); +if ($msg = prohibit_mb_email($mb_email))alert($msg, "", true, true); + +if ($msg = exist_mb_id($mb_id)) alert($msg); +if ($msg = exist_mb_nick($mb_nick, $mb_id)) alert($msg, "", true, true); +if ($msg = exist_mb_email($mb_email, $mb_id)) alert($msg, "", true, true); + +$data = array( +'mb_id' => $mb_id, +'mb_password' => get_encrypt_string($mb_password), +'mb_nick' => $mb_nick, +'mb_email' => $mb_email, +'mb_name' => $mb_name, +); + +$mb_email_certify = G5_TIME_YMDHIS; + +//메일인증을 사용한다면 +if( defined('G5_SOCIAL_CERTIFY_MAIL') && G5_SOCIAL_CERTIFY_MAIL && $config['cf_use_email_certify'] ){ + $mb_email_certify = ''; +} + +//회원 메일 동의 +$mb_mailling = (isset($_POST['mb_mailling']) && $_POST['mb_mailling']) ? 1 : 0; +//회원 정보 공개 +$mb_open = (isset($_POST['mb_open']) && $_POST['mb_open']) ? 1 : 0; + +// 회원정보 입력 +$sql = " insert into {$g5['member_table']} + set mb_id = '{$mb_id}', + mb_password = '".get_encrypt_string($mb_password)."', + mb_name = '{$mb_name}', + mb_nick = '{$mb_nick}', + mb_nick_date = '".G5_TIME_YMD."', + mb_email = '{$mb_email}', + mb_email_certify = '".$mb_email_certify."', + mb_today_login = '".G5_TIME_YMDHIS."', + mb_datetime = '".G5_TIME_YMDHIS."', + mb_ip = '{$_SERVER['REMOTE_ADDR']}', + mb_level = '{$config['cf_register_level']}', + mb_login_ip = '{$_SERVER['REMOTE_ADDR']}', + mb_mailling = '{$mb_mailling}', + mb_sms = '0', + mb_open = '{$mb_open}', + mb_open_date = '".G5_TIME_YMD."' "; + +$result = sql_query($sql, false); + +if($result) { + + // 회원가입 포인트 부여 + insert_point($mb_id, $config['cf_register_point'], '회원가입 축하', '@member', $mb_id, '회원가입'); + + // 최고관리자님께 메일 발송 + if ($config['cf_email_mb_super_admin']) { + $subject = '['.$config['cf_title'].'] '.$mb_nick .' 님께서 회원으로 가입하셨습니다.'; + + ob_start(); + include_once (G5_BBS_PATH.'/register_form_update_mail2.php'); + $content = ob_get_contents(); + ob_end_clean(); + + mailer($mb_nick, $mb_email, $config['cf_admin_email'], $subject, $content, 1); + } + + $mb = get_member($mb_id); + + //소셜 로그인 계정 추가 + if( function_exists('social_login_success_after') ){ + social_login_success_after($mb, '', 'register'); + } + + set_session('ss_mb_reg', $mb['mb_id']); + + if( !empty($user_profile->photoURL) && ($config['cf_register_level'] >= $config['cf_icon_level']) ){ //회원 프로필 사진이 있고, 회원 아이콘를 올릴수 있는 조건이면 + + // 회원아이콘 + $mb_dir = G5_DATA_PATH.'/member/'.substr($mb_id,0,2); + @mkdir($mb_dir, G5_DIR_PERMISSION); + @chmod($mb_dir, G5_DIR_PERMISSION); + $dest_path = "$mb_dir/$mb_id.gif"; + + social_profile_img_resize($dest_path, $user_profile->photoURL, $config['cf_member_icon_width'], $config['cf_member_icon_height'] ); + + // 회원이미지 + if( is_dir(G5_DATA_PATH.'/member_image/') ) { + $mb_dir = G5_DATA_PATH.'/member_image/'.substr($mb_id,0,2); + @mkdir($mb_dir, G5_DIR_PERMISSION); + @chmod($mb_dir, G5_DIR_PERMISSION); + $dest_path = "$mb_dir/$mb_id.gif"; + + social_profile_img_resize($dest_path, $user_profile->photoURL, $config['cf_member_img_width'], $config['cf_member_img_height'] ); + } + } + + if( $mb_email_certify ){ //메일인증 사용 안하면 + + //바로 로그인 처리 + set_session('ss_mb_id', $mb['mb_id']); + + } else { // 메일인증을 사용한다면 + $subject = '['.$config['cf_title'].'] 인증확인 메일입니다.'; + + // 어떠한 회원정보도 포함되지 않은 일회용 난수를 생성하여 인증에 사용 + $mb_md5 = md5(pack('V*', rand(), rand(), rand(), rand())); + + sql_query(" update {$g5['member_table']} set mb_email_certify2 = '$mb_md5' where mb_id = '$mb_id' "); + + $certify_href = G5_BBS_URL.'/email_certify.php?mb_id='.$mb_id.'&mb_md5='.$mb_md5; + + ob_start(); + include_once (G5_BBS_PATH.'/register_form_update_mail3.php'); + $content = ob_get_contents(); + ob_end_clean(); + + mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $mb_email, $subject, $content, 1); + } + + // 사용자 코드 실행 + @include_once ($member_skin_path.'/register_form_update.tail.skin.php'); + + goto_url(G5_HTTP_BBS_URL.'/register_result.php'); + +} else { + + alert('회원 가입 오류!', G5_URL ); + +} +?> \ No newline at end of file diff --git a/plugin/social/unlink.php b/plugin/social/unlink.php new file mode 100644 index 000000000..5d20bebe4 --- /dev/null +++ b/plugin/social/unlink.php @@ -0,0 +1,48 @@ + \ No newline at end of file diff --git a/skin/board/basic/img/btn_next2.gif b/skin/board/basic/img/btn_next2.gif new file mode 100644 index 000000000..9ec94650a Binary files /dev/null and b/skin/board/basic/img/btn_next2.gif differ diff --git a/skin/board/basic/img/btn_prev2.gif b/skin/board/basic/img/btn_prev2.gif new file mode 100644 index 000000000..827e7be43 Binary files /dev/null and b/skin/board/basic/img/btn_prev2.gif differ diff --git a/skin/board/basic/img/close_btn.png b/skin/board/basic/img/close_btn.png new file mode 100644 index 000000000..50e9f26ef Binary files /dev/null and b/skin/board/basic/img/close_btn.png differ diff --git a/skin/board/basic/img/cmt_btn.png b/skin/board/basic/img/cmt_btn.png new file mode 100644 index 000000000..202f1ff47 Binary files /dev/null and b/skin/board/basic/img/cmt_btn.png differ diff --git a/skin/board/basic/img/icon_bad.png b/skin/board/basic/img/icon_bad.png new file mode 100644 index 000000000..e568b1d83 Binary files /dev/null and b/skin/board/basic/img/icon_bad.png differ diff --git a/skin/board/basic/img/icon_comment.png b/skin/board/basic/img/icon_comment.png new file mode 100644 index 000000000..c7e3acbf9 Binary files /dev/null and b/skin/board/basic/img/icon_comment.png differ diff --git a/skin/board/basic/img/icon_file.gif b/skin/board/basic/img/icon_file.gif index cca47f566..244af004d 100644 Binary files a/skin/board/basic/img/icon_file.gif and b/skin/board/basic/img/icon_file.gif differ diff --git a/skin/board/basic/img/icon_good.png b/skin/board/basic/img/icon_good.png new file mode 100644 index 000000000..69841a134 Binary files /dev/null and b/skin/board/basic/img/icon_good.png differ diff --git a/skin/board/basic/img/icon_hot.gif b/skin/board/basic/img/icon_hot.gif index c95b839ae..2936de662 100644 Binary files a/skin/board/basic/img/icon_hot.gif and b/skin/board/basic/img/icon_hot.gif differ diff --git a/skin/board/basic/img/icon_img.gif b/skin/board/basic/img/icon_img.gif index fefa10d4a..3ba495d05 100644 Binary files a/skin/board/basic/img/icon_img.gif and b/skin/board/basic/img/icon_img.gif differ diff --git a/skin/board/basic/img/icon_link.gif b/skin/board/basic/img/icon_link.gif index 0f3cb1ac6..e9cb9559c 100644 Binary files a/skin/board/basic/img/icon_link.gif and b/skin/board/basic/img/icon_link.gif differ diff --git a/skin/board/basic/img/icon_lock.png b/skin/board/basic/img/icon_lock.png new file mode 100644 index 000000000..2a083a51d Binary files /dev/null and b/skin/board/basic/img/icon_lock.png differ diff --git a/skin/board/basic/img/icon_mobile.gif b/skin/board/basic/img/icon_mobile.gif index ad934d23c..43189ffae 100644 Binary files a/skin/board/basic/img/icon_mobile.gif and b/skin/board/basic/img/icon_mobile.gif differ diff --git a/skin/board/basic/img/icon_new.gif b/skin/board/basic/img/icon_new.gif index 45aa6d7ed..73fa06a8f 100644 Binary files a/skin/board/basic/img/icon_new.gif and b/skin/board/basic/img/icon_new.gif differ diff --git a/skin/board/basic/img/icon_reply.gif b/skin/board/basic/img/icon_reply.gif index 91c135977..7fe2c6558 100644 Binary files a/skin/board/basic/img/icon_reply.gif and b/skin/board/basic/img/icon_reply.gif differ diff --git a/skin/board/basic/img/icon_secret.gif b/skin/board/basic/img/icon_secret.gif index c04899f14..7be670092 100644 Binary files a/skin/board/basic/img/icon_secret.gif and b/skin/board/basic/img/icon_secret.gif differ diff --git a/skin/board/basic/img/icon_share.png b/skin/board/basic/img/icon_share.png new file mode 100644 index 000000000..6d64f625a Binary files /dev/null and b/skin/board/basic/img/icon_share.png differ diff --git a/skin/board/basic/img/icon_view.png b/skin/board/basic/img/icon_view.png new file mode 100644 index 000000000..ea76f5442 Binary files /dev/null and b/skin/board/basic/img/icon_view.png differ diff --git a/skin/board/basic/img/sch_bg.png b/skin/board/basic/img/sch_bg.png new file mode 100644 index 000000000..729178d8e Binary files /dev/null and b/skin/board/basic/img/sch_bg.png differ diff --git a/skin/board/basic/img/sch_btn.png b/skin/board/basic/img/sch_btn.png new file mode 100644 index 000000000..94f98db8f Binary files /dev/null and b/skin/board/basic/img/sch_btn.png differ diff --git a/skin/board/basic/list.skin.php b/skin/board/basic/list.skin.php index d995a8555..abde78f5d 100644 --- a/skin/board/basic/list.skin.php +++ b/skin/board/basic/list.skin.php @@ -12,11 +12,27 @@ if ($is_nogood) $colspan++; add_stylesheet('', 0); ?> -

      목록

      -
      + + +
      +
      + Total + 페이지 +
      + + + + +
      + +
      @@ -161,33 +188,11 @@ add_stylesheet('', 0 + + - -
      - 게시물 검색 - -
      - - - - - - - - -
      -
      - -
      -

      +

      + + + + -

      + ?> +

      페이지 정보

      - 작성자 - 작성일 - 조회 - 댓글 + 작성자 + 댓글 + 조회 + 작성일 +
      - - - - -
      -

      첨부파일

      - -
      - - - - - - - - - - -
      - - - - - - - -
      - -

      본문

      @@ -154,19 +59,19 @@ add_stylesheet('', 0

      - - + + +
      - 스크랩 - 추천 + 추천 - 비추천 + 비추천 @@ -175,30 +80,128 @@ add_stylesheet('', 0 if($board['bo_use_good'] || $board['bo_use_nogood']) { ?>
      - 추천 - 비추천 + 추천 + 비추천
      - +
      +
      + 스크랩 + + +
      + + $cnt = 0; + if ($view['file']['count']) { + for ($i=0; $i + + + +
      +

      첨부파일

      +
        + +
      • + + + + + () + 회 다운로드 | DATE : +
      • + +
      +
      + + + + + + + + + + +
      + + + + + + + +
        +
      • 이전글
      • +
      • 다음글
      • +
      + + +
      + - -
      - -
      -
      @@ -253,6 +256,19 @@ $(function() { // 이미지 리사이즈 $("#bo_v_atc").viewimageresize(); + + //sns공유 + $(".btn_share").click(function(){ + $("#bo_v_sns").fadeIn(); + + }); + + $(document).mouseup(function (e) { + var container = $("#bo_v_sns"); + if (!container.is(e.target) && container.has(e.target).length === 0){ + container.css("display","none"); + } + }); }); function excute_good(href, $el, $tx) diff --git a/skin/board/basic/view_comment.skin.php b/skin/board/basic/view_comment.skin.php index ad770b070..a372ff01f 100644 --- a/skin/board/basic/view_comment.skin.php +++ b/skin/board/basic/view_comment.skin.php @@ -7,7 +7,7 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 var char_min = parseInt(); // 최소 var char_max = parseInt(); // 최대 - +

      댓글목록

      @@ -15,8 +15,7 @@ var char_max = parseInt(); // 최대 $cmt_amt = count($list); for ($i=0; $i<$cmt_amt; $i++) { $comment_id = $list[$i]['wr_id']; - $cmt_depth = ""; // 댓글단계 - $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 20; + $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 50; $comment = $list[$i]['content']; /* if (strstr($list[$i]['wr_option'], "secret")) { @@ -29,54 +28,52 @@ var char_max = parseInt(); // 최대
      style="margin-left:px;border-top-color:#e0e0e0">
      -

      님의 댓글

      +

      님의 댓글의 댓글

      - 댓글의 댓글 - 아이피 - + 아이피 + () - 작성일 - + 작성일 +
      -

      - 비밀글 - -

      +
      +

      + 비밀글 + +

      + "> - + if($w == 'cu') { + $sql = " select wr_id, wr_content, mb_id from $write_table where wr_id = '$c_id' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + if (!($is_admin || ($member['mb_id'] == $cmt['mb_id'] && $cmt['mb_id']))) + $cmt['wr_content'] = ''; + $c_wr_content = $cmt['wr_content']; + } + + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w'; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w'; + ?> + + +
      + + " id="secret_comment_"> - - -

      등록된 댓글이 없습니다.

      @@ -89,9 +86,9 @@ var char_max = parseInt(); // 최대 $w = 'c'; ?> -
    - +
    - -
      -
    • -
    • -
    • -
    - -
    + + +
    + 게시물 검색 + +
    + + + + + + + + +
    +
    +
    @@ -155,34 +193,10 @@ add_stylesheet('', 0 + + - - -
    - 게시물 검색 - -
    - - - - - - - - -
    -
    - - -
    -

    +

    + + + + -

    + ?> +

    페이지 정보

    - 작성자 - 작성일 - 조회 - 댓글 + 작성자 + 댓글 + 조회 + 작성일 +
    - - - - -
    -

    첨부파일

    - -
    - - - - - - - - - - -
    - - - - - - - -
    - -

    본문

    @@ -154,19 +59,19 @@ add_stylesheet('', 0

    - - + + +
    - 스크랩 - 추천 + 추천 - 비추천 + 비추천 @@ -175,30 +80,128 @@ add_stylesheet('', 0 if($board['bo_use_good'] || $board['bo_use_nogood']) { ?>
    - 추천 - 비추천 + 추천 + 비추천
    - +
    +
    + 스크랩 + + +
    + + $cnt = 0; + if ($view['file']['count']) { + for ($i=0; $i + + + +
    +

    첨부파일

    +
      + +
    • + + + + + () + 회 다운로드 | DATE : +
    • + +
    +
    + + + + + + + + + + +
    + + + + + + + +
      +
    • 이전글
    • +
    • 다음글
    • +
    + + +
    + - -
    - -
    -
    @@ -253,6 +256,19 @@ $(function() { // 이미지 리사이즈 $("#bo_v_atc").viewimageresize(); + + //sns공유 + $(".btn_share").click(function(){ + $("#bo_v_sns").fadeIn(); + + }); + + $(document).mouseup(function (e) { + var container = $("#bo_v_sns"); + if (!container.is(e.target) && container.has(e.target).length === 0){ + container.css("display","none"); + } + }); }); function excute_good(href, $el, $tx) diff --git a/skin/board/gallery/view_comment.skin.php b/skin/board/gallery/view_comment.skin.php index f953e129b..a372ff01f 100644 --- a/skin/board/gallery/view_comment.skin.php +++ b/skin/board/gallery/view_comment.skin.php @@ -7,7 +7,7 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 var char_min = parseInt(); // 최소 var char_max = parseInt(); // 최대 - +

    댓글목록

    @@ -15,8 +15,7 @@ var char_max = parseInt(); // 최대 $cmt_amt = count($list); for ($i=0; $i<$cmt_amt; $i++) { $comment_id = $list[$i]['wr_id']; - $cmt_depth = ""; // 댓글단계 - $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 20; + $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 50; $comment = $list[$i]['content']; /* if (strstr($list[$i]['wr_option'], "secret")) { @@ -29,54 +28,52 @@ var char_max = parseInt(); // 최대
    style="margin-left:px;border-top-color:#e0e0e0">
    -

    님의 댓글

    +

    님의 댓글의 댓글

    - 댓글의 댓글 - 아이피 - + 아이피 + () - 작성일 - + 작성일 +
    -

    - 비밀글 - -

    +
    +

    + 비밀글 + +

    + "> - + if($w == 'cu') { + $sql = " select wr_id, wr_content, mb_id from $write_table where wr_id = '$c_id' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + if (!($is_admin || ($member['mb_id'] == $cmt['mb_id'] && $cmt['mb_id']))) + $cmt['wr_content'] = ''; + $c_wr_content = $cmt['wr_content']; + } + + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w'; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w'; + ?> + + +
    + + " id="secret_comment_"> - - -

    등록된 댓글이 없습니다.

    @@ -89,9 +86,9 @@ var char_max = parseInt(); // 최대 $w = 'c'; ?> -
    '; + echo ''; ?> @@ -120,6 +125,7 @@ function faq_open(el) if($con.is(":visible")) { $con.slideUp(); + } else { $("#faq_con .con_inner:visible").css("display", "none"); diff --git a/skin/faq/basic/style.css b/skin/faq/basic/style.css index 35168de92..3c3ce0bbb 100644 --- a/skin/faq/basic/style.css +++ b/skin/faq/basic/style.css @@ -1,23 +1,27 @@ @charset "utf-8"; - +#bo_cate {margin:15px 0 10px} #bo_cate h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} -#bo_cate ul {margin-bottom:10px;padding-left:1px;zoom:1} +#bo_cate ul {;zoom:1} #bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} -#bo_cate li {float:left;margin-bottom:-1px} -#bo_cate a {display:block;position:relative;margin-left:-1px;padding:6px 0 5px;width:90px;border:1px solid #ddd;background:#f7f7f7;color:#888;text-align:center;letter-spacing:-0.1em;line-height:1.2em;cursor:pointer} -#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none} -#bo_cate #bo_cate_on {z-index:2;border:1px solid #565e60;background:#fff;color:#565e60;font-weight:bold} +#bo_cate li {display:inline-block;} +#bo_cate a {display:block;border:1px solid #dadada;background:#fff;margin:0 0 5px 0;line-height:30px;padding:0 10px;border-radius:3px} +#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none;background:#f3f3f3} +#bo_cate #bo_cate_on {z-index:2;border:1px solid #253dbe;color:#253dbe;font-weight:bold} #faq_wrap {margin:10px 0 30px} #faq_wrap h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} .faq_admin {text-align:right} #faq_wrap ol {margin:0;padding:0;list-style:none} -#faq_con {border:1px solid #e9e9e9;border-top:0} -#faq_con h3 a {display:block;padding:10px;border-top:1px solid #e9e9e9;background:#f2f5f9;text-decoration:none} -#faq_con .con_inner {display:none;padding:10px;line-height:1.8em} -#faq_con .con_closer {margin:10px 0 0;text-align:right} -#faq_con .closer_btn {margin:0;padding:0;border:0;background:transparent} -.faq_tolist {padding:0 10px;text-align:right} -.faq_img {text-align:center} +#faq_wrap li{border:1px solid #ddd;background:#fff;margin:5px 0;} +#faq_wrap li h3{min-height:50px;line-height:30px;padding:10px;padding-left:50px;position:relative} +#faq_wrap li h3 .tit_bg{display:inline-block;position:absolute;top:10px;left:10px;text-align:center;background:#333;color:#fff;border-radius:50%;width:30px;height:30px} +#faq_con .con_inner{display:none;border-top:1px solid #ddd;padding:15px;padding-left:50px;position:relative;background: #f7f7f7;} +#faq_con .con_inner .tit_bg{display:inline-block;position:absolute;top:10px;left:10px;text-align:center;background:#777;color:#fff;border-radius:50%;width:30px;line-height:30px;height:30px} +#faq_con .con_inner .closer_btn{height:25px;font-size:0.92em;display:inline-block;padding:0 5px;border-radius:5px;} +#faq_con .con_closer{text-align:right} -#faq_sch {text-align:center} \ No newline at end of file +#faq_sch {text-align:center;border:1px solid #ccc;background:#fff;;padding:30px;margin:10px 0} +#faq_sch form{display:inline-block;position:relative} +#faq_sch .sch_tit{font-size:20px;font-weight:bold;display:inline-block;margin-right:10px;vertical-align:middle} +#faq_sch .frm_input{border-color:#646982;border-radius:0;width:300px} +#faq_sch .btn_submit{padding:0 10px;height:40px;color:#000;font-size:1.083em;font-weight:bold;color:#fff;background:#253dbe;} diff --git a/skin/latest/basic/img/icon_file.gif b/skin/latest/basic/img/icon_file.gif index cca47f566..244af004d 100644 Binary files a/skin/latest/basic/img/icon_file.gif and b/skin/latest/basic/img/icon_file.gif differ diff --git a/skin/latest/basic/img/icon_hot.gif b/skin/latest/basic/img/icon_hot.gif index c95b839ae..2936de662 100644 Binary files a/skin/latest/basic/img/icon_hot.gif and b/skin/latest/basic/img/icon_hot.gif differ diff --git a/skin/latest/basic/img/icon_img.gif b/skin/latest/basic/img/icon_img.gif index fefa10d4a..3ba495d05 100644 Binary files a/skin/latest/basic/img/icon_img.gif and b/skin/latest/basic/img/icon_img.gif differ diff --git a/skin/latest/basic/img/icon_link.gif b/skin/latest/basic/img/icon_link.gif index 0f3cb1ac6..e9cb9559c 100644 Binary files a/skin/latest/basic/img/icon_link.gif and b/skin/latest/basic/img/icon_link.gif differ diff --git a/skin/latest/basic/img/icon_lock.png b/skin/latest/basic/img/icon_lock.png new file mode 100644 index 000000000..2a083a51d Binary files /dev/null and b/skin/latest/basic/img/icon_lock.png differ diff --git a/skin/latest/basic/img/icon_mobile.gif b/skin/latest/basic/img/icon_mobile.gif index ad934d23c..43189ffae 100644 Binary files a/skin/latest/basic/img/icon_mobile.gif and b/skin/latest/basic/img/icon_mobile.gif differ diff --git a/skin/latest/basic/img/icon_secret.gif b/skin/latest/basic/img/icon_secret.gif index c04899f14..7be670092 100644 Binary files a/skin/latest/basic/img/icon_secret.gif and b/skin/latest/basic/img/icon_secret.gif differ diff --git a/skin/latest/basic/img/icon_view.png b/skin/latest/basic/img/icon_view.png new file mode 100644 index 000000000..ea76f5442 Binary files /dev/null and b/skin/latest/basic/img/icon_view.png differ diff --git a/skin/latest/basic/img/more-btn.gif b/skin/latest/basic/img/more-btn.gif new file mode 100644 index 000000000..fa4c87331 Binary files /dev/null and b/skin/latest/basic/img/more-btn.gif differ diff --git a/skin/latest/basic/img/more_bg.gif b/skin/latest/basic/img/more_bg.gif new file mode 100644 index 000000000..19aab13a3 Binary files /dev/null and b/skin/latest/basic/img/more_bg.gif differ diff --git a/skin/latest/basic/latest.skin.php b/skin/latest/basic/latest.skin.php index 989a3ee40..1c1a60698 100644 --- a/skin/latest/basic/latest.skin.php +++ b/skin/latest/basic/latest.skin.php @@ -3,42 +3,51 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 // add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨 add_stylesheet('', 0); +add_javascript('', 10); ?> - -
    - +
    +

    • "; + if ($list[$i]['icon_secret']) echo "비밀글 "; + + if ($list[$i]['icon_new']) echo "N새글"; + + if ($list[$i]['icon_hot']) echo "H인기글"; + + + echo " "; if ($list[$i]['is_notice']) echo "".$list[$i]['subject'].""; else echo $list[$i]['subject']; - if ($list[$i]['comment_cnt']) - echo $list[$i]['comment_cnt']; + echo ""; // if ($list[$i]['link']['count']) { echo "[{$list[$i]['link']['count']}]"; } // if ($list[$i]['file']['count']) { echo "<{$list[$i]['file']['count']}>"; } - if (isset($list[$i]['icon_new'])) echo " " . $list[$i]['icon_new']; - if (isset($list[$i]['icon_hot'])) echo " " . $list[$i]['icon_hot']; - if (isset($list[$i]['icon_file'])) echo " " . $list[$i]['icon_file']; - if (isset($list[$i]['icon_link'])) echo " " . $list[$i]['icon_link']; - if (isset($list[$i]['icon_secret'])) echo " " . $list[$i]['icon_secret']; - ?> + //echo $list[$i]['icon_reply']." "; + // if ($list[$i]['icon_file']) echo " " ; + //if ($list[$i]['icon_link']) echo " " ; + + if ($list[$i]['comment_cnt']) echo " + + ".$list[$i]['comment_cnt'].""; + + ?> + +
    • -
    • 게시물이 없습니다.
    • +
    • 게시물이 없습니다.
    - + 더보기 +
    - \ No newline at end of file diff --git a/skin/latest/basic/style.css b/skin/latest/basic/style.css index ab55517b1..8fb71ebde 100644 --- a/skin/latest/basic/style.css +++ b/skin/latest/basic/style.css @@ -1,11 +1,26 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* 새글 스킨 (latest) */ -.lt_pc {float:left;margin-left:20px} -.lt {position:relative;float:left;margin-bottom:20px;padding-bottom:10px;width:354px;height:150px;border-bottom:1px solid #e9e9e9} -.lt ul {margin:0 0 10px;padding:0;list-style:none} -.lt li {padding:3px 0} -.lt .lt_title {display:block;padding:10px 0 8px} -.lt .lt_more {position:absolute;top:10px;right:0} -.lt .cnt_cmt {display:inline-block;margin:0 0 0 3px;font-weight:bold} \ No newline at end of file + +.lat {position:relative;margin-bottom:20px;overflow:hidden;border: 1px solid #c6cacc;background:#fff} +.lat .lat_title {display:block;padding:0 20px;line-height:45px;font-size:1.083em;border-bottom:1px solid #e2e2e2;color:#253dbe;background:#fcfcfc} +.lat .lat_title a{color:#253dbe;display:inline-block;position:relative} +.lat .lat_title a:after{position:absolute;bottom:-1px;left:0;width:100%;height:2px;background:#253dbe;content:''} +.lat ul{padding:15px 20px} +.lat li {position:relative;line-height:18px;padding:3px 0;padding-right:50px;padding-left:10px;position:relative} +.lat li:before{position: absolute;top: 12px;left: 0px;width: 4px;height: 4px;background: #aaa;content: '';border-radius: 50%;} +.lat li a:hover{color:#a22121} +.lat li .fa-heart{color:#ff0000;} +.lat li .fa-lock{display: inline-block;line-height: 14px;width: 16px;font-size: 0.833em;color: #4f818c;background: #cbe3e8;text-align: center;border-radius: 2px;font-size: 12px;border:1px solid #a2c6ce} +.lat li .new_icon{display:inline-block;width: 16px;line-height:16px;font-size:0.833em;color:#ffff00;background:#6db142;text-align:center;border-radius: 2px;} +.lat li .hot_icon{display:inline-block;width: 16px;line-height:16px ;font-size:0.833em;color:#fff;background:#e52955;text-align:center;border-radius: 2px;} +.lat li .fa-caret-right{color:#bbb} +.lat .lt_date{position:absolute;top:3px;right:0;color:#888} +.lat .empty_li{line-height:145px ;color:#666;text-align:center;padding:0;} +.lat .empty_li:before{background:none;padding:0} + +.lat .lt_cmt{background:#5c85c1;color:#fff; font-size:11px;height:16px;line-height:16px;padding:0 5px;border-radius:3px; +-webkit-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +-moz-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +box-shadow: inset 0 2px 5px rgba(255,255,255,0.4);} +.lat .lt_more {position:absolute;top:11px;right:10px;display:block;width:25px;line-height:25px;color:#aaa;border-radius:3px;text-align:center;} +.lat .lt_more:hover{color:#777} \ No newline at end of file diff --git a/skin/latest/notice/latest.skin.php b/skin/latest/notice/latest.skin.php new file mode 100644 index 000000000..5091d3178 --- /dev/null +++ b/skin/latest/notice/latest.skin.php @@ -0,0 +1,53 @@ +', 0); +add_javascript('', 10); +?> + +
    +

    + + +
    + + + \ No newline at end of file diff --git a/skin/latest/notice/style.css b/skin/latest/notice/style.css new file mode 100644 index 000000000..3867cde8e --- /dev/null +++ b/skin/latest/notice/style.css @@ -0,0 +1,16 @@ +@charset "utf-8"; +/* 새글 스킨 (latest) */ +.notice {position:relative;padding:15px 50px;border-bottom:1px solid #d0d6e4} +.notice li{text-overflow: ellipsis;overflow: hidden;white-space: nowrap;} +.notice li a:hover{color:#a22121} +.notice li .lock_icon{display: inline-block;line-height: 14px;width: 16px;font-size: 0.833em;color: #4f818c;background: #cbe3e8;text-align: center;border-radius: 2px;font-size: 12px;border:1px solid #a2c6ce;vertical-align:top} +.notice li .new_icon{display:inline-block;line-height:16px;width:16px;font-size:0.833em;color:#ffff00;background:#6db142;text-align:center;margin-right:3px;border-radius:2px;vertical-align:top} +.notice .cnt_cmt{background:#5c85c1;color:#fff; font-size:11px;height:16px;line-height:16px;padding:0 5px;border-radius:3px;white-space: nowrap;margin-left:5px; +-webkit-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +-moz-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +box-shadow: inset 0 2px 5px rgba(255,255,255,0.4)} + +.notice h2{position:absolute;top:50%;left:10px;margin-top:-15px;left:5;line-height:30px} +.notice h2 a{display:inline-block;width:30px;line-height:30px;border-radius:25px;background:#4158d1;color:#fff;text-align:center;color:#fff} +.notice .bx-next{position:absolute;top:50%;right:10px;;width:26px;height:26px;line-height:24px;text-align:center;background:#fff;border:1px solid #d1d1d1;margin-top:-12px} +.notice .bx-prev{position:absolute;top:50%;right:35px;width:26px;height:26px;line-height:24px;text-align:center;background:#fff;border:1px solid #d1d1d1;margin-top:-12px} diff --git a/skin/latest/pic_basic/latest.skin.php b/skin/latest/pic_basic/latest.skin.php new file mode 100644 index 000000000..5b9eb2726 --- /dev/null +++ b/skin/latest/pic_basic/latest.skin.php @@ -0,0 +1,66 @@ +', 0); +$thumb_width = 210; +$thumb_height = 150; +?> + +
    +

    +
      + '; + ?> +
    • + + 비밀글 "; + + if ($list[$i]['icon_new']) echo "N새글"; + + if ($list[$i]['icon_hot']) echo "H인기글"; + + + echo " "; + if ($list[$i]['is_notice']) + echo "".$list[$i]['subject'].""; + else + echo $list[$i]['subject']; + + + + echo ""; + + // if ($list[$i]['link']['count']) { echo "[{$list[$i]['link']['count']}]"; } + // if ($list[$i]['file']['count']) { echo "<{$list[$i]['file']['count']}>"; } + + //echo $list[$i]['icon_reply']." "; + // if ($list[$i]['icon_file']) echo " " ; + //if ($list[$i]['icon_link']) echo " " ; + + if ($list[$i]['comment_cnt']) echo " + + ".$list[$i]['wr_comment'].""; + + ?> + + +
    • + + +
    • 게시물이 없습니다.
    • + +
    + 더보기 + +
    diff --git a/skin/latest/pic_basic/style.css b/skin/latest/pic_basic/style.css new file mode 100644 index 000000000..9945e8d26 --- /dev/null +++ b/skin/latest/pic_basic/style.css @@ -0,0 +1,24 @@ +@charset "utf-8"; +/* 새글 스킨 (latest) */ +.pic_lt{position:relative;margin-bottom:20px;overflow:hidden;border: 1px solid #c6cacc;background:#fff} +.pic_lt .lat_title {display:block;background:#fcfcfc;padding:0 20px;line-height:45px;font-size:1.083em;border-bottom:1px solid #e2e2e2;color:#253dbe;} +.pic_lt .lat_title a{color:#253dbe;display:inline-block;position:relative} +.pic_lt .lat_title a:after{position:absolute;bottom:-1px;left:0;width:100%;height:2px;background:#253dbe;content:''} +.pic_lt .lt_more {position:absolute;top:11px;right:10px;display:block;width:25px;line-height:25px;color:#aaa;border-radius:3px;text-align:center;} +.pic_lt .lt_more:hover{color:#777} +.pic_lt ul:after {display:block;visibility:hidden;clear:both;content:""} +.pic_lt ul{padding:20px 15px } +.pic_lt li{float:left;width:20%;padding:0 10px} +.pic_lt li .lt_img{margin:5px 0;display:block} +.pic_lt li .lt_img img{width:100%;height:auto} +.pic_lt li a:hover{color:#a22121} +.pic_lt li .fa-heart{color:#ff0000;} +.pic_lt li .fa-lock{display: inline-block;line-height: 14px;width: 16px;font-size: 0.833em;color: #4f818c;background: #cbe3e8;text-align: center;border-radius: 2px;font-size: 12px;border:1px solid #a2c6ce} +.pic_lt li .new_icon{display:inline-block;width: 16px;line-height:16px ;font-size:0.833em;color:#ffff00;background:#6db142;text-align:center;border-radius: 2px;} +.pic_lt li .hot_icon{display:inline-block;width: 16px;line-height:16px ;font-size:0.833em;color:#fff;background:#e52955;text-align:center;border-radius: 2px;} +.pic_lt li .fa-caret-right{color:#bbb} +.pic_lt .lt_cmt{background:#5c85c1;color:#fff; font-size:11px;height:16px;line-height:16px;padding:0 5px;border-radius:3px;white-space: nowrap; +-webkit-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +-moz-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +box-shadow: inset 0 2px 5px rgba(255,255,255,0.4);} +.pic_lt .lt_date{display:block;margin-top:5px;color: #888;} diff --git a/skin/member/basic/formmail.skin.php b/skin/member/basic/formmail.skin.php index e57be622c..42b5520de 100644 --- a/skin/member/basic/formmail.skin.php +++ b/skin/member/basic/formmail.skin.php @@ -6,70 +6,69 @@ add_stylesheet('', ?> -
    +

    님께 메일보내기

    - + -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    메일쓰기
    형식 +
    +

    메일쓰기

    +
      + +
    • + + +
    • +
    • + + +
    • + +
    • + + +
    • +
    • + 형식 -
    - - 첨부 파일은 누락될 수 있으므로 메일을 보낸 후 파일이 첨부 되었는지 반드시 확인해 주시기 바랍니다. -
    자동등록방지
    + +
  • + + +
  • +
  • +
    + + +
    +
    첨부 파일은 누락될 수 있으므로 메일을 보낸 후 파일이 첨부 되었는지 반드시 확인해 주시기 바랍니다.
    + +
  • +
  • +
    + + +
    +
  • +
  • + 자동등록방지 + +
  • + +
    + + +
    -
    - - -
    diff --git a/skin/member/basic/login.skin.php b/skin/member/basic/login.skin.php index 86772c70d..6bd3c820d 100644 --- a/skin/member/basic/login.skin.php +++ b/skin/member/basic/login.skin.php @@ -14,33 +14,30 @@ add_stylesheet('',
    회원로그인 - - - - + + + +
    + + - - +
    - \ No newline at end of file + diff --git a/skin/member/basic/member_confirm.skin.php b/skin/member/basic/member_confirm.skin.php index 3ea749ba7..457a318b4 100644 --- a/skin/member/basic/member_confirm.skin.php +++ b/skin/member/basic/member_confirm.skin.php @@ -23,20 +23,15 @@ add_stylesheet('',
    - 회원아이디 + 회원아이디 - - - + +
    - -
    - \ No newline at end of file + diff --git a/skin/member/basic/register_form.skin.php b/skin/member/basic/register_form.skin.php index 436bee0e9..c69447e72 100644 --- a/skin/member/basic/register_form.skin.php +++ b/skin/member/basic/register_form.skin.php @@ -6,61 +6,51 @@ add_stylesheet('', ?> -
    - - - - + + + + -
    - - - - - - - - date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400))) { // 닉네임수정일이 지나지 않았다면 ?> - - - - -
    - - - - - - - - - - - - - - - - -
    사이트 이용정보 입력
    - 영문자, 숫자, _ 만 입력 가능. 최소 3자이상 입력하세요. - class="frm_input " minlength="3" maxlength="20"> + + + + + + + + + date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400))) { // 닉네임수정일이 지나지 않았다면 ?> + + + +
    +
    +

    사이트 이용정보 입력

    +
      +
    • + + class="frm_input half_input " minlength="3" maxlength="20" placeholder="아이디"> -
    class="frm_input " minlength="3" maxlength="20">
    class="frm_input " minlength="3" maxlength="20">
    + 영문자, 숫자, _ 만 입력 가능. 최소 3자이상 입력하세요. + +
  • + + class="frm_input half_input " minlength="3" maxlength="20" placeholder="비밀번호"> + + + class="frm_input half_input right_input " minlength="3" maxlength="20" placeholder="비밀번호 확인"> +
  • +
    - - - - - - - - - - - - - + + 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. + - - - - + + + - - - - - - + +
  • + + class="frm_input full_input " size="70" maxlength="255" placeholder="홈페이지"> +
  • + - - - - - - +
  • + + + + class="frm_input half_input " maxlength="20" placeholder="전화번호"> + - -
  • - - - - + + - - - - - - - -
    개인정보 입력
    - - 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. - - class="frm_input " size="10"> +

    개인정보 입력

    + +
      +
    • + + class="frm_input half_input " size="10" placeholder="이름"> ', else $mb_cert = '휴대폰'; ?> +
      본인확인성인인증 완료
      -
    - - 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    - 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. -
    - - - -
    + + + +
  • + + + + + + + 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    + 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. +
    + +
  • + + +
  • + + @@ -109,160 +104,176 @@ add_stylesheet('', - -
  • class="frm_input " size="70" maxlength="255">
    class="frm_input " maxlength="20">
    - class="frm_input " maxlength="20"> + + + + class="frm_input right_input half_input " maxlength="20" placeholder="휴대폰번호"> -
    - 주소 + + +
  • 필수 -
  • - class="frm_input " size="5" maxlength="6"> + class="frm_input " size="5" maxlength="6" placeholder="우편번호">
    - class="frm_input frm_address " size="50"> -
    - - + class="frm_input frm_address full_input " size="50" placeholder="기본주소"> +
    + +
    - - + + -
    + + + +
    - - - - - - - - - +

    기타 개인설정

    +
      + +
    • + + +
    • + - -
    - - - - + +
  • + + +
  • + - = $config['cf_icon_level']) { ?> - - - - - + + + - - - - + + - - - - - - + +
  • + + + > + 휴대폰 문자메세지를 받겠습니다. + +
  • + - - - - - - - - - - - + + + - - - - - - + - - - - - -
    기타 개인설정
    + = $config['cf_icon_level']) { ?> +
  • + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    - gif만 가능하며 용량 바이트 이하만 등록됩니다. + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다.
    - + 회원아이콘 -
  • + = $config['cf_icon_level'] && $config['cf_member_img_size'] && $config['cf_member_img_width'] && $config['cf_member_img_height']) { ?> +
  • + + + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다. +
    + + + 회원아이콘 + + + + +
  • + + +
  • + > 정보 메일을 받겠습니다. -
  • - > - 휴대폰 문자메세지를 받겠습니다. -
    - - 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. - + +
  • + id="reg_mb_open"> 다른분들이 나의 정보를 볼 수 있도록 합니다. -
  • 정보공개 + + 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. + + + +
  • + 정보공개 + 정보공개는 수정후 일 이내, 까지는 변경이 안됩니다.
    이렇게 하는 이유는 잦은 정보공개 수정으로 인하여 쪽지를 보낸 후 받지 않는 경우를 막기 위해서 입니다.
    - -
  • 자동등록방지
    + +
  • + + +
  • + + +
  • + 자동등록방지 + +
  • +
    - -
    - - 취소 -
    -
    + +
    +
    + 취소 + +
    + -
    \ No newline at end of file diff --git a/skin/member/basic/register_result.skin.php b/skin/member/basic/register_result.skin.php index 1267d20ee..2072485a3 100644 --- a/skin/member/basic/register_result.skin.php +++ b/skin/member/basic/register_result.skin.php @@ -6,13 +6,13 @@ add_stylesheet('', ?> -
    - -

    +

    +

    회원가입이 완료되었습니다.

    +

    님의 회원가입을 진심으로 축하합니다.

    - +

    회원 가입 시 입력하신 이메일 주소로 인증메일이 발송되었습니다.
    발송된 인증메일을 확인하신 후 인증처리를 하시면 사이트를 원활하게 이용하실 수 있습니다. @@ -38,9 +38,7 @@ add_stylesheet('', 감사합니다.

    - + 메인으로
    \ No newline at end of file diff --git a/skin/member/basic/scrap.skin.php b/skin/member/basic/scrap.skin.php index e89053522..c2a7c52ce 100644 --- a/skin/member/basic/scrap.skin.php +++ b/skin/member/basic/scrap.skin.php @@ -6,41 +6,28 @@ add_stylesheet('', ?> -
    -

    +
    +

    -
    - - - - - - - - - - - - - - - - - - - - - +
    +
    "; ?> - -
    스크랩 목록
    번호게시판제목보관일시삭제
    삭제
    자료가 없습니다.
    + 자료가 없습니다."; ?> +
    - +
    \ No newline at end of file diff --git a/skin/member/basic/scrap_popin.skin.php b/skin/member/basic/scrap_popin.skin.php index 81f82a5a9..ad3ed8b28 100644 --- a/skin/member/basic/scrap_popin.skin.php +++ b/skin/member/basic/scrap_popin.skin.php @@ -6,35 +6,34 @@ add_stylesheet('', ?> -
    +

    스크랩하기

    -
    +
    -
    - - - - - - - - - - - - -
    제목 확인 및 댓글 쓰기
    제목
    -
    +
    +

    제목 확인 및 댓글 쓰기

    +
      +
    • + 제목 + +
    • +
    • + + +
    • +
    +
    -

    - 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. -

    +

    + 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. +

    -
    - +
    + +
    diff --git a/skin/member/basic/style.css b/skin/member/basic/style.css index b86359a68..b3a308714 100644 --- a/skin/member/basic/style.css +++ b/skin/member/basic/style.css @@ -1,5 +1,4 @@ @charset "utf-8"; -/* SIR 지운아빠 */ /* ### 기본 스타일 커스터마이징 시작 ### */ @@ -22,6 +21,7 @@ .mbskin .win_btn input {} .mbskin .win_btn a {} .mbskin .win_btn a:focus, .mbskin .win_btn a:hover {} + /* 게시판용 버튼 */ .mbskin a.btn_b01 {} .mbskin a.btn_b01:focus, .mbskin .btn_b01:hover {} @@ -30,7 +30,30 @@ .mbskin a.btn_admin {} /* 관리자 전용 버튼 */ .mbskin a.btn_admin:focus, .mbskin a.btn_admin:hover {} +/* 기본박스 */ +.mbskin{position: relative;margin:100px auto 0;border:1px solid #ddd;width:400px;background:#fff;text-align:center; +} +.mbskin:before,.mbskin:after{ +content:""; +position:absolute;z-index:-1;top:2%;bottom:0;left:10px;right:10px; +-webkit-box-shadow:0 0 20px rgba(0,0,0,0.8); + -moz-box-shadow:0 0 20px rgba(0,0,0,0.8); + box-shadow:0 0 20px rgba(0,0,0,0.8); +-moz-border-radius:100px / 10px; + border-radius:100px / 10px;} +.mbskin:after{right:10px;left:auto; + -webkit-transform:skew(8deg) rotate(3deg); + -moz-transform:skew(8deg) rotate(3deg); + -ms-transform:skew(8deg) rotate(3deg); + -o-transform:skew(8deg) rotate(3deg); + transform:skew(8deg) rotate(3deg);} +.mbskin .frm_input{width:100%} +.mbskin .btn_submit{width:100%;margin:10px 0 0;height:45px;font-weight:bold;font-size:1.25em} +.mbskin h1{margin: 60px 0 30px;font-size: 2em;} + + /* 기본테이블 */ + .mbskin .tbl_head01 {} .mbskin .tbl_head01 caption {} .mbskin .tbl_head01 thead th {} @@ -82,95 +105,158 @@ /* ### 기본 스타일 커스터마이징 끝 ### */ /* 회원가입 약관 */ -#fregister section {margin:0 0 20px;padding:20px 0} -#fregister h2 {margin:0 0 20px;text-align:center} -#fregister textarea {display:block;margin-bottom:10px;padding:5px;width:98%;height:150px;border:1px solid #e9e9e9;background:#f7f7f7} -#fregister .fregister_agree {padding:10px 0 0;text-align:right} -#fregister .fregister_agree label {display:inline-block;margin-right:5px} -#fregister p {color:#e8180c;text-align:center} -#fregister .btn_confirm {margin-bottom:20px} -#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%} -#fregister_private .tbl_head01 td {border:1px solid #e9e9e9} -#fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden} +#fregister p{text-align:center;color: #c7254e;background: #f9f2f4;padding:10px;border:1px solid #ecc7d2;margin:0 0 5px} +#fregister section {;margin:10px auto 30px;border:1px solid #dbdbdb;position:relative;border-radius:3px 3px 0 0 ; +-webkit-box-shadow: 0 1px 3px #eee; +-moz-box-shadow: 0 1px 3px #eee; +box-shadow: 0 1px 3px #eee; +} +#fregister_chkall{text-align:right} +#fregister h2 {text-align:left;padding:15px 20px;border-bottom:1px solid #dbdbdb;background:#f8f8f8} +#fregister textarea {display:block;padding:20px;width:100%;height:150px;background:#fff;border:0;line-height:1.6em} +#fregister .fregister_agree {position:absolute;top:0;right:0;;padding:15px} +#fregister_private div{padding:20px;background:#fff} +#fregister_private table{width:100%;border-collapse:collapse} +#fregister_private table caption {position:absolute;font-size:0;line-height:0;overflow:hidden} +#fregister_private table th{background:#646982;width:33.33%;color:#fff;padding:10px;border:1px solid #555971} +#fregister_private table td{border:1px solid #ddd;padding:10px;} +#fregister .btn_confirm{text-align:center;} +#fregister .btn_confirm .btn_submit{height:50px;padding:0 40px;font-weight:bold;font-size:1.083em} /* 회원가입 입력 */ -#fregisterform textarea {height:50px} - +#register_form{background:#fff;padding:20px;margin-bottom:20px} #fregisterform #msg_certify {margin:5px 0 0;padding:5px;border:1px solid #dbecff;background:#eaf4ff;text-align:center} - #fregisterform .frm_address {margin:5px 0 0} #fregisterform #mb_addr3 {display:inline-block;margin:5px 0 0;vertical-align:middle} #fregisterform #mb_addr_jibeon {display:block;margin:5px 0 0} +#fregisterform .btn_confirm{text-align:center} +#fregisterform .btn_confirm .btn_submit{height:45px;;padding:0 30px;font-weight:bold;font-size:1.083em} +#fregisterform .btn_confirm .btn_cancel{line-height:45px;height:45px;padding:0 30px;font-weight:bold;font-size:1.083em} +#fregisterform .frm_info{display:block;color:#3497d9;font-size:0.92em} +#fregisterform .form_01 div{margin: 0 0 50px} +#fregisterform .captcha{display:block;margin:5px 0 0} +#fregisterform .reg_mb_img_file img{max-width:100%;height:auto} + /* 회원가입 완료 */ -#reg_result {padding:50px 0 0} +#reg_result {padding:100px 0 40px;text-align:center;background:#fff} +#reg_result h2{font-size:2em;margin:0 0 20px} +#reg_result h2 strong{color:#ed6478} #reg_result #result_email {margin:20px 0;padding:10px 50px;border-top:1px solid #e9e9e9;border-bottom:1px solid #dde4e9;background:#fff;line-height:2em} #reg_result #result_email span {display:inline-block;width:150px} #reg_result #result_email strong {color:#e8180c;font-size:1.2em} #reg_result p {line-height:1.8em} #reg_result .btn_confirm {margin:50px 0} +#reg_result .reg_result_p{font-size:1.25em;margin:0 0 10px;} +#reg_result .reg_result_p strong{color:#3497d9} +#reg_result .btn_submit{padding: 0 30px;font-weight:bold;height:40px;line-height:40px;display:inline-block;margin:30px 0 0 ;font-size:1.083em} /* 아이디/비밀번호 찾기 */ #find_info #mb_hp_label {display:inline-block;margin-left:10px} -#find_info #info_fs {margin:0 20px 20px;padding:0;background:#fff} -#find_info #info_fs .frm_input {width:70%} -#find_info p {margin:0 0 10px;line-height:1.8em} -#find_info #captcha {margin:0 20px} +#find_info p {line-height:1.5em} +#find_info #mb_email{margin:10px 0;} /* 로그인 */ -#mb_login {margin:0 auto;padding:100px 0;width:500px} -#mb_login h1 {margin:0 0 20px;font-size:1.3em} -#mb_login h2 {margin:0} -#mb_login p {padding:10px 0;line-height:1.5em} -#mb_login #login_fs {position:relative;margin:0;padding:20px 20px 20px 95px;border:1px solid #cfded8;border-bottom:0;background:#fff} -#mb_login #login_fs legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} -#mb_login #login_fs label {letter-spacing:-0.1em} -#mb_login #login_fs .login_id {position:absolute;top:26px;left:95px} -#mb_login #login_fs .login_pw {position:absolute;top:52px;left:95px} -#mb_login #login_fs .frm_input {display:block;margin:0 0 5px 80px;width:162px} -#mb_login #login_fs .btn_submit {position:absolute;top:20px;right:95px;width:60px;height:53px} -#mb_login #login_info {margin:0 0 30px;padding:20px;border:1px solid #cfded8;background:#f5f6fa} -#mb_login #login_info div {text-align:right} +#mb_login {} +#login_fs{padding:0 50px} +#mb_login #login_fs .frm_input{margin:0 0 10px} +#mb_login #login_fs .btn_submit {margin:0 0 20px} +#mb_login #login_info{background:#f6f6f6;padding:25px 10px;border-top:1px solid #e8e8e8;margin:40px 0 0 } +#mb_login #login_info:after {display:block;visibility:hidden;clear:both;content:""} +#mb_login #login_info h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#mb_login #login_info a{display:inline-block;width:50%;float:left} +#login_password_lost{border-right:1px solid #ddd} + +#mb_login_notmb{margin:30px auto;padding:20px 30px } +#mb_login_notmb h2{font-size:1.25em;margin:20px 0 10px} +#guest_privacy{border:1px solid #ccc;text-align:left;line-height:1.6em;color:#666;background:#fafafa;padding:10px;height:150px;margin:10px 0;overflow-y:auto} +#mb_login_notmb .btn_submit{display:block;text-align:center;line-height:45px} + +#mb_login_od_wr{margin:30px auto;padding:20px 30px } +#mb_login_od_wr h2{font-size:1.25em;margin:20px 0 10px} +#mb_login_od_wr .frm_input{margin:10px 0 0 } +#mb_login_od_wr p{background:#f3f3f3;margin:20px 0 0 ;padding:15px 20px;line-height:1.5em} /* 쪽지 */ -#memo_view_contents {margin:0 auto 20px;width:90%} -#memo_view_contents h1 {position:absolute;font-size:0;line-height:0;overflow:hidden} -#memo_view_ul {margin:0;padding:0 0 10px;border-bottom:1px solid #eee;list-style:none} -.memo_view_li {position:relative;padding:5px 0} -.memo_view_subj {display:inline-block;width:65px} -#memo_view p {padding:10px 0;min-height:150px;height:auto !important;height:150px;background:#fff;line-height:1.8em} +#memo_list .memo_name,#memo_list .memo_name .sv_wrap{font-weight:bold} +#memo_list .memo_datetime{float:right;font-size:0.92em;color:#777;font-style:italic} +#memo_list .memo_del{margin-left: 5px; color: #49857c;font-size: 15px;} + +#memo_view_contents {margin:10px 0;border:1px solid #ddd;} +#memo_view_contents h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#memo_view_ul {margin:0;border-bottom:1px solid #eee;list-style:none;background:#f3f3f3;} +#memo_view_ul:after {display:block;visibility:hidden;clear:both;content:""} +.memo_view_li {position:relative;padding:10px;float:left;width:50%;} +.memo_view_name strong,.memo_view_name .sv_wrap{font-weight:bold !important} +.memo_view_subj{display: inline-block;height: 20px;line-height: 18px;border: 1px solid #3497d9;color: #3497d9;padding: 0 5px;border-radius: 15px;font-size: 11px;} +.memo_view_li .profile_img img{border-radius:50%} +.memo_view_date{text-align:right;color:#555;font-style:italic} +.memo_view_date strong{font-weight:normal} +#memo_view .btn_b02{float:right} +#memo_view p {padding:10px;border-top:1px solid #ddd;min-height:150px;height:auto !important;height:150px;background:#fff;line-height:1.8em} #memo_write textarea {height:100px} /* 스크랩 */ +#scrap .scrap_tit{font-weight:bold;display:block;font-size:1.083em;margin-bottom:5px;line-height:1.3em} +#scrap .scrap_cate{ display:block;color:#3598db ;font-size:0.92em;float:left} +#scrap .scrap_datetime{;color:#777;font-style:italic;float:right} +#scrap .scrap_del{position:absolute;top:5px;right:10px;font-size:18px;color:#49857c} +#scrap .scrap_del:hover{color:#98ca69} #scrap_do table {margin:0 0 10px;width:100%} #scrap_do textarea {height:100px} +#scrap_do .scrap_tit{background:#f3f3f3;padding:10px 15px;font-size:1.083em;font-weight:bold} +#scrap_do label{display:block;margin:0 0 5px;font-size:0.92em} +/*포인트*/ +#point .point_top{line-height:15px;margin:0 0 5px} +#point .point_top:after {display:block;visibility:hidden;clear:both;content:""} +#point .point_tit{font-weight:bold;float:left;font-size:1.083em;display:block;} +#point .point_num{font-size:1.25em;color:#00c4ac;font-weight:bold;float:right;} +#point .point_date1{float:left;color:#555;font-style:italic} +#point .point_date{float:right;color:#555;font-style:italic} +#point .txt_expired {color:#aaa;} +#point .point_all{background:#ae99da;border:0;border-bottom:2px solid #9781c5;color:#fff;font-weight:bold;font-size:1.083em} +#point .point_all span,#point .point_status span{float:right;} +#point .point_status{background:#737373;border:0;color:#fff;font-weight:bold;font-size:1.083em} +#point .point_status span{margin-left:10px} /* 회원 비밀번호 확인 */ -#mb_confirm {margin:0 auto;padding:100px 0;width:500px} -#mb_confirm h1 {margin:0 0 20px;font-size:1.3em} -#mb_confirm p {padding:20px;border:1px solid #dde4e9;border-bottom:0;background:#fff} -#mb_confirm p strong {display:block} -#mb_confirm fieldset {margin:0 0 30px;padding:30px 0;border:1px solid #e9e9e9;background:#f5f6fa;text-align:center} +#mb_confirm {} +#mb_confirm h1 {margin:60px 0 30px;font-size:2em} +#mb_confirm p {padding:0 20px 40px;border-bottom:1px solid #e9e9e9;font-size:1.083em;line-height:1.4em;color:#656565} +#mb_confirm p strong {display:block;color:#3ca1ff;font-size:1.167em;margin:0 0 5px} +#mb_confirm fieldset {;padding:50px;text-align:left} #mb_confirm fieldset .frm_input {background-color:#fff !important} #mb_confirm label {letter-spacing:-0.1em} -#mb_confirm_id {display:inline-block;margin-right:20px;font-weight:bold} +#mb_confirm_id {display:block;margin:5px 0 10px;font-weight:bold} +#mb_confirm .confirm_id{font-size:0.92em;color:#666} /* 비밀글 비밀번호 확인 */ -#pw_confirm {margin:0 auto;padding:100px 0;width:500px} -#pw_confirm h1 {margin:0 0 20px;font-size:1.3em} -#pw_confirm p {padding:20px;border:1px solid #dde4e9;border-bottom:0;background:#fff} -#pw_confirm p strong {display:block} -#pw_confirm fieldset {margin:0 0 30px;padding:30px 0;border:1px solid #e9e9e9;background:#f5f6fa;text-align:center} +#pw_confirm h1 {margin:60px 20px 30px;font-size:2em} +#pw_confirm p {padding:0 20px 40px;border-bottom:1px solid #e9e9e9;font-size:1.083em;line-height:1.4em;color:#656565} +#pw_confirm p strong {display:block;color:#3ca1ff;font-size:1.167em;margin:0 0 5px} +#pw_confirm fieldset {;padding:50px;text-align:center} #pw_confirm fieldset .frm_input {background-color:#fff !important} #pw_confirm label {letter-spacing:-0.1em} #pw_confirm_id {display:inline-block;margin-right:20px;font-weight:bold} +#mb_confirm_id{} /* 폼메일 */ -#formmail #subject {width:386px} #formmail textarea {height:100px} +#formmail .formmail_flie{position:relative} +#formmail .formmail_flie .file_wr {border: 1px solid #ccc;background: #fff;color: #000;vertical-align: middle;border-radius: 3px;padding: 5px;height: 40px;margin: 0;} +#formmail .lb_icon {position: absolute;top: 1px;left: 1px;border-radius: 3px 0 0 3px;height: 38px;line-height: 38px;width: 40px;background: #eee;text-align: center;color: #888;} +#formmail .frm_file {padding-left: 50px;} +#formmail .frm_info{color: #3497d9;font-size: 0.92em;} /* 자기소개 */ +#profile h1 a{color:#fff} #profile table {margin-bottom:0} -#profile section {margin:0 auto 20px;padding:20px;width:86%} -#profile h2 {margin:0} \ No newline at end of file +#profile table th{text-align:left;padding:10px;width:100px} +#profile section {color: #2d4c7b;background: #eff9f9;padding: 10px;border: 1px solid #bfd4dc;margin: 10px 0;} +#profile h2 {margin:0 0 5px} +#profile .profile_name{text-align:center;font-weight:bold} +#profile .my_profile_img{display:block;margin:20px 0 5px;} +#profile .my_profile_img img{border-radius:50%;border:1px solid #aaa} +#profile .profile_img img{border-radius:50%} +#profile .profile_name .sv_wrap{font-weight:bold;text-align:left} \ No newline at end of file diff --git a/skin/new/basic/new.skin.php b/skin/new/basic/new.skin.php index 2558d8118..9401f2b50 100644 --- a/skin/new/basic/new.skin.php +++ b/skin/new/basic/new.skin.php @@ -22,8 +22,8 @@ add_stylesheet('', 0);
    - - 목록 + 목록 + +
    diff --git a/skin/search/basic/search.skin.php b/skin/search/basic/search.skin.php index e341efa3f..c6386f500 100644 --- a/skin/search/basic/search.skin.php +++ b/skin/search/basic/search.skin.php @@ -23,8 +23,10 @@ add_stylesheet('', - - + + + + - id="sop_or" name="sop"> - - id="sop_and" name="sop"> - + + id="sop_or" name="sop"> + + id="sop_and" name="sop"> + + @@ -68,7 +72,7 @@ add_stylesheet('', if ($board_count) { ?>
    -

    전체검색 결과

    +

    전체검색 결과

    게시판
    @@ -109,7 +113,7 @@ add_stylesheet('', for ($i=0; $i', ?>
  • - - 새창 +
    + + 새창 +

    - - +
    + + +
  • - +
    diff --git a/skin/search/basic/style.css b/skin/search/basic/style.css index 8adf23a45..94d01dc26 100644 --- a/skin/search/basic/style.css +++ b/skin/search/basic/style.css @@ -1,29 +1,53 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* 전체검색결과 스킨 */ -#sch_res_detail {padding:0 0 10px;border-bottom:1px solid #e9e9e9;text-align:center} +#sch_res_detail {background:#fff;padding:30px;border:1px solid #ccc;text-align:center;margin:0 0 10px} #sch_res_detail legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} -#sch_res_ov {margin:0 0 10px;padding:10px;border-bottom:1px solid #e9e9e9;background:#f5f6fa;zoom:1} +#sch_res_detail select{border:1px solid #646982;height:40px;padding:0 5px} +#sch_res_detail .frm_input{border:1px solid #646982;border-radius:0;} +#sch_res_detail .sch_wr{position:relative;display:inline-block} +#sch_res_detail .btn_submit{padding:0 10px;height:40px;color:#000;font-size:1.083em;font-weight:bold;color:#fff;background:#253dbe} +#sch_res_detail .sch_rd{display:block;margin:5px 0 0;font-size:0.92em;color:#666} + +#sch_res_ov {text-align:center;zoom:1} #sch_res_ov:after {display:block;visibility:hidden;clear:both;content:""} -#sch_res_ov h2 {float:left} -#sch_res_ov dl {float:left;margin:0 0 0 10px} +#sch_res_ov h2 {text-align:center;margin:30px 0 10px;font-size:1.5em;} +#sch_res_ov h2 strong{color:#00c4ac;} +#sch_res_ov dl {display:inline-block;line-height: 30px;font-size: 0.92em;color: #4e546f;background: #d4d4d4;padding: 0 10px;border-radius: 5px;} +#sch_res_ov dl:after {display:block;visibility:hidden;clear:both;content:""} #sch_res_ov dt {float:left} #sch_res_ov dd {float:left;margin:0 10px 0 5px} -#sch_res_ov p {float:right;margin:0;padding:0;line-height:1em} +#sch_res_ov dd .sch_word{color:#000} +#sch_res_ov p {margin:0;padding:0;line-height:1em;color:#777;font-size:0.92em} + + +#sch_res_board {background:#ecf2f3;padding:7px;margin:10px 0;border:1px solid #bed1d4} +#sch_res_board h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#sch_res_board ul {zoom:1} +#sch_res_board ul:after {display:block;visibility:hidden;clear:both;content:""} +#sch_res_board li {display:inline-block;padding:2px;} +#sch_res_board a {display:block;line-height:26px;padding:0 10px;border-radius:3px;border:1px solid transparent} +#sch_res_board a:focus, #sch_res_board a:hover {text-decoration:none;background:#d2d6dc;} +#sch_res_board .cnt_cmt {font-weight:normal !important;display:inline-block;background:#c4dce0;margin-left:3px;color:#3497d9;border-radius:15px;height:18px;padding:0 5px;line-height:18px;font-size:0.92em} +#sch_res_board .sch_on {z-index:2;background:#3497d9;color:#fff;font-weight:bold;border-bottom-color:#1977b5; +-webkit-box-shadow: inset 0 2px 5px rgb(33, 135, 202); +-moz-box-shadow: inset 0 2px 5px rgb(33, 135, 202); +box-shadow:inset 0 2px 5px rgb(33, 135, 202);} +#sch_res_board .sch_on:hover{;background:#3497d9;color:#fff;} + + -#sch_res_board {margin:0 0 10px;padding-left:1px;list-style:none;zoom:1} -#sch_res_board:after {display:block;visibility:hidden;clear:both;content:""} -#sch_res_board li {float:left;margin-bottom:-1px} -#sch_res_board a {display:block;position:relative;margin-left:-1px;padding:6px 0 5px;width:180px;border:1px solid #ddd;text-align:center;letter-spacing:-0.1em;line-height:1.2em;cursor:pointer} -#sch_res_board a:focus, #sch_res_board a:hover, #sch_res_board a:active {text-decoration:none} -#sch_res_board .cnt_cmt {font-weight:normal !important} .sch_res_list {margin:0 0 10px;padding:10px 0 15px} -.sch_res_list h2 {margin:0 0 15px;font-size:1.2em} -.sch_res_list ul {margin:0;padding:0;list-style:none} -.sch_res_list li {margin:0 0 10px;padding:0 0 10px;border-bottom:1px solid #e9e9e9} +.sch_res_list h2 {margin:0 0 10px;font-size:1.2em} +.sch_res_list ul {margin:0;padding:0;list-style:none;border-top:1px solid #000} +.sch_res_list li {;border-bottom:1px solid #e0e0e0;background:#fff;position:relative} +.sch_res_list .sch_tit{display:block;background:#f4f4f4;padding:10px 70px 10px 10px} +.sch_res_list .pop_a{position:absolute;top:10px;right:10px;color:#666;} .sch_res_title {display:inline-block;margin:0 0 5px} -.sch_res_list p {margin:0 0 10px;line-height:1.8em} -.sch_more {text-align:right} -.sch_on {color:#ff3061} \ No newline at end of file +.sch_res_list p {padding:10px;color:#666;line-height:1.5em} +.sch_res_list .sch_info{padding:10px;color:#777} +.sch_res_list .sch_info:after {display:block;visibility:hidden;clear:both;content:""} +.sch_res_list .profile_img img{border-radius:50%} +.sch_res_list .sch_datetime{float:right;} +.sch_more {text-align:right;margin:10px 0 30px} +.sch_more a{display:inline-block;color:#f2664f} diff --git a/skin/social/img/btn_p.jpg b/skin/social/img/btn_p.jpg new file mode 100644 index 000000000..854640b55 Binary files /dev/null and b/skin/social/img/btn_p.jpg differ diff --git a/skin/social/img/login_id.jpg b/skin/social/img/login_id.jpg new file mode 100644 index 000000000..42b9ae47c Binary files /dev/null and b/skin/social/img/login_id.jpg differ diff --git a/skin/social/img/login_pw.jpg b/skin/social/img/login_pw.jpg new file mode 100644 index 000000000..e686037d8 Binary files /dev/null and b/skin/social/img/login_pw.jpg differ diff --git a/skin/social/img/plus_minus.png b/skin/social/img/plus_minus.png new file mode 100644 index 000000000..62f41eb17 Binary files /dev/null and b/skin/social/img/plus_minus.png differ diff --git a/skin/social/img/sns_fb_s.png b/skin/social/img/sns_fb_s.png new file mode 100644 index 000000000..c6028b196 Binary files /dev/null and b/skin/social/img/sns_fb_s.png differ diff --git a/skin/social/img/sns_gp_s.png b/skin/social/img/sns_gp_s.png new file mode 100644 index 000000000..aa0884594 Binary files /dev/null and b/skin/social/img/sns_gp_s.png differ diff --git a/skin/social/img/sns_kakao_s.png b/skin/social/img/sns_kakao_s.png new file mode 100644 index 000000000..09f0a4aba Binary files /dev/null and b/skin/social/img/sns_kakao_s.png differ diff --git a/skin/social/img/sns_logo.png b/skin/social/img/sns_logo.png new file mode 100644 index 000000000..958bb5788 Binary files /dev/null and b/skin/social/img/sns_logo.png differ diff --git a/skin/social/img/sns_logo_not.png b/skin/social/img/sns_logo_not.png new file mode 100644 index 000000000..04308576c Binary files /dev/null and b/skin/social/img/sns_logo_not.png differ diff --git a/skin/social/img/sns_naver_s.png b/skin/social/img/sns_naver_s.png new file mode 100644 index 000000000..7ea7a5b19 Binary files /dev/null and b/skin/social/img/sns_naver_s.png differ diff --git a/skin/social/img/sns_payco_s.png b/skin/social/img/sns_payco_s.png new file mode 100644 index 000000000..6ecf203ed Binary files /dev/null and b/skin/social/img/sns_payco_s.png differ diff --git a/skin/social/img/sns_twitter_s.png b/skin/social/img/sns_twitter_s.png new file mode 100644 index 000000000..2c5fe153d Binary files /dev/null and b/skin/social/img/sns_twitter_s.png differ diff --git a/skin/social/index.php b/skin/social/index.php new file mode 100644 index 000000000..e69de29bb diff --git a/skin/social/social_login.skin.php b/skin/social/social_login.skin.php new file mode 100644 index 000000000..02ae62f9a --- /dev/null +++ b/skin/social/social_login.skin.php @@ -0,0 +1,85 @@ +', 10); +?> + + \ No newline at end of file diff --git a/skin/social/social_outlogin.skin.1.php b/skin/social/social_outlogin.skin.1.php new file mode 100644 index 000000000..43260475d --- /dev/null +++ b/skin/social/social_outlogin.skin.1.php @@ -0,0 +1,85 @@ +', 10); +?> + + \ No newline at end of file diff --git a/skin/social/social_register.skin.php b/skin/social/social_register.skin.php new file mode 100644 index 000000000..b15d87064 --- /dev/null +++ b/skin/social/social_register.skin.php @@ -0,0 +1,88 @@ +', 10); +?> +
    + + +
    \ No newline at end of file diff --git a/skin/social/social_register_member.skin.php b/skin/social/social_register_member.skin.php new file mode 100644 index 000000000..ccd41f476 --- /dev/null +++ b/skin/social/social_register_member.skin.php @@ -0,0 +1,192 @@ +', 11); +add_stylesheet('', 12); +add_stylesheet('', 13); +add_javascript('', 10); + +$email_msg = $is_exists_email ? '등록할 이메일이 중복되었습니다.다른 이메일을 입력해 주세요.' : ''; +?> + + +
    + + + + +
    + + + + + + + + + + +
    +
    + 자세히보기 + +
    +
    +

    +
    +
    +
    +
    + 자세히보기 + +
    +
    +

    +
    +
    +
    + +
    + +
    + + + + + + + + + +
    개인정보 입력
    + + +
    +
    + +
    + + 취소 +
    +
    + + + + +
    +

    혹시 기존 회원이신가요?

    + +
    + + + + + +
    + \ No newline at end of file diff --git a/skin/social/social_u_register_form.skin.php b/skin/social/social_u_register_form.skin.php new file mode 100644 index 000000000..29d8f6aca --- /dev/null +++ b/skin/social/social_u_register_form.skin.php @@ -0,0 +1,163 @@ +', 10); +?> + +
  • + +
    +
    + + $provider_name ){ + + if( !option_array_checked($social, $config['cf_social_servicelist'])) { + continue; + } + + $social_nonce = social_nonce_create($social, $session_id); + $add_class=''; + $title=''; + if( in_array($social, $my_provides) ){ + + $link_href = G5_SOCIAL_LOGIN_URL.'/unlink.php?provider='.$social.'&social_nonce='.$social_nonce; + + $title = $provider_name.' 연결을 해제합니다.'; + } else { + $add_class = ' sns-icon-not'; + + $link_href = $self_url.'?provider='.$social.'&mylink=1&url='.$urlencode; + + $title = $provider_name.' 계정을 연결 합니다.'; + + } + ?> + + + + + +
    +
    +
  • + + \ No newline at end of file diff --git a/skin/social/style.css b/skin/social/style.css new file mode 100644 index 000000000..9a2e71964 --- /dev/null +++ b/skin/social/style.css @@ -0,0 +1,148 @@ +@charset "utf-8"; + +.social_info_guide{background:#f3f3f3;border:1px solid #ddd;margin:0 10px 10px;padding:10px 15px;line-height:1.5em} +.bg-warning{margin:0 10px 10px;padding:10px 15px;line-height:1.5em} +.bg-warning1{background:#f7dfe4;border:1px solid #eac3cb} +.bg-warning2{background:#deeabf;border:1px solid #bde498} +.bg-warning3{background:#fff8dc;border:1px solid #f1e4b2} + +/* SNS LOGIN */ +.login-sns{padding-bottom:10px;margin-top:5px;border: 1px solid #d2d9e6;border-bottom: 1px solid #c1ccda;clear:both;background:#fff;} +.login-sns h3{padding-top:10px;text-align:center;color:#777;font-weight:normal} +.sns-wrap {margin:10px 0 0;text-align:center} +.sns-icon {display:inline-block;vertical-align:middle;text-decoration:none} +.sns-icon:hover {text-decoration:none} +.sns-icon .ico {display:block;vertical-align:middle} +/*.sns-icon .txt {position:absolute;line-height:0;font-size:0;vertical-align:middle;overflow:hidden}*/ +.sns-icon .txt i {font-style:normal} + +#fregisterform .form_01 .reg-form {margin-bottom:20px} +#fregisterform .form_01 .reg-form .sns-wrap {margin:10px 0 0;text-align:left} +.reg-form .sns-icon {display:inline-block;vertical-align:middle;text-decoration:none;border-width:1px;border-style:solid;overflow:hidden;margin:0 1px} +.reg-form .sns-icon:hover {text-decoration:none} +.reg-form .sns-icon .ico {display:block;background:url('./img/sns_logo.png') no-repeat;vertical-align:middle;width:24px;height:24px} +.reg-form .sns-icon-not .ico {display:block;background:url('./img/sns_logo_not.png') no-repeat;vertical-align:middle} +.reg-form .sns-icon .txt {position:absolute;line-height:0;font-size:0;vertical-align:middle;overflow:hidden} +.reg-form .sns-icon .txt i {font-style:normal} + +.sns-wrap-reg .sns-naver {border-color:#18a400;background:#2db400} +.sns-wrap-reg .sns-naver .ico {background-position:-29px 0; } +.sns-wrap-reg .sns-google {border-color:#ca2c19;background:#dd5443} +.sns-wrap-reg .sns-google .ico {background-position:-58px 0} +.sns-wrap-reg .sns-facebook {border-color:#2e5393;background:#3a5897} +.sns-wrap-reg .sns-facebook .ico {background-position:0 0 } + +.sns-wrap-reg .sns-icon {border-color:#dcdcdc} +.sns-wrap-reg .sns-icon-not {border-color:#8b8b8b} +.sns-wrap-reg .sns-naver{border-color:#18a400} +.sns-wrap-reg .sns-naver .ico {background-position:-29px 0; } +.sns-wrap-reg .sns-google .ico {background-position:-58px 0} +.sns-wrap-reg .sns-google {border-color:#ca2c19} +.sns-wrap-reg .sns-facebook .ico {background-position:0 0 } +.sns-wrap-reg .sns-facebook {border-color:#2e5393} +.sns-wrap-reg .sns-kakao .ico {background-position:-87px 0} +.sns-wrap-reg .sns-twitter {border-color:#488FC9} +.sns-wrap-reg .sns-twitter .ico {background-position:-145px 0} +.sns-wrap-reg .sns-payco {border-color:#C44646} +.sns-wrap-reg .sns-payco .ico {background-position:-116px 0} +.sns-wrap-reg .sns-kakao {border-color:#f2df00} + +/* SNS by COLOR */ +.sns-wrap-over .sns-naver{background:url('./img/sns_naver_s.png') no-repeat} +.sns-wrap-over .sns-google {background:url('./img/sns_gp_s.png') no-repeat} +.sns-wrap-over .sns-facebook {background:url('./img/sns_fb_s.png') no-repeat} +.sns-wrap-over .sns-twitter {background:url('./img/sns_twitter_s.png') no-repeat} +.sns-wrap-over .sns-payco {background:url('./img/sns_payco_s.png') no-repeat} +.sns-wrap-over .sns-kakao {background:url('./img/sns_kakao_s.png') no-repeat} +.reg-form .sns-icon-not {border-color:#8b8b8b} + +.social-login-loading{width:100%;height:auto;text-align:center} +.social-login-loading p{display:inline-block;margin-top:10px;padding:40px 0 0;line-height:30px} + +/* 아웃로그인 */ +#sns_outlogin .sns-icon {overflow:hidden;margin:0 1px} +#sns_outlogin .sns-icon .txt {position:absolute;line-height:0;font-size:0;vertical-align:middle;overflow:hidden} +#sns_outlogin .sns-icon .ico {width:30px;height:30px} + +/*로그인 */ +#sns_login{border:0;margin-top:15px ;padding: 20px 50px 0;border-top:1px solid #edeaea} +#sns_login h3{;padding:10px 0 0;text-align:left;font-weight:bold} +#sns_login .sns-icon{display:block;height:40px;line-height:40px;width:100%;margin:0 0 5px;padding-left:40px;text-align:left;color:#fff;border-radius:2px} +#sns_login .sns-naver{background-color:#1fc800;background-position:5px 5px;border-bottom:1px solid #1ea505} +#sns_login .sns-kakao{background-color:#ffeb00;background-position:5px 5px;border-bottom:1px solid #e2c10a} +#sns_login .sns-kakao {color:#3c1e1e} +#sns_login .sns-facebook{background-color:#3b579d;background-position:5px 5px;border-bottom:1px solid #28458f} +#sns_login .sns-google{background-color:#db4a3a;background-position:5px 5px;border-bottom:1px solid #c03121} +#sns_login .sns-twitter{background-color:#1ea1f2;background-position:5px 5px;border-bottom:1px solid #1e82c0} +#sns_login .sns-payco{background-color:#df0b00;background-position:5px 5px;border-bottom:1px solid #9d0800} +#sns_login .txt{text-align:left;padding-left:10px;border-left:1px solid rgba(0,0,0,0.1);display:block;font-weight:bold} +#sns_login .txt:hover{background:rgba(0,0,0,0.07)} + +/*회원가입 */ +#sns_register{margin:0 0 10px;padding:0;text-align:center} +#sns_register h2{text-align: left;padding: 15px 20px;border-bottom: 1px solid #dbdbdb;background: #f8f8f8;} +#sns_register .sns-wrap:after {display:block;visibility:hidden;clear:both;content:""} +#sns_register .sns-wrap{display:inline-block;margin:18px 0 15px;vertical-align:top} +#sns_register .sns-icon{display:inline-block;height:40px;line-height:40px;width:210px;margin:0 3px 5px;padding-left:40px;text-align:left;color:#fff;border-radius:2px;float:left} +#sns_register .sns-icon:nth-child(3n+1){clear:both} +#sns_register .sns-naver{background-color:#1fc800;background-position:5px 5px;border-bottom:1px solid #1ea505} +#sns_register .sns-kakao{background-color:#ffeb00;background-position:5px 5px;border-bottom:1px solid #e2c10a} +#sns_register .sns-kakao {color:#3c1e1e} +#sns_register .sns-facebook{background-color:#3b579d;background-position:5px 5px;border-bottom:1px solid #28458f} +#sns_register .sns-google{background-color:#db4a3a;background-position:5px 5px;border-bottom:1px solid #c03121} +#sns_register .sns-twitter{background-color:#1ea1f2;background-position:5px 5px;border-bottom:1px solid #1e82c0} +#sns_register .sns-payco{background-color:#df0b00;background-position:5px 5px;border-bottom:1px solid #9d0800} +#sns_register .txt{text-align:;padding-left:10px;border-left:1px solid rgba(0,0,0,0.1);display:block;font-weight:bold} +#sns_register .txt:hover{background:rgba(0,0,0,0.07)} + +/*기존 계정에 연결하기*/ + +/* Styles for Accordion */ + +.mbskin .toggle{position:relative;display:block;border:1px solid #c6cacc;margin-top:-1px;background-color: #fcfcfc;} +.mbskin .toggle .toggle-title{padding:13px 15px;line-height:20px} +.mbskin .toggle .title-name{display:block} +.mbskin .toggle .toggle-inner{padding:15px;line-height:1.5em;display:none;background:#fff;border-top:1px solid #e2e2e2;} +.mbskin .toggle .toggle-inner div{max-width:100%} +.mbskin .right_i{position:absolute;font-size:0.92em;top:10px;right:10px;padding:0 10px 0 0;border-radius:3px;display:inline-block;z-index: 2;background: #3497d9;color: #fff;border-bottom-color: #1977b5;cursor:pointer} +.mbskin .toggle .toggle-title .right_i i{background:url("./img/plus_minus.png") 0 -24px no-repeat;width:20px;height:24px;display:inline-block;vertical-align:middle} +.mbskin .toggle .toggle-title.active .right_i i{background:url("./img/plus_minus.png") 0 0 no-repeat} +.mbskin .all_agree{position:relative;display:block;;margin-bottom:6px;background:#fff;border:1px solid #c6cacc;border-top:0;padding:13px 15px;line-height:20px} + +#register_member .sns_tbl{background:#fff;;margin:10px 0;border:1px solid #c6cacc;} +.sns_tbl table{border:0} +.sns_tbl caption{ padding: 0 20px;line-height: 45px;font-size: 1.083em;border-bottom: 1px solid #e2e2e2;color: #253dbe;background: #fcfcfc;} +.sns_tbl th{width:100px;text-align:right;padding:10px;} +.sns_tbl td{padding:10px;} +.sns_tbl .email_msg{color:#777;margin:5px 0 0} + +#fregisterform .btn_confirm{text-align:center;margin:20px 0} +#fregisterform .btn_confirm .btn_submit{height:45px;;padding:0 30px;font-weight:bold;font-size:1.083em} +#fregisterform .btn_confirm .btn_cancel{line-height:45px;height:45px;padding:0 30px;font-weight:bold;font-size:1.083em} + +#sns-link-pnl .connect-close {position:absolute;top:10px;right:10px;margin:0;padding:0;width:30px;height:30px;border:0;background:transparent;color:#383838;cursor:pointer;font-size:15px} +#sns-link-pnl .connect-close:hover {color:#ff5191} +#sns-link-pnl .connect-close .fa {margin:0 0 0 1px} +#sns-link-pnl .connect-close .txt {position:absolute;line-height:0;font-size:0;overflow:hidden} + +#sns-link-pnl #login_fs{margin:0 auto;width:100%;text-align:left} +#sns-link-pnl #login_fs label{display:block;display: block;font-size: 0.93em;color: #7a7a7a;margin: 5px 0;} +#sns-link-pnl #login_fs .lg_id,#sns-link-pnl #login_fs .lg_pw{width:100%;margin-bottom:5px;} +#sns-link-pnl #login_id,#sns-link-pnl #login_pw{width:100%} +#sns-link-pnl #login_fs .login_submit{width: 100%;height: 44px;font-size:1.167em;margin:10px auto 0;font-weight:bold;cursor:pointer;display:block;} +#sns-link-pnl .connect-fg {height:320px;text-align:left} +#sns-link-pnl .login_fs {margin:0 auto;width:260px} +#sns-link-pnl .connect-fg .connect-desc {margin:0 0 10px;padding:15px;border:1px solid #d6e9c6;background:#dff0d8;color:#3c763d} +#sns-link-pnl .connect-fg .connect-title {margin-top:25px;margin-bottom:10px;font-size:1.667em;font-weight:bold;text-align:center} + +.mbskin .member_connect:after {display:block;visibility:hidden;clear:both;content:""} +.mbskin .member_connect{margin-top:80px;background:#d9d9d9;border-radius:3px;padding:10px;text-align:left} +.mbskin .member_connect .strong{font-size:1em;font-weight:bold;margin:0 0 10px} +.mbskin .member_connect button{color: #fff;border:0;padding:6px 20px 7px;border:1px solid #6446e7;font-weight:bold;background: #6f50e7;border-radius:3px;font-size:0.91em} +.mbskin .member_connect button:hover{background:#6446e7} + +html.remodal-is-locked {overflow-y:scroll !important} + +@media only screen and (min-width: 641px) { + #sns-link-pnl.remodal{max-width:400px;padding:50px} +} \ No newline at end of file diff --git a/skin/visit/basic/style.css b/skin/visit/basic/style.css index 6b061cb27..039875a6a 100644 --- a/skin/visit/basic/style.css +++ b/skin/visit/basic/style.css @@ -1,13 +1,15 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* 방문자 집계 */ -#visit {border-bottom:1px dotted #dde4e9} -#visit div {margin:0 auto;width:970px;zoom:1} -#visit div:after {display:block;visibility:hidden;clear:both;content:""} -#visit h2 {float:left;padding:10px 45px 10px 0} -#visit dl {float:left;margin:0 0 0 10px;padding:0} -#visit dt {float:left;margin:0;padding:10px 0 10px} -#visit dd {float:left;margin:0 30px 0 0;padding:10px} -#visit a {display:inline-block;padding:10px;text-decoration:none} -#visit a:focus, #visit a:hover {} \ No newline at end of file +#visit {border: 1px solid #d2d9e6; border-bottom: 1px solid #c1ccda;margin:40px 20px 20px;background:#fff;position:relative; +-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.1); +-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.1); +box-shadow:0 1px 2px rgba(0,0,0,0.1)} +#visit .btn_admin{position:absolute;top:10px;right:10px;height:25px;line-height:25px;padding:0 5px;border-radius:3px} +#visit h2 {font-size:1.167em;text-align:center;padding-bottom:15px;padding-top:25px;color:#16b3d6;position:relative} +#visit h2 i{position:absolute;top:-22px;left:50%;width:44px;line-height:44px;margin-left:-22px;border-radius:25px;background:#16b3d6;color:#fff} +#visit dl {border-top:1px solid #e9e9e9;padding:10px 15px;border-radius:5px} +#visit dl:after {display:block;visibility:hidden;clear:both;content:""} +#visit dt {float:left;width:20%;padding:0 5px;line-height:23px;height:23px;color:#555} +#visit dt span{display:inline-block;width:5px;height:5px;border-radius:50%;vertical-align: middle;} +#visit dd {float:left;;width:30%;padding:0 5px;;text-align:right;text-align:right;font-weight:bold;line-height:23px;height:23px;font-size:0.92em} +#visit dd strong{display:inline-block;padding:0 5px;border-radius:20px;line-height:15px;color:#fff;} diff --git a/skin/visit/basic/visit.skin.php b/skin/visit/basic/visit.skin.php index 87e481d2e..768a58829 100644 --- a/skin/visit/basic/visit.skin.php +++ b/skin/visit/basic/visit.skin.php @@ -9,19 +9,17 @@ add_stylesheet('', 0
    -
    -

    접속자집계

    -
    -
    오늘
    -
    -
    어제
    -
    -
    최대
    -
    -
    전체
    -
    -
    - 상세보기 -
    +

    접속자집계

    +
    +
    오늘
    +
    +
    어제
    +
    +
    최대
    +
    +
    전체
    +
    +
    + 상세보기
    \ No newline at end of file diff --git a/tail.php b/tail.php index 0fe5db786..9a83862d4 100644 --- a/tail.php +++ b/tail.php @@ -13,33 +13,53 @@ if (G5_IS_MOBILE) { ?>
    +
    + + + + +
    +

    - - -
    <?php echo G5_VERSION ?>
    -
    -
    -
    -
    + +
    + +
    <?php echo G5_VERSION ?>
    +
    Copyright © 소유하신 도메인. All rights reserved.
    + + +
    -모바일 버전으로 보기 +
    -
    +
    - +
    diff --git a/theme/basic/head.php b/theme/basic/head.php index 2d5bf0af9..61aaaef61 100644 --- a/theme/basic/head.php +++ b/theme/basic/head.php @@ -26,134 +26,202 @@ include_once(G5_LIB_PATH.'/popular.lib.php'); include G5_BBS_PATH.'/newwin.inc.php'; // 팝업레이어 } ?> +
    + +
    +
    + 사이트 내 전체검색 +
    + + + + + +
    -
    - 사이트 내 전체검색 -
    - - - - - -
    + - // 검색에 많은 부하가 걸리는 경우 이 주석을 제거하세요. - var cnt = 0; - for (var i=0; i 1) { - alert("빠른 검색을 위하여 검색어에 공백은 한개만 입력할 수 있습니다."); - f.stx.select(); - f.stx.focus(); - return false; - } - - return true; - } - -
    - -
    - - - - +
    + +
    - -
    - -
    - +
    +
    +
    -
    - - -
    +
    +
    -
    \ No newline at end of file +

    + diff --git a/theme/basic/head.sub.php b/theme/basic/head.sub.php index a282caaf2..fdbcf09af 100644 --- a/theme/basic/head.sub.php +++ b/theme/basic/head.sub.php @@ -39,7 +39,7 @@ if (G5_IS_MOBILE) { echo ''.PHP_EOL; } else { echo ''.PHP_EOL; - echo ''.PHP_EOL; + echo ''.PHP_EOL; } if($config['cf_add_meta']) @@ -66,6 +66,8 @@ var g5_cookie_domain = ""; + + '.PHP_EOL; // overflow scroll 감지 @@ -74,7 +76,7 @@ if(!defined('G5_IS_ADMIN')) echo $config['cf_add_script']; ?> - +>

    최신글

    + +
    - 'mobile' "; -if(!$is_admin) - $sql .= " and a.bo_use_cert = '' "; -$sql .= " order by b.gr_order, a.bo_order "; -$result = sql_query($sql); -for ($i=0; $row=sql_fetch_array($result); $i++) { - if ($i%2==1) $lt_style = "margin-left:20px"; - else $lt_style = ""; -?> -
    + + 'mobile' "; + if(!$is_admin) + $sql .= " and a.bo_use_cert = '' "; + $sql .= " and a.bo_table not in ('notice', 'gallery') "; //공지사항과 갤러리 게시판은 제외 + $sql .= " order by b.gr_order, a.bo_order "; + $result = sql_query($sql); + for ($i=0; $row=sql_fetch_array($result); $i++) { + if ($i%2==1) $lt_style = "margin-left:2%"; + else $lt_style = ""; + ?> +
    - - + + + +
    + +
    + + + +
    - +
    + +
      '.PHP_EOL; + echo ' - + +
      +

      사이트 내 전체검색

      +
      + + + + +
      + + +
    - + +
    + -
    -

    사이트 내 전체검색

    -
    - - - - -
    + - - +
    + + + + +
    - - - +
    -
    +
    -
    - -
    +
    -
    -
    - - - - -
    \ No newline at end of file +

    diff --git a/theme/basic/mobile/skin/board/basic/img/btn_next2.gif b/theme/basic/mobile/skin/board/basic/img/btn_next2.gif new file mode 100644 index 000000000..f17993bb1 Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/btn_next2.gif differ diff --git a/theme/basic/mobile/skin/board/basic/img/btn_prev2.gif b/theme/basic/mobile/skin/board/basic/img/btn_prev2.gif new file mode 100644 index 000000000..63604af1a Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/btn_prev2.gif differ diff --git a/theme/basic/mobile/skin/board/basic/img/cmt_btn.png b/theme/basic/mobile/skin/board/basic/img/cmt_btn.png new file mode 100644 index 000000000..202f1ff47 Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/cmt_btn.png differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_bad.png b/theme/basic/mobile/skin/board/basic/img/icon_bad.png new file mode 100644 index 000000000..e568b1d83 Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/icon_bad.png differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_comment.png b/theme/basic/mobile/skin/board/basic/img/icon_comment.png new file mode 100644 index 000000000..bd7e67f33 Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/icon_comment.png differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_file.gif b/theme/basic/mobile/skin/board/basic/img/icon_file.gif index cca47f566..244af004d 100644 Binary files a/theme/basic/mobile/skin/board/basic/img/icon_file.gif and b/theme/basic/mobile/skin/board/basic/img/icon_file.gif differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_good.png b/theme/basic/mobile/skin/board/basic/img/icon_good.png new file mode 100644 index 000000000..69841a134 Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/icon_good.png differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_hot.gif b/theme/basic/mobile/skin/board/basic/img/icon_hot.gif index c95b839ae..4e8d7ff1b 100644 Binary files a/theme/basic/mobile/skin/board/basic/img/icon_hot.gif and b/theme/basic/mobile/skin/board/basic/img/icon_hot.gif differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_link.gif b/theme/basic/mobile/skin/board/basic/img/icon_link.gif index 0f3cb1ac6..e9cb9559c 100644 Binary files a/theme/basic/mobile/skin/board/basic/img/icon_link.gif and b/theme/basic/mobile/skin/board/basic/img/icon_link.gif differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_lock.png b/theme/basic/mobile/skin/board/basic/img/icon_lock.png new file mode 100644 index 000000000..2a083a51d Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/icon_lock.png differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_reply.gif b/theme/basic/mobile/skin/board/basic/img/icon_reply.gif index 91c135977..7fe2c6558 100644 Binary files a/theme/basic/mobile/skin/board/basic/img/icon_reply.gif and b/theme/basic/mobile/skin/board/basic/img/icon_reply.gif differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_secret.gif b/theme/basic/mobile/skin/board/basic/img/icon_secret.gif index c04899f14..7be670092 100644 Binary files a/theme/basic/mobile/skin/board/basic/img/icon_secret.gif and b/theme/basic/mobile/skin/board/basic/img/icon_secret.gif differ diff --git a/theme/basic/mobile/skin/board/basic/img/icon_view.png b/theme/basic/mobile/skin/board/basic/img/icon_view.png new file mode 100644 index 000000000..bfa5eb1e6 Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/icon_view.png differ diff --git a/theme/basic/mobile/skin/board/basic/img/require.png b/theme/basic/mobile/skin/board/basic/img/require.png new file mode 100644 index 000000000..c03e1eb6f Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/require.png differ diff --git a/theme/basic/mobile/skin/board/basic/img/sch_btn.png b/theme/basic/mobile/skin/board/basic/img/sch_btn.png new file mode 100644 index 000000000..94f98db8f Binary files /dev/null and b/theme/basic/mobile/skin/board/basic/img/sch_btn.png differ diff --git a/theme/basic/mobile/skin/board/basic/list.skin.php b/theme/basic/mobile/skin/board/basic/list.skin.php index f651a3aff..ebdacd66f 100644 --- a/theme/basic/mobile/skin/board/basic/list.skin.php +++ b/theme/basic/mobile/skin/board/basic/list.skin.php @@ -10,10 +10,15 @@ if ($is_checkbox) $colspan++; add_stylesheet('', 0); ?> -

    목록

    - + + + -
    "> +
    -
    -
    - Total - 페이지 -
    - - - - +
    + 전체 + 페이지
    +
    @@ -49,79 +45,75 @@ add_stylesheet('', 0 -
      -
    • 목록
    • +
    • 목록
    • -
    • -
    • -
    • +
    • +
    • +
    - -
    @@ -144,7 +136,7 @@ add_stylesheet('', 0 - @@ -153,8 +145,8 @@ add_stylesheet('', 0 - - + + diff --git a/theme/basic/mobile/skin/board/basic/style.css b/theme/basic/mobile/skin/board/basic/style.css index b1d433d3a..af21b8c7d 100644 --- a/theme/basic/mobile/skin/board/basic/style.css +++ b/theme/basic/mobile/skin/board/basic/style.css @@ -1,5 +1,4 @@ @charset "utf-8"; -/* SIR 지운아빠 */ /* ### 기본 스타일 커스터마이징 시작 ### */ @@ -11,7 +10,7 @@ #bo_list a.btn_b02:focus, #bo_list .btn_b02:hover {} #bo_list a.btn_admin {} /* 관리자 전용 버튼 */ #bo_list a.btn_admin:focus, #bo_list a.btn_admin:hover {} - +.chk_all{margin:10px 0} /* 읽기 버튼 */ #bo_v a.btn_b01 {} #bo_v a.btn_b01:focus, #bo_v .btn_b01:hover {} @@ -26,55 +25,6 @@ #bo_w .btn_cancel {} #bo_w .btn_frmline {} /* 우편번호검색버튼 등 */ -/* 기본테이블 */ -/* 목록 테이블 */ -#bo_list .tbl_head01 {} -#bo_list .tbl_head01 caption {} -#bo_list .tbl_head01 thead th {} -#bo_list .tbl_head01 thead a {} -#bo_list .tbl_head01 thead th input {} /* middle 로 하면 게시판 읽기에서 목록 사용시 체크박스 라인 깨짐 */ -#bo_list .tbl_head01 tfoot th {} -#bo_list .tbl_head01 tfoot td {} -#bo_list .tbl_head01 tbody th {} -#bo_list .tbl_head01 td {} -#bo_list .tbl_head01 a {} -#bo_list td.empty_table {} - -/* 읽기 내 테이블 */ -#bo_v .tbl_head01 {} -#bo_v .tbl_head01 caption {} -#bo_v .tbl_head01 thead th {} -#bo_v .tbl_head01 thead a {} -#bo_v .tbl_head01 thead th input {} /* middle 로 하면 게시판 읽기에서 목록 사용시 체크박스 라인 깨짐 */ -#bo_v .tbl_head01 tfoot th {} -#bo_v .tbl_head01 tfoot td {} -#bo_v .tbl_head01 tbody th {} -#bo_v .tbl_head01 td {} -#bo_v .tbl_head01 a {} -#bo_v td.empty_table {} - -/* 쓰기 테이블 */ -#bo_w table {} -#bo_w caption {} -#bo_w .frm_address {} -#bo_w .frm_file {} -#bo_w .frm_info {} - -#bo_w .tbl_frm01 {} -#bo_w .tbl_frm01 caption {} -#bo_w .tbl_frm01 th {} -#bo_w .tbl_frm01 td {} -#bo_w .tbl_frm01 textarea, #bo_w .frm_input {} -#bo_w .tbl_frm01 textarea {} -/* -#bo_w .tbl_frm01 #captcha {} -#bo_w .tbl_frm01 #captcha input {} -*/ -#bo_w .tbl_frm01 a {} - -#bo_w .required, #bo_w textarea.required {} - -/* ### 기본 스타일 커스터마이징 끝 ### */ /* 게시판 목록 */ #bo_list .td_chk {width:30px;text-align:center} @@ -88,14 +38,24 @@ #bo_list .td_date {width:60px;text-align:center} #bo_list .td_datetime {width:150px;text-align:center} #bo_list .td_mng {width:80px;text-align:center} +#bo_list .notice_icon{display: inline-block;background: #ff6f6f;padding: 0 5px;line-height: 20px;border-radius: 5px;font-weight: normal;font-size:11px;color: #fff;} +#bo_list .notice_icon i{color:#fff} +#bo_list .bo_subject .fa-download{width:16px;height:16px;line-height:16px;background:#ecaa30;color:#fff;text-align:center;font-size:10px;border-radius:2px} +#bo_list .bo_subject .fa-link{width:16px;height:16px;line-height:16px;background:#2aa974;color:#fff;text-align:center;font-size:10px;border-radius:2px} +#bo_list .bo_subject .fa-heart{color:#ff0000;;text-align:center;font-size:10px;border-radius:2px} +#bo_list .bo_subject .new_icon{display:inline-block;padding: 0 3px;line-height:16px ;font-size:0.833em;color:#fff;background:#c56bed} +#bo_list .bo_tit .fa-lock{color:#666} + #bo_cate h2 {width:0;height:0;font-size:0;line-height:0;overflow:hidden} -#bo_cate ul {margin:5px 10px;padding-left:1px;zoom:1} -#bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} -#bo_cate li {float:left;margin-bottom:-1px;width:25%} -#bo_cate a {display:block;position:relative;margin-left:-1px;padding:5px 0;border:1px solid #ddd;background:#f7f7f7;color:#888;text-align:center;text-decoration:none;letter-spacing:-0.1em} -#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none} -#bo_cate #bo_cate_on {z-index:2;border:1px solid #565e60;background:#fff;color:#565e60;font-weight:bold} +#bo_cate ul {margin: 10px;padding-left:1px;zoom:1} +#bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} +#bo_cate li{display:inline-block;float:left;margin:3px 5px 3px 0} +#bo_cate a {display:block;line-height:24px;padding:0 10px;border-radius:13px;background:#fff;} +#bo_cate #bo_cate_on {background:#4162ff;color:#fff; +-webkit-box-shadow:0 0 5px rgba(65,98,255,0.8); +-moz-box-shadow:0 0 5px rgba(65,98,255,0.8); +box-shadow: 0 0 8px rgba(65,98,255,0.8);} /* 관리자일 때 */ #bo_list_admin th label {position:absolute;font-size:0;line-height:0;overflow:hidden} @@ -108,29 +68,40 @@ /* 관리자가 아닐 때 */ #bo_list th:nth-of-type(2) {width:100px} - #bo_list td:nth-of-type(2) {text-align:center} /* 게시판 목록 공통 */ -.bo_fx {margin-bottom:5px;padding:5px 10px} +.bo_fx {margin-bottom:5px;padding:0 10px} .bo_fx:after {display:block;visibility:hidden;clear:both;content:""} .bo_fx ul {margin:0;padding:0;list-style:none} -#bo_list_total {float:left;padding:0;height:2.5em;line-height:2.5em} +#bo_list_total{position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden;font-size:0} .btn_bo_user {float:right;margin:0;padding:0;list-style:none} .btn_bo_user li {float:left;margin-left:5px} -.btn_bo_adm {float:left} -.btn_bo_adm li {float:left;margin-right:5px} -.btn_bo_adm input {padding:8px;border:0;background:#e8180c;color:#fff;text-decoration:none;vertical-align:middle} +.btn_bo_adm {text-align:center} +.btn_bo_adm li {display:inline-block;} +.btn_bo_adm button {border:0;padding:0 10px;background:#d13f4a;color:#fff;text-decoration:none;vertical-align:middle} .bo_notice td {background:#f7f7f7} .bo_notice td a {font-weight:bold} .td_num strong {color:#000} -.bo_cate_link {display:inline-block;margin:0 3px 0 0;padding:0 6px 0 0;border-right:1px solid #e7f1ed;color:#999 !important;font-weight:bold;text-decoration:none} /* 글제목줄 분류스타일 */ +.bo_cate_link {;color:#3ca1ff !important;font-weight:normal;text-decoration:none;font-size:0.92em} /* 글제목줄 분류스타일 */ +.bo_subject{display:block;font-size:1.083em;font-weight:bold;margin:5px 0} +.bo_subject i{color: #8d96c2;font-size:12px} +.bo_subject .fa-heart{color:#ff0000} .bo_current {color:#e8180c} -.td_subject a {display:block} -.td_subject img {margin-left:3px} -#bo_list .cnt_cmt {display:inline-block;margin:0 0 0 3px;font-weight:bold} +.bo_info{border-top: 1px solid #eee;margin: 10px 0 0;line-height: 20px;color: #666;position: relative;padding-top: 10px;vertical-align:top} +.bo_info .comment_icon{background:url(./img/icon_comment.png) no-repeat 50% 50% ;display:inline-block;width:20px;height:28px;text-indent:-999px;overflow:hidden;vertical-align:top;background-size:70%;margin:0 0px 0 5px} +.bo_info .bo_date{position:absolute;top:10px;right:0;font-style: italic;} +.bo_info .cnt_cmt {display:inline-block;margin: 0 5px 0 3px;} +.bo_info .profile_img img{border-radius:50%;vertical-align:top} -#bo_sch {margin-bottom:10px;padding-top:5px;text-align:center} +#bo_sch {background:#fff;border:1px solid #bdc2d8;position:relative;margin:10px;border-radius:3px} +#bo_sch:after {display:block;visibility:hidden;clear:both;content:""} +#bo_sch legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} +#bo_sch select{border:0;;margin:9px 0;height:20px;border-right:1px solid #ddd;float:left;width:40%} +#bo_sch .sch_input{height:38px;border:0;padding:0;background-color:transparent;float:left;width:60%;padding:0 40px 0 10px} +#bo_sch .sch_btn{height:38px;position:absolute;top:0;right:0;border:0;width:40px;background:none;font-size:15px} + +#bo_list{margin:10px 0} /* 게시판 쓰기 */ #bo_w #wr_email, #bo_w #wr_homepage, #bo_w #wr_subject {width:100%} @@ -142,97 +113,163 @@ #wr_email, #wr_homepage, #wr_subject, .wr_link {width:100%} /* 게시판 읽기 */ -#bo_v {margin-bottom:15px;padding-bottom:15px} +#bo_v {padding:20px 10px 10px;background:#fff +;-webkit-box-shadow: 0 1px 4px #ddd; +-moz-box-shadow: 0 1px 4px #ddd; +box-shadow: 0 1px 4px #ddd;} -#bo_v_table {padding:0 10px;color:#999;font-size:0.9em;font-weight:bold} +#bo_v_table {padding: 10px;color:#999;font-size:0.9em;font-weight:bold} -#bo_v_title {padding:0 10px 5px;font-size:1.2em} +#bo_v_title {;text-align:center} +.bo_v_cate{display:inline-block;background: #4162ff;color: #fff;border-radius: 13px;line-height: 24px;padding: 0 10px;font-weight:normal; +-webkit-box-shadow: 0 0 5px rgba(65,98,255,0.8); +-moz-box-shadow: 0 0 5px rgba(65,98,255,0.8); +box-shadow: 0 0 8px rgba(65,98,255,0.8);} +.bo_v_tit{display:block;font-size:1.5em;margin:10px 0 0} +#bo_v header p{font-size:0.92em;color:#777;font-style:italic ;text-align:center;margin:10px 0 0 } -#bo_v_info {padding:0 10px 10px;border-bottom:1px solid #ddd} +#bo_v_info {padding:15px 0px 10px;border-bottom:1px solid #eee;text-align:center;color:#666;line-height:20px;} #bo_v_info h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} -#bo_v_info {} -#bo_v_info strong {display:inline-block;margin:0 0 0 5px;font-weight:normal} +#bo_v_info strong {display:inline-block;font-weight:normal;margin:0 5px} +#bo_v_info .profile_img img{border-radius:50%;vertical-align:top} +#bo_v_info .icon_view{display:inline-block;background:url(./img/icon_view.png) no-repeat 50% 50%;background-size:80%;height:15px;width:20px;overflow:hidden;text-indent:-999px;vertical-align:middle;margin:0 3px 0 5px} +#bo_v_info .icon_comment{display:inline-block;background:url(./img/icon_comment.png) no-repeat 50% 50%;background-size:70%;height:15px;width:20px;overflow:hidden;text-indent:-999px;vertical-align:middle;margin:0 3px 0 5px} -#bo_v_file {} -#bo_v_file h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} +#bo_v_file {margin:10px 0} +#bo_v_file h2 {background:#949ab4;color:#fff;margin-bottom:1px;line-height:35px;padding: 0 10px} #bo_v_file ul {margin:0;padding:0;list-style:none} -#bo_v_file li {padding:0 10px;border-bottom:1px solid #eee;background:#f7f7f7} -#bo_v_file a {display:inline-block;padding:5px 0;color:#000;text-decoration:none} +#bo_v_file li {padding: 10px;border-bottom:1px solid #fff;background:#f1f7fa;color:#777} +#bo_v_file a {display:block;color:#000;text-decoration:none;margin:0 0 3px} #bo_v_file a:focus, #bo_v_file a:hover, #bo_v_file a:active {text-decoration:none} -.bo_v_file_cnt {display:inline-block;margin:0 10px} +#bo_v_file a strong{color:#3497d9;text-decoration:underline} +.bo_v_file_cnt {font-size:0.92em} -#bo_v_link {} -#bo_v_link h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} +#bo_v_link{margin:10px 0} +#bo_v_link h2 {background:#949ab4;color:#fff;margin-bottom:1px;line-height:35px;padding: 0 10px} #bo_v_link ul {margin:0;padding:0;list-style:none} -#bo_v_link li {padding:0 10px;border-bottom:1px solid #eee;background:#f7f7f7} -#bo_v_link a {display:inline-block;padding:5px 0;color:#000;text-decoration:none} +#bo_v_link li {padding: 10px;border-bottom:1px solid #fff;background:#f1f7fa;color:#777} +#bo_v_link a {display:block;color:#000;text-decoration:none;margin:0 0 3px} +#bo_v_link a strong{color:#3497d9;text-decoration:underline} #bo_v_link a:focus, #bo_v_link a:hover, #bo_v_link a:active {text-decoration:none} -.bo_v_link_cnt {display:inline-block;margin:0 10px} +.bo_v_link_cnt {font-size:0.92em} -#bo_v_top {margin:0 0 10px;padding:10px} +#bo_v_top {margin:10px 0;} #bo_v_top:after {display:block;visibility:hidden;clear:both;content:""} #bo_v_top h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} #bo_v_top ul {margin:0;padding:0;list-style:none} +#bo_v_top ul:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_top ul li{display:inline-block;} +.bo_v_left{float:left} +.bo_v_right{float:right} #bo_v_bot {padding:0 10px} #bo_v_bot:after {display:block;visibility:hidden;clear:both;content:""} #bo_v_bot h2 {position:absolute;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} #bo_v_bot ul {margin:0;padding:0;list-style:none} -.bo_v_nb {float:left} -.bo_v_nb li {float:left;margin-right:5px} -.bo_v_com {float:right} -.bo_v_com li {float:left;margin-left:5px} +.bo_v_nb{margin:10px 0;border-top:1px solid #ddd;border-bottom:1px solid #ddd;text-align:center;position:relative;} +.bo_v_nb:after {display:block;visibility:hidden;clear:both;content:""} +.bo_v_nb li {} +.bo_v_nb li a{display:inline-block;padding:10px;color:#777} +.bo_v_nb .bo_v_next{;position:absolute;top:0;right:0;} +.bo_v_nb .bo_v_prev{;position:absolute;top:0;left:0;} -#bo_v_atc {padding:0 10px;min-height:200px} +#bo_v_atc {min-height:200px} #bo_v_atc_title {margin:0;padding:0;height:0;overflow:hidden} #bo_v_img {margin:0 0 10px;width:100%;overflow:hidden;zoom:1} #bo_v_img:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_img a.view_image{display:block} #bo_v_img img {margin-bottom:15px;max-width:100%;height:auto} -#bo_v_con {margin-bottom:20px;width:100%;font-size:1.250em;line-height:1.7em;word-break:break-all;overflow:hidden} +#bo_v_con {min-height:200px;margin-bottom:20px;width:100%;font-size:1.250em;line-height:1.7em;word-break:break-all;overflow:hidden} #bo_v_con a {color:#000;text-decoration:underline} #bo_v_con img {max-width:100%;height:auto} -#bo_v_act {position:relative;margin-bottom:20px;text-align:center} +#bo_v_act {margin-bottom:30px;text-align:center} +#bo_v_act .bo_v_act_gng {position:relative} #bo_v_act a {margin-right:5px;vertical-align:middle} -#bo_v_act strong {color:#ff3061} -#bo_v_act_good, #bo_v_act_nogood {display:none;position:absolute;top:30px;right:10%;padding:10px 0;width:165px;background:#ff3061;color:#fff;text-align:center} +#bo_v_act a:hover{background-color:#f3f3f3} +#bo_v_act_good, #bo_v_act_nogood {display:none;position:absolute;top:30px;left:0;padding:10px 0;width:165px;background:#ff3061;color:#fff;text-align:center} +#bo_v_act .bo_v_good{padding:15px 0;display:inline-block;border:1px solid #000;width:70px;height:70px;line-height:20px;border-radius:50%;font-style:italic} +#bo_v_act .bo_v_nogood{padding:15px 0;display:inline-block;border:1px solid #000;width:70px;height:70px;line-height:20px;border-radius:50%;font-style:italic} +#bo_v_act .bo_v_good i,#bo_v_act .bo_v_nogood i{font-size:18px;} +#bo_v_share{position:relative;margin:20px 0;text-align:right} +#bo_v_share:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_share .btn_scrap{display:inline-block;background:#d4d4d4;color:#444;line-height:40px;width:60px;font-weight:bold;text-align:center;float:left;border-radius:3px} -#bo_v_sns {margin:0 0 20px;padding:0;list-style:none;zoom:1} +.btn_share{display:none;} +.bo_v_snswr{position:relative;float:right} +#bo_v_sns {;padding:0;list-style:none;zoom:1} #bo_v_sns:after {display:block;visibility:hidden;clear:both;content:""} -#bo_v_sns li {float:left;margin:0 5px 0 0} +#bo_v_sns li {float:left;width:50px;text-align:center;margin-left:3px} +#bo_v_sns li a{height:40px;padding:10px 0;} +#bo_v_sns li .sns_f{display:block;background:#415b92;border-radius:3px} +#bo_v_sns li .sns_t{display:block;background:#35b3dc;border-radius:3px} +#bo_v_sns li .sns_g{display:block;background:#d5503a;border-radius:3px} +#bo_v_sns li .sns_k{display:block;background:#fbe300;border-radius:3px} +#bo_v_sns li img{vertical-align:top} /* 게시판 댓글 */ -#bo_vc {margin:0 0 20px;padding:20px 10px 10px;border:1px solid #e5e8ec;background:#f5f8f9} -#bo_vc h2 {margin-bottom:5px} -#bo_vc article {padding:0 0 5px;border-top:1px dotted #ccc} -#bo_vc header {position:relative;padding:13px 0 5px} -#bo_vc header .icon_reply {position:absolute;top:13px;left:-20px} +.cmt_btn{background:url('./img/cmt_btn.png') no-repeat right 8px;text-align:left ;width:100% ;border:0;color:#ed6478;font-weight:bold;font-size:1.167em;margin: 20px 0 10px;padding:0 0 10px ;border-bottom:1px solid #e8e8e8} +.cmt_btn_op{background:url('./img/cmt_btn.png') no-repeat right -23px} + +#bo_vc {} +#bo_vc h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_vc article {margin:0 0 15px} +#bo_vc header {position:relative;padding:0 0 0 50px;height:40px;line-height:20px} +#bo_vc .comment_profile_img{position:absolute;top:0;left:0} +#bo_vc .comment_profile_img img, #bo_vc .profile_img img{border-radius:50%} #bo_vc .sv_member, #bo_vc .sv_guest {font-weight:bold} -.bo_vc_hdinfo {display:inline-block;margin:0 10px 0 5px} +.bo_vc_hdinfo {display:inline-block;color:#777;font-style:italic} #bo_vc h1 {width:0;height:0;font-size:0;line-height:0;overflow:hidden} -#bo_vc a {color:#000;text-decoration:none} -#bo_vc p {padding:0 0 5px;line-height:1.8em} +#bo_vc .cmt_contents {padding:10px 15px ;margin:5px 0 0 ;border-radius:5px;background:#f6f6f6;line-height:1.8em} +#bo_vc .cmt_contents p{font-size:1.083em} #bo_vc p a {text-decoration:underline} -#bo_vc p a.s_cmt {text-decoration:none} +#bo_vc p a.s_cmt {text-decoration:underline;color:#ed6479} #bo_vc_empty {margin:0;padding:15px !important;text-align:center} #bo_vc #bo_vc_winfo {float:left} #bo_vc footer {zoom:1} #bo_vc footer:after {display:block;visibility:hidden;clear:both;content:""} -.bo_vc_act {float:right;margin:0;list-style:none} +.bo_vc_act {text-align:right;;margin:0;list-style:none} .bo_vc_act:after {display:block;visibility:hidden;clear:both;content:""} -.bo_vc_act li {float:left;margin-left:5px} +.bo_vc_act li {display:inline-block;margin:0 2px} +.bo_vc_act li a{color:#3497d9;text-decoration:underline} -#bo_vc_w {position:relative;margin-bottom:10px;padding:0 10px 15px;border-bottom:1px solid #dde4e9} -#bo_vc_w h2 {padding:10px 0 5px} -#bo_vc_w .tbl_wrap {margin:0 0 15px} -#bo_vc_w #char_cnt {display:block;margin-bottom:5px} -#bo_vc_w textarea {width:99%} +.bo_vc_w {position:relative;margin:10px 0;display:block;} +.bo_vc_w:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +.bo_vc_w #char_cnt {display:block;margin:0 0 5px} +.bo_vc_w textarea{border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;width:100%;height:120px} +#wr_secret{} +.bo_vc_w_info{margin:5px 0} +.bo_vc_w_info:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w_info .frm_input{float:left;;width:49.5%;margin: 0 0 5px 0} +.bo_vc_w_info #wr_password{float:right;} +.bo_vc_w_info #captcha{;display:block;clear:both} +.bo_vc_w .btn_confirm{margin-top:5px;clear:both} +.bo_vc_w .icon_lock{display:inline-block;font-size:17px;padding: 5px;margin-right:5px;} +.bo_vc_w .btn_submit{height:50px;width:100%;padding:0 20px;border-radius:3px;font-weight:bold;font-size:1.083em;} +.bo_vc_w_wr:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w .bo_vc_secret{float:right;display:block;} -#bo_vc_sns {margin:0;padding:0;list-style:none;zoom:1} +#bo_vc_send_sns{display:block;float:left} +#bo_vc_sns {display:block;margin:0;padding:0;list-style:none;zoom:1} #bo_vc_sns:after {display:block;visibility:hidden;clear:both;content:""} -#bo_vc_sns li {float:left;margin:0 10px 0 0} -#bo_vc_sns input {margin:0 0 0 5px} \ No newline at end of file +#bo_vc_sns li {float:left;margin:0 5px 0 0} +#bo_vc_sns .sns_li_f{border-radius:3px;background:#3a589b;height:40px;;padding: 10px 0 10px 10px} +#bo_vc_sns .sns_li_t{border-radius:3px;background:#00aced;height:40px;;padding: 10px 0 10px 10px} +#bo_vc_sns .sns_li_off{background:#bbb} +#bo_vc_sns a{display:inline-block;padding:0 15px 0 5px;} +#bo_vc_sns input {margin:0 5px 0 0 } + +/*글쓰기*/ +#bo_w .bo_w_select select{border:1px solid #3497d9;background:#fff;width:100%} +#bo_w .bo_w_link label{position:absolute;top:1px;left:1px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;background:#eee;text-align:center} +#bo_w .bo_w_link .frm_input{padding-left:50px} +#bo_w .bo_w_flie .lb_icon{position:absolute;top:0px;left:0px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;background:#eee;text-align:center} +#bo_w .bo_w_flie .frm_file{padding-left:50px;} +#bo_w .bo_w_flie .file_wr{border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;height:40px;margin:0} +#bo_w .bo_w_flie .frm_input{margin:5px 0 0 } + diff --git a/theme/basic/mobile/skin/board/basic/view.skin.php b/theme/basic/mobile/skin/board/basic/view.skin.php index d8f85841d..69490ffb2 100644 --- a/theme/basic/mobile/skin/board/basic/view.skin.php +++ b/theme/basic/mobile/skin/board/basic/view.skin.php @@ -8,112 +8,46 @@ add_stylesheet('', 0 -
    + +
    -

    +

    + + + + -

    + ?> + +

    작성일

    페이지 정보

    - 작성자 - 작성일 - 조회 - 댓글 + 작성자 + 조회 + 댓글
    - - - -
    -

    첨부파일

    - -
    - - - - - -
    - - - +
    + +

    댓글목록

    @@ -23,54 +25,53 @@ var char_max = parseInt(); // 최대 ?>
    style="margin-left:px;border-top-color:#e0e0e0">
    -

    님의 댓글

    - - 댓글의 댓글 +

    님의 댓글의 댓글

    + + - 아이피 - + 아이피 + () - 작성일 +
    + 작성일
    +
    + +

    + "; ?> + +

    - -

    - "; ?> - -

    + "> - + if($w == 'cu') { + $sql = " select wr_id, wr_content, mb_id from $write_table where wr_id = '$c_id' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + if (!($is_admin || ($member['mb_id'] == $cmt['mb_id'] && $cmt['mb_id']))) + $cmt['wr_content'] = ''; + $c_wr_content = $cmt['wr_content']; + } + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w'; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w'; + ?> + + +
    + + "> - - -

    등록된 댓글이 없습니다.

    @@ -83,7 +84,7 @@ var char_max = parseInt(); // 최대 ?> @@ -259,7 +246,10 @@ var char_max = parseInt(); // 최대 function comment_box(comment_id, work) { - var el_id; + var el_id, + form_el = 'fviewcomment', + respond = document.getElementById(form_el); + // 댓글 아이디가 넘어오면 답변, 수정 if (comment_id) { @@ -276,11 +266,13 @@ var char_max = parseInt(); // 최대 if (save_before) { document.getElementById(save_before).style.display = 'none'; - document.getElementById(save_before).innerHTML = ''; } document.getElementById(el_id).style.display = ''; - document.getElementById(el_id).innerHTML = save_html; + document.getElementById(el_id).appendChild(respond); + //입력값 초기화 + document.getElementById('wr_content').value = ''; + // 댓글 수정 if (work == 'cu') { @@ -311,15 +303,26 @@ var char_max = parseInt(); // 최대 comment_box('', 'c'); // 댓글 입력폼이 보이도록 처리하기위해서 추가 (root님) - // sns 등록 $(function() { + // sns 등록 $("#bo_vc_send_sns").load( "/view_comment_write.sns.skin.php?bo_table=", function() { save_html = document.getElementById('bo_vc_w').innerHTML; } ); + + + }); + + $(function() { + //댓글열기 + $(".cmt_btn").click(function(){ + $(this).toggleClass("cmt_btn_op"); + $("#bo_vc").toggle(); + }); + }); diff --git a/theme/basic/mobile/skin/board/basic/write.skin.php b/theme/basic/mobile/skin/board/basic/write.skin.php index aa5f5b4ad..31e01e4cf 100644 --- a/theme/basic/mobile/skin/board/basic/write.skin.php +++ b/theme/basic/mobile/skin/board/basic/write.skin.php @@ -6,8 +6,6 @@ add_stylesheet('', 0 ?>
    -

    -
    @@ -51,115 +49,113 @@ add_stylesheet('', 0 echo $option_hidden; ?> -
    - - - +
    +

    + + +
    + + +
    + + -
    - - - +
    + + +
    - - - - +
    + + class="frm_input full_input " maxlength="20" placeholder="비밀번호"> +
    - - - - +
    + + +
    - - - - +
    + + +
    - - - - +
    + 옵션 + +
    - - - - - - +
    + + +
    - - - - +
    + + + +

    이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

    + + + + +
    글자
    + +
    - - - - - - - - + + - - - - +
    +
    + + +
    + + + + + + + + + + +
    - - - - - + +
    + 자동등록방지 + + +
    - -
    class="frm_input " maxlength="20">
    옵션
    - -
    - - -

    이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

    - - - - -
    글자
    - -
    " id="wr_link" class="frm_input wr_link">
    파일 # - - - - - - - -
    자동등록방지 - -
    -
    - +
    취소 +
    diff --git a/theme/basic/mobile/skin/board/gallery/list.skin.php b/theme/basic/mobile/skin/board/gallery/list.skin.php index 598b13675..9248df798 100644 --- a/theme/basic/mobile/skin/board/gallery/list.skin.php +++ b/theme/basic/mobile/skin/board/gallery/list.skin.php @@ -8,7 +8,13 @@ add_stylesheet('', 0 -

    목록

    + + +
    @@ -22,19 +28,9 @@ add_stylesheet('', 0 -
    -
    - Total - 페이지 -
    - - - - +
    + 전체 + 페이지
    @@ -60,47 +56,49 @@ add_stylesheet('', 0
  • - - - - - - 열람중"; - else - echo $list[$i]['num']; - ?> - - + 작성자 +
    + 조회 + 추천 + 비추천 + 작성일 +
    +
  • +
    게시물이 없습니다."; } ?> @@ -130,29 +130,20 @@ add_stylesheet('', 0
      -
    • 목록
    • +
    • 목록
    • -
    • -
    • -
    • +
    • +
    • +
    - -
    -
    -
    - - - - - - + echo ''.PHP_EOL; + } + ?> + + + 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. + +
    + 본인확인성인인증 완료 +
    + + + - - - - +
  • + + + + 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    + 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. +
    + + + + +
  • - - - - + + + - - - - +
  • + + " maxlength="255" placeholder="홈페이지"> +
  • - - - - +
  • + + " maxlength="20" placeholder="전화번호"> +
  • - - - - +
  • + + + class="frm_input full_input " maxlength="20" placeholder="휴대폰번호"> + + + + +
  • - - - - +
  • + 주소필수 + + class="frm_input " size="5" maxlength="6" placeholder="우편번호"> +
    + + class="frm_input frm_address " size="50" placeholder="주소">
    + + +
    + + + + +
  • -
    개인정보 입력
    - - 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. - - class="frm_input "> - 아이핀 본인확인'.PHP_EOL; - if($config['cf_cert_hp']) - echo ''.PHP_EOL; +
    + +

    개인정보 입력

    +
  • + + class="frm_input full_input " placeholder="이름"> + 아이핀 본인확인'.PHP_EOL; + if($config['cf_cert_hp'] && $config['cf_cert_hp'] != 'lg') + echo ''.PHP_EOL; - echo ''.PHP_EOL; - } - ?> - -
    - 본인확인성인인증 완료 -
    - -
  • - - 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    - 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. -
    - - - -
    +
  • + + @@ -104,155 +99,170 @@ add_stylesheet('', - -
  • " maxlength="255" >
    " maxlength="20" >
    - class="frm_input " maxlength="20"> - - - -
    - 주소 - 필수 - - - class="frm_input " size="5" maxlength="6"> -
    - - class="frm_input frm_address " size="50">
    - - -
    - - - -
    -
    - - +
    + +

    기타 개인설정

    -
    - - - +
  • + + +
  • - - - - +
  • + + +
  • = $config['cf_icon_level']) { ?> - - - - +
  • + + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다. +
    + + 회원아이콘 + + + + +
  • - - - - + = $config['cf_icon_level'] && $config['cf_member_img_size'] && $config['cf_member_img_width'] && $config['cf_member_img_height']) { ?> +
  • + + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다. +
    + + 회원아이콘 + + + + +
  • + + +
  • + + >정보 메일을 받겠습니다. + +
  • - - - - + + - - - - +
  • + + > + 다른분들이 나의 정보를 볼 수 있도록 합니다. + + 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. + + + +
  • - - - - +
  • + 정보공개 + + + + 정보공개는 수정후 일 이내, 까지는 변경이 안됩니다.
    + 이렇게 하는 이유는 잦은 정보공개 수정으로 인하여 쪽지를 보낸 후 받지 않는 경우를 막기 위해서 입니다. +
    + +
  • + + - - - - +
  • + + +
  • - - - - -
    기타 개인설정
    - - 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    - gif만 가능하며 용량 바이트 이하만 등록됩니다. -
    - - - 회원아이콘 - - - -
    - > - 정보 메일을 받겠습니다. -
    - > +
  • + + + > 휴대폰 문자메세지를 받겠습니다. -
  • - - 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. - - - > - 다른분들이 나의 정보를 볼 수 있도록 합니다. -
    정보공개 - - 정보공개는 수정후 일 이내, 까지는 변경이 안됩니다.
    - 이렇게 하는 이유는 잦은 정보공개 수정으로 인하여 쪽지를 보낸 후 받지 않는 경우를 막기 위해서 입니다. -
    - -
    자동등록방지
    +
  • + 자동등록방지 + +
  • +
    -
    - +
    취소 +
    @@ -288,10 +298,6 @@ add_stylesheet('', $cert_url = G5_KCPCERT_URL.'/kcpcert_form.php'; $cert_type = 'kcp-hp'; break; - case 'lg': - $cert_url = G5_LGXPAY_URL.'/AuthOnlyReq.php'; - $cert_type = 'lg-hp'; - break; default: echo 'alert("기본환경설정에서 휴대폰 본인확인 설정을 해주십시오");'; echo 'return false;'; @@ -410,16 +416,26 @@ add_stylesheet('', } - if (typeof f.mb_icon != 'undefined') { + if (typeof f.mb_icon != "undefined") { if (f.mb_icon.value) { - if (!f.mb_icon.value.toLowerCase().match(/.(gif)$/i)) { - alert('회원아이콘이 gif 파일이 아닙니다.'); + if (!f.mb_icon.value.toLowerCase().match(/.(gif|jpe?g|png)$/i)) { + alert("회원아이콘이 이미지 파일이 아닙니다."); f.mb_icon.focus(); return false; } } } + if (typeof f.mb_img != "undefined") { + if (f.mb_img.value) { + if (!f.mb_img.value.toLowerCase().match(/.(gif|jpe?g|png)$/i)) { + alert("회원이미지가 이미지 파일이 아닙니다."); + f.mb_img.focus(); + return false; + } + } + } + if (typeof(f.mb_recommend) != 'undefined' && f.mb_recommend.value) { if (f.mb_id.value == f.mb_recommend.value) { alert('본인을 추천할 수 없습니다.'); diff --git a/theme/basic/mobile/skin/member/basic/register_result.skin.php b/theme/basic/mobile/skin/member/basic/register_result.skin.php index 44ebe9dd4..fb677f0c1 100644 --- a/theme/basic/mobile/skin/member/basic/register_result.skin.php +++ b/theme/basic/mobile/skin/member/basic/register_result.skin.php @@ -4,41 +4,42 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 // add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨 add_stylesheet('', 0); ?> +
    +

    회원가입이 완료되었습니다.

    +
    +

    + 님의 회원가입을 진심으로 축하합니다.
    +

    -
    + +

    + 회원 가입 시 입력하신 이메일 주소로 인증메일이 발송되었습니다.
    + 발송된 인증메일을 확인하신 후 인증처리를 하시면 사이트를 원활하게 이용하실 수 있습니다. +

    +
    + 아이디 +
    + 이메일 주소 + +
    +

    + 이메일 주소를 잘못 입력하셨다면, 사이트 관리자에게 문의해주시기 바랍니다. +

    + -

    - 님의 회원가입을 진심으로 축하합니다.
    -

    +

    + 회원님의 비밀번호는 아무도 알 수 없는 암호화 코드로 저장되므로 안심하셔도 좋습니다.
    + 아이디, 비밀번호 분실시에는 회원가입시 입력하신 이메일 주소를 이용하여 찾을 수 있습니다. +

    - -

    - 회원 가입 시 입력하신 이메일 주소로 인증메일이 발송되었습니다.
    - 발송된 인증메일을 확인하신 후 인증처리를 하시면 사이트를 원활하게 이용하실 수 있습니다. -

    -
    - 아이디 -
    - 이메일 주소 - +

    + 회원 탈퇴는 언제든지 가능하며 일정기간이 지난 후, 회원님의 정보는 삭제하고 있습니다.
    + 감사합니다. +

    -

    - 이메일 주소를 잘못 입력하셨다면, 사이트 관리자에게 문의해주시기 바랍니다. -

    - - -

    - 회원님의 비밀번호는 아무도 알 수 없는 암호화 코드로 저장되므로 안심하셔도 좋습니다.
    - 아이디, 비밀번호 분실시에는 회원가입시 입력하신 이메일 주소를 이용하여 찾을 수 있습니다. -

    - -

    - 회원 탈퇴는 언제든지 가능하며 일정기간이 지난 후, 회원님의 정보는 삭제하고 있습니다.
    - 감사합니다. -

    diff --git a/theme/basic/mobile/skin/member/basic/scrap.skin.php b/theme/basic/mobile/skin/member/basic/scrap.skin.php index ccb43bac5..6ba0a162c 100644 --- a/theme/basic/mobile/skin/member/basic/scrap.skin.php +++ b/theme/basic/mobile/skin/member/basic/scrap.skin.php @@ -5,13 +5,13 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 add_stylesheet('', 0); ?> -
    +

    -
      +
      • - + 삭제
      • @@ -22,6 +22,6 @@ add_stylesheet('',
        - +
    diff --git a/theme/basic/mobile/skin/member/basic/scrap_popin.skin.php b/theme/basic/mobile/skin/member/basic/scrap_popin.skin.php index 04dfd5fd3..1b3fc792b 100644 --- a/theme/basic/mobile/skin/member/basic/scrap_popin.skin.php +++ b/theme/basic/mobile/skin/member/basic/scrap_popin.skin.php @@ -5,35 +5,34 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 add_stylesheet('', 0); ?> -
    +

    스크랩하기

    + +
    +

    제목 확인 및 댓글 쓰기

    +
      +
    • + 제목 + +
    • +
    • + + +
    • +
    + +

    + 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. +

    -
    - - - - - - - - - - - - -
    제목 확인 및 댓글 쓰기
    제목
    +
    + +
    -

    - 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. -

    - -
    - -
    \ No newline at end of file diff --git a/theme/basic/mobile/skin/member/basic/style.css b/theme/basic/mobile/skin/member/basic/style.css index 60bd23600..7d2123881 100644 --- a/theme/basic/mobile/skin/member/basic/style.css +++ b/theme/basic/mobile/skin/member/basic/style.css @@ -1,7 +1,9 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* ### 기본 스타일 커스터마이징 시작 ### */ +.mbskin{text-align:center;padding:10px} +.mbskin h1{font-size:1.75em;margin:40px 0 25px} +.mbskin p {padding-bottom:20px;border-bottom:1px solid #c8c8c8} +.mbskin p strong{color:#4162ff;padding-bottom:5px;display:block;font-size:1.083em} /* 버튼 */ .mbskin a.btn01 {} @@ -73,123 +75,168 @@ /* ### 기본 스타일 커스터마이징 끝 ### */ /* 회원가입 약관 */ -#fregister section {padding:15px;border-bottom:1px solid #eee;background:#fafafa} -#fregister h2 {margin:0 0 15px;text-align:center} -#fregister textarea {display:block;margin-bottom:10px;padding:5px;width:99%;height:150px;border:1px solid #cfded8;background:#f7f7f7} -.fregister_agree {padding:10px 0 0;text-align:right} +#fregister section {background:#fff;margin:10px 0;border:1px solid #dbdbdb; +-webkit-box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2); +-moz-box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2); +box-shadow: 2px 2px 3px 0px rgba(0,0,0,0.2);} +#fregister .chk_all{text-align:left} +#fregister h2 {text-align:left;border-bottom:1px solid #dbdbdb;padding:10px 15px;line-height:1.7em;font-size:1.167em} +#fregister textarea {display:block;padding:10px;width:100%;border:0;background:#fff;height:180px;line-height:1.5em;color:#555} +.fregister_agree {border-top:1px solid #dbdbdb;padding:10px 15px;line-height:1.7em;text-align:left;font-size:1.083em} .fregister_agree label {display:inline-block;margin-right:5px} -#fregister p {color:#e8180c;text-align:center} +#fregister p {border:0;padding:0 0 5px;} #fregister .btn_confirm {margin:15px 0} -#fregister_private .tbl_head01 {margin:0} -#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%} -#fregister_private .tbl_head01 td {border:1px solid #e9e9e9;background:#fff} +#fregister_private .tbl_head01 {padding:20px;margin:0} #fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden;top:0;color:#fff} /* 회원가입 입력 */ #fregisterform #reg_mb_email, #fregisterform .frm_address {width:100%} - #fregisterform textarea {width:100%;height:50px} - #fregisterform #msg_certify {margin:5px 0 0;padding:5px;border:1px solid #dbecff;background:#eaf4ff;text-align:center} - #fregisterform .frm_address {margin:5px 0 0} #fregisterform #mb_addr3 {display:block;margin:5px 0 0} #fregisterform #mb_addr_jibeon {display:block;margin:5px 0 0} +#fregisterform .form_01{margin-bottom: 30px} +#fregisterform .form_01 h2{font-size:1.167em;margin:0 0 5px} +#fregisterform .frm_label{display:block;font-size:1.083em;margin:15px 0 5px;color:#555} +#fregisterform .btn_frmline {height:40px;padding:0 10px} +#fregisterform .rgs_name_li button{margin:5px 0 0 } +#fregisterform .reg_mb_img_file img{max-width:100%;height:auto} /* 회원가입 완료 */ -#reg_result {padding:40px 10px 0} +#reg_result {padding:20px 10px 10px} #reg_result #result_email {margin:20px 0;padding:10px 50px;border-top:1px solid #eee;border-bottom:1px solid #eee;background:#fff;line-height:2em} #reg_result #result_email span {display:inline-block;width:150px} #reg_result #result_email strong {color:#e8180c;font-size:1.2em} -#reg_result p {line-height:1.8em} -#reg_result .btn_confirm {margin:50px 0} +#reg_result h2{text-align:center;font-size:1.25em;margin:0 0 10px} +#reg_result h2 strong{color:#ed6478} +#reg_result p {line-height:1.7em} +#reg_result .btn_confirm {margin:20px 0 30px} +#reg_result .reg_result_wr{background:#fff;padding:10px 20px} +#reg_result .reg_cong{margin:10px 0;font-size:1.083em;font-weight:bold} +#reg_result .reg_cong strong{color:#3497d9} +#reg_result .btn_confirm a{display:inline-block;padding:0 20px;height:40px;line-height:38px;border:1px solid #ed6478;color:#ed6478;border-radius:3px;font-weight:bold} /* 아이디/비밀번호 찾기 */ -#find_info #info_fs {margin:0 20px 10px} -#find_info #info_fs p {margin:0 0 10px;line-height:1.8em} +/*#find_info #info_fs {margin:0 20px 10px}*/ +#find_info #info_fs p {margin:0 0 10px;line-height:1.5em;font-size:0.92em;color:#4162ff} #find_info #info_fs #mb_email {width:100%} -#find_info #captcha {margin:0 20px;padding:0 0 10px} -#find_info #captcha input {margin-left:5px} +#find_info #captcha{margin:5px 0 } /* 로그인 */ -#mb_login {margin:20px 0} -#mb_login h1 {margin:0 0 15px;padding:0 10px;font-size:1.3em} +#mb_login {margin:40px auto 10px;;max-width:500px;padding:20px;} +#mb_login h1 {font-size:2em;text-align:center;margin:0 0 20px} #mb_login h2 {margin:0} #mb_login p {padding:10px 0;line-height:1.5em} -#mb_login #login_frm {position:relative;padding:0 5px;font-size:1em} -#mb_login #login_frm div {padding:10px 0 0;text-align:right} -#mb_login .frm_input {display:block;margin-bottom:5px;padding:0;width:81%;height:1.8em;line-height:1.8em} -#mb_login .btn_submit {position:absolute;top:0;right:5px;padding:0 !important;width:18%;height:4.3em !important;text-align:center} -#mb_login section {margin:30px 0;padding:15px 10px;border:1px solid #cfded8;background:#f7f7f7} -#mb_login section div {text-align:right} +#mb_login #login_frm {position:relative} +#mb_login #login_frm div {padding:10px 0 ;text-align:right} +#mb_login .frm_input {width:100%;margin:5px 0} +#mb_login .btn_submit {width:100%;border-radius:3px;height:40px;margin:5px 0;font-size:1.083em;font-weight:bold} +#mb_login .mb_login_join{border-top:1px solid #ddd;margin:20px 0 0 ;padding:10px 0} +#mb_login .mb_login_join:after {display:block;visibility:hidden;clear:both;content:""} +#mb_login .mb_login_join h2{position:absolute;font-size:0;line-height:0;overflow:hidden} +#mb_login .mb_login_join a{display:block;float:left;width:50%;} +#login_password_lost{border-right:1px solid #cdcdcd;} +#flogin{background:#fff;padding:20px;margin:20px 0;border-bottom:1px solid #ddd;} + +#mb_login_notmb{background:#fff;border-bottom:1px solid #ccc;padding:20px;} +#mb_login_notmb h2{font-size:1.25em;padding:10px;background:#f3f3f3} +#mb_login_notmb p{border:0;padding:0;margin:10px;color:#} +#guest_privacy p{border:1px solid #ddd;background:#fff;color:#666;min-height:20px;height:200px;padding:10px;text-align:left;overflow-y:auto;margin:10px 0} +#mb_login_notmb .btn_submit{width:100%;display:block;height:40px;line-height:40px} + +#mb_login_od_wr{background:#fff;border-bottom:1px solid #ccc;padding:20px;} +#mb_login_od_wr p{border:0;text-align:left;} +#mb_login_od_wr p strong{display:inline} +#mb_login_odinfo{margin:10px 0 0 ;background:#f3f3f3;padding:10px} +#mb_login_odinfo h2{font-size:1.167em} /* 쪽지 */ -#memo_view_contents {margin:0 auto 20px;width:90%} -#memo_view_contents h1 {position:absolute;font-size:0;line-height:0;overflow:hidden} -#memo_view_ul {margin:0;padding:0 0 10px;border-bottom:1px solid #eee;list-style:none} -.memo_view_li {position:relative;padding:5px 0} -.memo_view_subj {display:inline-block;width:65px} +#memo_view_contents {} +#memo_view_contents h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#memo_view_ul {margin:0 0 3px;background:#fff;padding:5px 10px;border-radius:3px; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} +.memo_view_li {position:relative;padding:2px 0} +.memo_view_subj {display:inline-block;width:60px;font-size:0.92em;color:#777} #memo_view_ul a {} -#memo_view p {padding:10px 0;min-height:150px;height:auto !important;height:150px;line-height:1.8em} +#memo_view p {padding:10px 15px;border-radius:3px;;min-height:150px;height:auto !important;height:150px;line-height:1.8em;background:#fff; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} -#memo_list_ul {margin:0 20px;padding:0;border-top:1px solid #e9e9e9;list-style:none} -#memo_list_ul li {position:relative;padding:10px 0;border-bottom:1px solid #e9e9e9} -#memo_list_ul .memo_link {} -#memo_list_ul .memo_send {display:block;margin-top:4px} -#memo_list_ul .memo_send a{color:#777} -#memo_list_ul .memo_read {font-size:0.95em;color:#666} -#memo_list_ul .memo_del {position:absolute;top:10px;right:0} +#memo_list_ul {} +#memo_list_ul li {position:relative;background:#fff;margin:10px 0;border-radius:3px;padding:10px 15px; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} -#memo_write #me_recv_mb_id {width:98%} -#memo_write textarea {width:99%;height:100px} +#memo_list_ul .memo_link {display:block;font-weight:bold;font-size:1.083em;margin:0 0 5px} +#memo_list_ul .memo_date{font-size:0.92em;color:#777;font-style:italic} +#memo_list_ul .memo_del{display:block;position:absolute;top:0;right:0;width:40px;height:40px;background:url(./img/btn_del.gif) no-repeat 50% 50%; text-indent:-9999px;overflow:hidden} + +#memo_write #me_recv_mb_id {width:100%} +#memo_write textarea {width:100%;height:100px} +#memo_write .win_btn{margin:10px;} /* 스크랩 */ -#scrap_ul {margin:0 20px;padding:0;border-top:1px solid #e9e9e9;list-style:none} -#scrap_ul li {position:relative;padding:10px 35px 10px 0;border-bottom:1px solid #e9e9e9} -#scrap_ul .scrap_board {display:inline-block;margin:0 10px 0 0;font-weight:bold} -#scrap_ul .scrap_del {position:absolute;top:10px;right:0} - -#scrap_do table {margin:0 0 10px;width:100%} -#scrap_do textarea {width:99%;height:100px} +#scrap_ul li{position:relative;} +#scrap_ul .scrap_board {display:block;color:#4162ff;margin:0 0 5px} +#scrap_ul .scrap_del {display:block;position:absolute;top:0;right:0;width:40px;height:40px;background:url(./img/btn_del.gif) no-repeat 50% 50%; text-indent:-9999px;overflow:hidden} +#scrap_ul .scrap_link{font-weight:bold;font-size:1.083em;} +.scrap_tit{font-weight:bold;border-bottom:1px solid #d7d7d7;padding:0 0 10px;font-size:1.167em} +#scrap_do #wr_content{margin-top:5px} +#scrap_do label{color:#666} /* 포인트 */ -#point_ul {margin:0 20px;padding:0;border-top:1px solid #e9e9e9;list-style:none} -#point_ul li {position:relative;padding:10px 0;border-bottom:1px solid #e9e9e9} -#point_ul .point_wrap01 {position:relative;padding:0 0 0 90px} -#point_ul .point_wrap02 {margin:7px 0 0;text-align:right} -#point_ul .point_date {position:absolute;top:0;left:0} +#point_ul {;padding:0;border-top:1px solid #e9e9e9;list-style:none} +#point_ul li {position:relative;} +#point_ul li:after {display:block;visibility:hidden;clear:both;content:""} +#point_ul .point_wrap01 {float:left} +#point_ul .point_wrap02 {float:right;text-align:right} +#point_ul .point_log{display:block;font-weight:bold;margin:0 0 5px;font-size:1.083em} +#point_ul .point_inout{display:block;font-weight:bold;margin:0 0 5px;color:#4162ff;font-size:1.083em} +#point_ul .point_date{font-style:italic} -#point_sum {margin:0 20px} -#point_sum .sum_row {margin:0 0 1px;background:#f2f5f9} -#point_sum .sum_row:after {display:block;visibility:hidden;clear:both;content:''} +#point_sum{margin:10px 0 20px} +#point_sum:after {display:block;visibility:hidden;clear:both;content:''} +#point_sum .sum_row {float:left;width:33.333%;text-align:center;background:#939db8;color:#fff;} +#point_sum .sum_row:nth-child(even){background:#8490af} #point_sum .sum_tit, #point_sum .sum_val {display:block;margin:0 0 1px;padding:10px} -#point_sum .sum_tit {clear:both;float:left;width:100px} -#point_sum .sum_val {float:right} +#point_sum .sum_tit {} +#point_sum .sum_val {} /* 회원 비밀번호 확인 */ #mb_confirm {margin:30px 0} #mb_confirm h1 {margin:0 0 15px;padding:0 10px;font-size:1.3em} #mb_confirm p {padding:15px 10px;border-bottom:1px solid #cfded8;border-bottom:0;background:#fff} #mb_confirm p strong {display:block} -#mb_confirm fieldset {position:relative;margin:0 0 5px;padding:20px 10px;border-bottom:1px solid #cfded8;background:#f7f7f7} -#mb_confirm_pw {display:block;margin-top:10px;padding:0;width:88%;line-height:1.8em !important} -#mb_confirm .btn_submit {position:absolute;bottom:20px;right:10px;width:10%;height:1.9em !important;line-height:1.9em} +#mb_confirm fieldset {position:relative;margin:20px 0;text-align:left;color:#555} +#mb_confirm_id{font-weight:bold;display:block;font-size:1.083em;margin:5px 0} +#mb_confirm_pw {display:block;margin-top:10px;width:100%} +#mb_confirm .btn_submit {width:100%;height:40px;border-radius:3px;margin:10px 0} /* 비밀글 비밀번호 확인 */ -#pw_confirm {margin:30px 0} -#pw_confirm h1 {margin:0 0 15px;padding:0 10px;font-size:1.3em} -#pw_confirm p {padding:15px 10px;border-bottom:1px solid #cfded8;border-bottom:0;background:#fff} -#pw_confirm p strong {display:block} -#pw_confirm fieldset {position:relative;margin:0 0 5px;padding:5px 5px 10px;border-bottom:1px solid #cfded8;background:#f7f7f7} -#pw_wr_password {display:block;margin-top:10px;padding:0;width:88%;line-height:1.8em !important} -#pw_confirm .btn_submit {position:absolute;bottom:10px;right:5px;width:10%;height:1.9em !important;line-height:1.9em} +#pw_confirm fieldset {position:relative;margin:0 0 5px;padding:15px 0;border-top:1px solid #fffefe} +#pw_wr_password {width:100%} +#pw_confirm .btn_submit {margin:5px 0;width:100%;border-radius:3px;height:45px;font-weight:bold;font-size:1.083em} /* 폼메일 */ -#formmail #subject {width:98%} -#formmail textarea {width:99%;height:100px} +#formmail #subject {width:100%} +#formmail textarea {width:100%;height:100px} +#formmail .frm_file{padding-left:50px;} +#formmail .file_wr{border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;height:40px;} +#formmail .lb_icon{position:absolute;top:0px;left:0px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;overflow:hidden;text-indent:-999px;background:url(./img/icon_file.gif) no-repeat 50% 50% #eee} /* 자기소개 */ -#profile table {margin-bottom:0} -#profile section {padding:10px 20px} +#profile section {margin:10px; } #profile h2 {margin:0} -#profile .sv_wrap a {margin:0 0 5px;padding:0;font-weight:bold;line-height:10px} \ No newline at end of file +#profile .sv_wrap a {color:#fdff2f} +#profile table{width:100%;border-collapse:collapse} +#profile table th{background:#fff;padding:10px;width:90px;text-align:left;border-bottom:1px solid #eee} +#profile table td{background:#fff;padding:10px;border-bottom:1px solid #eee} +#profile p{background:#fff;padding:10px;margin:10px 0; +-webkit-box-shadow: 0 0 5px rgba(50,50,50,0.2); +-moz-box-shadow: 0 0 5px rgba(50,50,50,0.2); +box-shadow: 0 1px 5px rgba(50,50,50,0.2);} \ No newline at end of file diff --git a/theme/basic/mobile/skin/new/basic/new.skin.php b/theme/basic/mobile/skin/new/basic/new.skin.php index 9055d2b52..e7263f92f 100644 --- a/theme/basic/mobile/skin/new/basic/new.skin.php +++ b/theme/basic/mobile/skin/new/basic/new.skin.php @@ -16,8 +16,8 @@ add_stylesheet('', 0);
    + + +
    - - - - - -
    -

    연락처정보

    -
    - -
    이메일
    -
    - - -
    휴대폰
    -
    - -
    -
    - - +
    -
    -

    본문

    - - \n"; - - for ($i=0; $i<$view['img_count']; $i++) { - //echo $view['img_file'][$i]; - echo get_view_thumbnail($view['img_file'][$i], $qaconfig['qa_image_width']); - } - - echo "
    \n"; - } - ?> - - -
    - - - - - - - - ', 0);

    연관질문

    -
    - - - - - - - - - - +
    + +
      -
    - - - - - - - -
    분류제목상태등록일
    - - - -
    + for($i=0; $i<$view['rel_count']; $i++) { + ?> +
  • +
    + + + + + +
    +
    + + +
    +
  • + +
    - -
    - -
    - + diff --git a/theme/basic/mobile/skin/qa/basic/write.skin.php b/theme/basic/mobile/skin/qa/basic/write.skin.php index adbcbdfbb..3d19ca931 100644 --- a/theme/basic/mobile/skin/qa/basic/write.skin.php +++ b/theme/basic/mobile/skin/qa/basic/write.skin.php @@ -27,92 +27,82 @@ add_stylesheet('', 0); echo $option_hidden; ?> -
    - - - - - - - - + + - - - - - - + +
  • + 옵션 + +
  • + - - - - - - + + - - - - - - + + - - - - +
  • + + +
  • - - - - +
  • + +
    + +
    +
  • - - - - +
  • +
    + 파일 #1 + + + + +
    +
  • - - - - +
  • +
    + 파일 #2 + + + + +
    +
  • - -
    +
    +
      + +
    • + -
    옵션
    - class="frm_input email" maxlength="100"> + +
  • + + class="frm_input full_input email" maxlength="100" placeholder="이메일"> > -
  • - class="frm_input" size="30"> + +
  • + + class="frm_input full_input" size="30" placeholder="휴대폰"> > 답변등록 SMS알림 수신 -
  • - -
    - -
    파일 #1 - - - - -
    파일 #2 - - - - -
    +
    -
    - - 목록 +
    + 목록 +
    diff --git a/theme/basic/mobile/skin/search/basic/search.skin.php b/theme/basic/mobile/skin/search/basic/search.skin.php index c1ae64ec8..d4229ec77 100644 --- a/theme/basic/mobile/skin/search/basic/search.skin.php +++ b/theme/basic/mobile/skin/search/basic/search.skin.php @@ -9,7 +9,7 @@ add_stylesheet('',
    상세검색 -
    +
    @@ -21,11 +21,10 @@ add_stylesheet('', -
    -
    + - - + + diff --git a/theme/basic/screenshot.png b/theme/basic/screenshot.png index 423a3993e..249f4c134 100644 Binary files a/theme/basic/screenshot.png and b/theme/basic/screenshot.png differ diff --git a/theme/basic/skin/board/basic/img/btn_next2.gif b/theme/basic/skin/board/basic/img/btn_next2.gif new file mode 100644 index 000000000..9ec94650a Binary files /dev/null and b/theme/basic/skin/board/basic/img/btn_next2.gif differ diff --git a/theme/basic/skin/board/basic/img/btn_prev2.gif b/theme/basic/skin/board/basic/img/btn_prev2.gif new file mode 100644 index 000000000..827e7be43 Binary files /dev/null and b/theme/basic/skin/board/basic/img/btn_prev2.gif differ diff --git a/theme/basic/skin/board/basic/img/close_btn.png b/theme/basic/skin/board/basic/img/close_btn.png new file mode 100644 index 000000000..50e9f26ef Binary files /dev/null and b/theme/basic/skin/board/basic/img/close_btn.png differ diff --git a/theme/basic/skin/board/basic/img/cmt_btn.png b/theme/basic/skin/board/basic/img/cmt_btn.png new file mode 100644 index 000000000..202f1ff47 Binary files /dev/null and b/theme/basic/skin/board/basic/img/cmt_btn.png differ diff --git a/theme/basic/skin/board/basic/img/icon_bad.png b/theme/basic/skin/board/basic/img/icon_bad.png new file mode 100644 index 000000000..e568b1d83 Binary files /dev/null and b/theme/basic/skin/board/basic/img/icon_bad.png differ diff --git a/theme/basic/skin/board/basic/img/icon_comment.png b/theme/basic/skin/board/basic/img/icon_comment.png new file mode 100644 index 000000000..c7e3acbf9 Binary files /dev/null and b/theme/basic/skin/board/basic/img/icon_comment.png differ diff --git a/theme/basic/skin/board/basic/img/icon_file.gif b/theme/basic/skin/board/basic/img/icon_file.gif index cca47f566..244af004d 100644 Binary files a/theme/basic/skin/board/basic/img/icon_file.gif and b/theme/basic/skin/board/basic/img/icon_file.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_good.png b/theme/basic/skin/board/basic/img/icon_good.png new file mode 100644 index 000000000..69841a134 Binary files /dev/null and b/theme/basic/skin/board/basic/img/icon_good.png differ diff --git a/theme/basic/skin/board/basic/img/icon_hot.gif b/theme/basic/skin/board/basic/img/icon_hot.gif index c95b839ae..2936de662 100644 Binary files a/theme/basic/skin/board/basic/img/icon_hot.gif and b/theme/basic/skin/board/basic/img/icon_hot.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_img.gif b/theme/basic/skin/board/basic/img/icon_img.gif index fefa10d4a..3ba495d05 100644 Binary files a/theme/basic/skin/board/basic/img/icon_img.gif and b/theme/basic/skin/board/basic/img/icon_img.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_link.gif b/theme/basic/skin/board/basic/img/icon_link.gif index 0f3cb1ac6..e9cb9559c 100644 Binary files a/theme/basic/skin/board/basic/img/icon_link.gif and b/theme/basic/skin/board/basic/img/icon_link.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_lock.png b/theme/basic/skin/board/basic/img/icon_lock.png new file mode 100644 index 000000000..2a083a51d Binary files /dev/null and b/theme/basic/skin/board/basic/img/icon_lock.png differ diff --git a/theme/basic/skin/board/basic/img/icon_mobile.gif b/theme/basic/skin/board/basic/img/icon_mobile.gif index ad934d23c..43189ffae 100644 Binary files a/theme/basic/skin/board/basic/img/icon_mobile.gif and b/theme/basic/skin/board/basic/img/icon_mobile.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_new.gif b/theme/basic/skin/board/basic/img/icon_new.gif index 45aa6d7ed..73fa06a8f 100644 Binary files a/theme/basic/skin/board/basic/img/icon_new.gif and b/theme/basic/skin/board/basic/img/icon_new.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_reply.gif b/theme/basic/skin/board/basic/img/icon_reply.gif index 91c135977..7fe2c6558 100644 Binary files a/theme/basic/skin/board/basic/img/icon_reply.gif and b/theme/basic/skin/board/basic/img/icon_reply.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_secret.gif b/theme/basic/skin/board/basic/img/icon_secret.gif index c04899f14..7be670092 100644 Binary files a/theme/basic/skin/board/basic/img/icon_secret.gif and b/theme/basic/skin/board/basic/img/icon_secret.gif differ diff --git a/theme/basic/skin/board/basic/img/icon_share.png b/theme/basic/skin/board/basic/img/icon_share.png new file mode 100644 index 000000000..6d64f625a Binary files /dev/null and b/theme/basic/skin/board/basic/img/icon_share.png differ diff --git a/theme/basic/skin/board/basic/img/icon_view.png b/theme/basic/skin/board/basic/img/icon_view.png new file mode 100644 index 000000000..ea76f5442 Binary files /dev/null and b/theme/basic/skin/board/basic/img/icon_view.png differ diff --git a/theme/basic/skin/board/basic/img/sch_bg.png b/theme/basic/skin/board/basic/img/sch_bg.png new file mode 100644 index 000000000..729178d8e Binary files /dev/null and b/theme/basic/skin/board/basic/img/sch_bg.png differ diff --git a/theme/basic/skin/board/basic/img/sch_btn.png b/theme/basic/skin/board/basic/img/sch_btn.png new file mode 100644 index 000000000..94f98db8f Binary files /dev/null and b/theme/basic/skin/board/basic/img/sch_btn.png differ diff --git a/theme/basic/skin/board/basic/list.skin.php b/theme/basic/skin/board/basic/list.skin.php index d995a8555..abde78f5d 100644 --- a/theme/basic/skin/board/basic/list.skin.php +++ b/theme/basic/skin/board/basic/list.skin.php @@ -12,11 +12,27 @@ if ($is_nogood) $colspan++; add_stylesheet('', 0); ?> -

    목록

    -
    + + +
    +
    + Total + 페이지 +
    + + + + +
    + +
    @@ -161,33 +188,11 @@ add_stylesheet('', 0 + + - -
    - 게시물 검색 - -
    - - - - - - - - -
    -
    - -
    -

    +

    + + + + -

    + ?> +

    페이지 정보

    - 작성자 - 작성일 - 조회 - 댓글 + 작성자 + 댓글 + 조회 + 작성일 +
    - - - - -
    -

    첨부파일

    - -
    - - - - - - - - - - -
    - - - - - - - -
    - -

    본문

    @@ -154,19 +59,19 @@ add_stylesheet('', 0

    - - + + +
    - 스크랩 - 추천 + 추천 - 비추천 + 비추천 @@ -175,30 +80,128 @@ add_stylesheet('', 0 if($board['bo_use_good'] || $board['bo_use_nogood']) { ?>
    - 추천 - 비추천 + 추천 + 비추천
    - +
    +
    + 스크랩 + + +
    + + $cnt = 0; + if ($view['file']['count']) { + for ($i=0; $i + + + +
    +

    첨부파일

    +
      + +
    • + + + + + () + 회 다운로드 | DATE : +
    • + +
    +
    + + + + + + + + + + +
    + + + + + + + +
      +
    • 이전글
    • +
    • 다음글
    • +
    + + +
    + - -
    - -
    -
    @@ -253,6 +256,19 @@ $(function() { // 이미지 리사이즈 $("#bo_v_atc").viewimageresize(); + + //sns공유 + $(".btn_share").click(function(){ + $("#bo_v_sns").fadeIn(); + + }); + + $(document).mouseup(function (e) { + var container = $("#bo_v_sns"); + if (!container.is(e.target) && container.has(e.target).length === 0){ + container.css("display","none"); + } + }); }); function excute_good(href, $el, $tx) diff --git a/theme/basic/skin/board/basic/view_comment.skin.php b/theme/basic/skin/board/basic/view_comment.skin.php index 94cd090fa..a372ff01f 100644 --- a/theme/basic/skin/board/basic/view_comment.skin.php +++ b/theme/basic/skin/board/basic/view_comment.skin.php @@ -7,7 +7,7 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 var char_min = parseInt(); // 최소 var char_max = parseInt(); // 최대 - +

    댓글목록

    @@ -15,8 +15,7 @@ var char_max = parseInt(); // 최대 $cmt_amt = count($list); for ($i=0; $i<$cmt_amt; $i++) { $comment_id = $list[$i]['wr_id']; - $cmt_depth = ""; // 댓글단계 - $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 20; + $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 50; $comment = $list[$i]['content']; /* if (strstr($list[$i]['wr_option'], "secret")) { @@ -29,54 +28,52 @@ var char_max = parseInt(); // 최대
    style="margin-left:px;border-top-color:#e0e0e0">
    -

    님의 댓글

    +

    님의 댓글의 댓글

    - 댓글의 댓글 - 아이피 - + 아이피 + () - 작성일 - + 작성일 +
    -

    - 비밀글 - -

    +
    +

    + 비밀글 + +

    + "> - + if($w == 'cu') { + $sql = " select wr_id, wr_content, mb_id from $write_table where wr_id = '$c_id' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + if (!($is_admin || ($member['mb_id'] == $cmt['mb_id'] && $cmt['mb_id']))) + $cmt['wr_content'] = ''; + $c_wr_content = $cmt['wr_content']; + } + + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w'; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w'; + ?> + + +
    + + " id="secret_comment_"> - - -

    등록된 댓글이 없습니다.

    @@ -89,9 +86,9 @@ var char_max = parseInt(); // 최대 $w = 'c'; ?> -
    @@ -155,34 +193,10 @@ add_stylesheet('', 0 + + - - -
    - 게시물 검색 - -
    - - - - - - - - -
    -
    - - -
    -

    +

    + + + + -

    + ?> +

    페이지 정보

    - 작성자 - 작성일 - 조회 - 댓글 + 작성자 + 댓글 + 조회 + 작성일 +
    - - - - -
    -

    첨부파일

    - -
    - - - - - - - - - - -
    - - - - - - - -
    - -

    본문

    @@ -154,19 +59,19 @@ add_stylesheet('', 0

    - - + + +
    - 스크랩 - 추천 + 추천 - 비추천 + 비추천 @@ -175,30 +80,128 @@ add_stylesheet('', 0 if($board['bo_use_good'] || $board['bo_use_nogood']) { ?>
    - 추천 - 비추천 + 추천 + 비추천
    - +
    +
    + 스크랩 + + +
    + + $cnt = 0; + if ($view['file']['count']) { + for ($i=0; $i + + + +
    +

    첨부파일

    +
      + +
    • + + + + + () + 회 다운로드 | DATE : +
    • + +
    +
    + + + + + + + + + + +
    + + + + + + + +
      +
    • 이전글
    • +
    • 다음글
    • +
    + + +
    + - -
    - -
    -
    @@ -253,6 +256,19 @@ $(function() { // 이미지 리사이즈 $("#bo_v_atc").viewimageresize(); + + //sns공유 + $(".btn_share").click(function(){ + $("#bo_v_sns").fadeIn(); + + }); + + $(document).mouseup(function (e) { + var container = $("#bo_v_sns"); + if (!container.is(e.target) && container.has(e.target).length === 0){ + container.css("display","none"); + } + }); }); function excute_good(href, $el, $tx) diff --git a/theme/basic/skin/board/gallery/view_comment.skin.php b/theme/basic/skin/board/gallery/view_comment.skin.php index 14b0333d2..a372ff01f 100644 --- a/theme/basic/skin/board/gallery/view_comment.skin.php +++ b/theme/basic/skin/board/gallery/view_comment.skin.php @@ -7,7 +7,7 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 var char_min = parseInt(); // 최소 var char_max = parseInt(); // 최대 - +

    댓글목록

    @@ -15,8 +15,7 @@ var char_max = parseInt(); // 최대 $cmt_amt = count($list); for ($i=0; $i<$cmt_amt; $i++) { $comment_id = $list[$i]['wr_id']; - $cmt_depth = ""; // 댓글단계 - $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 20; + $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 50; $comment = $list[$i]['content']; /* if (strstr($list[$i]['wr_option'], "secret")) { @@ -29,54 +28,52 @@ var char_max = parseInt(); // 최대
    style="margin-left:px;border-top-color:#e0e0e0">
    -

    님의 댓글

    +

    님의 댓글의 댓글

    - 댓글의 댓글 - 아이피 - + 아이피 + () - 작성일 - + 작성일 +
    -

    - 비밀글 - -

    +
    +

    + 비밀글 + +

    + "> - + if($w == 'cu') { + $sql = " select wr_id, wr_content, mb_id from $write_table where wr_id = '$c_id' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + if (!($is_admin || ($member['mb_id'] == $cmt['mb_id'] && $cmt['mb_id']))) + $cmt['wr_content'] = ''; + $c_wr_content = $cmt['wr_content']; + } + + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w'; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w'; + ?> + + +
    + + " id="secret_comment_"> - - -

    등록된 댓글이 없습니다.

    @@ -89,9 +86,9 @@ var char_max = parseInt(); // 최대 $w = 'c'; ?> -
    '; + echo ''; ?> @@ -120,6 +125,7 @@ function faq_open(el) if($con.is(":visible")) { $con.slideUp(); + } else { $("#faq_con .con_inner:visible").css("display", "none"); diff --git a/theme/basic/skin/faq/basic/style.css b/theme/basic/skin/faq/basic/style.css index 35168de92..3c3ce0bbb 100644 --- a/theme/basic/skin/faq/basic/style.css +++ b/theme/basic/skin/faq/basic/style.css @@ -1,23 +1,27 @@ @charset "utf-8"; - +#bo_cate {margin:15px 0 10px} #bo_cate h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} -#bo_cate ul {margin-bottom:10px;padding-left:1px;zoom:1} +#bo_cate ul {;zoom:1} #bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} -#bo_cate li {float:left;margin-bottom:-1px} -#bo_cate a {display:block;position:relative;margin-left:-1px;padding:6px 0 5px;width:90px;border:1px solid #ddd;background:#f7f7f7;color:#888;text-align:center;letter-spacing:-0.1em;line-height:1.2em;cursor:pointer} -#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none} -#bo_cate #bo_cate_on {z-index:2;border:1px solid #565e60;background:#fff;color:#565e60;font-weight:bold} +#bo_cate li {display:inline-block;} +#bo_cate a {display:block;border:1px solid #dadada;background:#fff;margin:0 0 5px 0;line-height:30px;padding:0 10px;border-radius:3px} +#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none;background:#f3f3f3} +#bo_cate #bo_cate_on {z-index:2;border:1px solid #253dbe;color:#253dbe;font-weight:bold} #faq_wrap {margin:10px 0 30px} #faq_wrap h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} .faq_admin {text-align:right} #faq_wrap ol {margin:0;padding:0;list-style:none} -#faq_con {border:1px solid #e9e9e9;border-top:0} -#faq_con h3 a {display:block;padding:10px;border-top:1px solid #e9e9e9;background:#f2f5f9;text-decoration:none} -#faq_con .con_inner {display:none;padding:10px;line-height:1.8em} -#faq_con .con_closer {margin:10px 0 0;text-align:right} -#faq_con .closer_btn {margin:0;padding:0;border:0;background:transparent} -.faq_tolist {padding:0 10px;text-align:right} -.faq_img {text-align:center} +#faq_wrap li{border:1px solid #ddd;background:#fff;margin:5px 0;} +#faq_wrap li h3{min-height:50px;line-height:30px;padding:10px;padding-left:50px;position:relative} +#faq_wrap li h3 .tit_bg{display:inline-block;position:absolute;top:10px;left:10px;text-align:center;background:#333;color:#fff;border-radius:50%;width:30px;height:30px} +#faq_con .con_inner{display:none;border-top:1px solid #ddd;padding:15px;padding-left:50px;position:relative;background: #f7f7f7;} +#faq_con .con_inner .tit_bg{display:inline-block;position:absolute;top:10px;left:10px;text-align:center;background:#777;color:#fff;border-radius:50%;width:30px;line-height:30px;height:30px} +#faq_con .con_inner .closer_btn{height:25px;font-size:0.92em;display:inline-block;padding:0 5px;border-radius:5px;} +#faq_con .con_closer{text-align:right} -#faq_sch {text-align:center} \ No newline at end of file +#faq_sch {text-align:center;border:1px solid #ccc;background:#fff;;padding:30px;margin:10px 0} +#faq_sch form{display:inline-block;position:relative} +#faq_sch .sch_tit{font-size:20px;font-weight:bold;display:inline-block;margin-right:10px;vertical-align:middle} +#faq_sch .frm_input{border-color:#646982;border-radius:0;width:300px} +#faq_sch .btn_submit{padding:0 10px;height:40px;color:#000;font-size:1.083em;font-weight:bold;color:#fff;background:#253dbe;} diff --git a/theme/basic/skin/latest/basic/img/icon_file.gif b/theme/basic/skin/latest/basic/img/icon_file.gif index cca47f566..244af004d 100644 Binary files a/theme/basic/skin/latest/basic/img/icon_file.gif and b/theme/basic/skin/latest/basic/img/icon_file.gif differ diff --git a/theme/basic/skin/latest/basic/img/icon_hot.gif b/theme/basic/skin/latest/basic/img/icon_hot.gif index c95b839ae..2936de662 100644 Binary files a/theme/basic/skin/latest/basic/img/icon_hot.gif and b/theme/basic/skin/latest/basic/img/icon_hot.gif differ diff --git a/theme/basic/skin/latest/basic/img/icon_img.gif b/theme/basic/skin/latest/basic/img/icon_img.gif index fefa10d4a..3ba495d05 100644 Binary files a/theme/basic/skin/latest/basic/img/icon_img.gif and b/theme/basic/skin/latest/basic/img/icon_img.gif differ diff --git a/theme/basic/skin/latest/basic/img/icon_link.gif b/theme/basic/skin/latest/basic/img/icon_link.gif index 0f3cb1ac6..e9cb9559c 100644 Binary files a/theme/basic/skin/latest/basic/img/icon_link.gif and b/theme/basic/skin/latest/basic/img/icon_link.gif differ diff --git a/theme/basic/skin/latest/basic/img/icon_lock.png b/theme/basic/skin/latest/basic/img/icon_lock.png new file mode 100644 index 000000000..2a083a51d Binary files /dev/null and b/theme/basic/skin/latest/basic/img/icon_lock.png differ diff --git a/theme/basic/skin/latest/basic/img/icon_mobile.gif b/theme/basic/skin/latest/basic/img/icon_mobile.gif index ad934d23c..43189ffae 100644 Binary files a/theme/basic/skin/latest/basic/img/icon_mobile.gif and b/theme/basic/skin/latest/basic/img/icon_mobile.gif differ diff --git a/theme/basic/skin/latest/basic/img/icon_secret.gif b/theme/basic/skin/latest/basic/img/icon_secret.gif index c04899f14..7be670092 100644 Binary files a/theme/basic/skin/latest/basic/img/icon_secret.gif and b/theme/basic/skin/latest/basic/img/icon_secret.gif differ diff --git a/theme/basic/skin/latest/basic/img/icon_view.png b/theme/basic/skin/latest/basic/img/icon_view.png new file mode 100644 index 000000000..ea76f5442 Binary files /dev/null and b/theme/basic/skin/latest/basic/img/icon_view.png differ diff --git a/theme/basic/skin/latest/basic/img/more-btn.gif b/theme/basic/skin/latest/basic/img/more-btn.gif new file mode 100644 index 000000000..fa4c87331 Binary files /dev/null and b/theme/basic/skin/latest/basic/img/more-btn.gif differ diff --git a/theme/basic/skin/latest/basic/img/more_bg.gif b/theme/basic/skin/latest/basic/img/more_bg.gif new file mode 100644 index 000000000..19aab13a3 Binary files /dev/null and b/theme/basic/skin/latest/basic/img/more_bg.gif differ diff --git a/theme/basic/skin/latest/basic/latest.skin.php b/theme/basic/skin/latest/basic/latest.skin.php index 989a3ee40..cd7d11efd 100644 --- a/theme/basic/skin/latest/basic/latest.skin.php +++ b/theme/basic/skin/latest/basic/latest.skin.php @@ -5,40 +5,48 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 add_stylesheet('', 0); ?> - -
    - +
    +

    • "; + if ($list[$i]['icon_secret']) echo "비밀글 "; + + if ($list[$i]['icon_new']) echo "N새글"; + + if ($list[$i]['icon_hot']) echo "H인기글"; + + + echo " "; if ($list[$i]['is_notice']) echo "".$list[$i]['subject'].""; else echo $list[$i]['subject']; - if ($list[$i]['comment_cnt']) - echo $list[$i]['comment_cnt']; + echo ""; // if ($list[$i]['link']['count']) { echo "[{$list[$i]['link']['count']}]"; } // if ($list[$i]['file']['count']) { echo "<{$list[$i]['file']['count']}>"; } - if (isset($list[$i]['icon_new'])) echo " " . $list[$i]['icon_new']; - if (isset($list[$i]['icon_hot'])) echo " " . $list[$i]['icon_hot']; - if (isset($list[$i]['icon_file'])) echo " " . $list[$i]['icon_file']; - if (isset($list[$i]['icon_link'])) echo " " . $list[$i]['icon_link']; - if (isset($list[$i]['icon_secret'])) echo " " . $list[$i]['icon_secret']; - ?> + //echo $list[$i]['icon_reply']." "; + // if ($list[$i]['icon_file']) echo " " ; + //if ($list[$i]['icon_link']) echo " " ; + + if ($list[$i]['comment_cnt']) echo " + + ".$list[$i]['comment_cnt'].""; + + ?> + +
    • -
    • 게시물이 없습니다.
    • +
    • 게시물이 없습니다.
    - + 더보기 +
    - \ No newline at end of file diff --git a/theme/basic/skin/latest/basic/style.css b/theme/basic/skin/latest/basic/style.css index ab55517b1..8fb71ebde 100644 --- a/theme/basic/skin/latest/basic/style.css +++ b/theme/basic/skin/latest/basic/style.css @@ -1,11 +1,26 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* 새글 스킨 (latest) */ -.lt_pc {float:left;margin-left:20px} -.lt {position:relative;float:left;margin-bottom:20px;padding-bottom:10px;width:354px;height:150px;border-bottom:1px solid #e9e9e9} -.lt ul {margin:0 0 10px;padding:0;list-style:none} -.lt li {padding:3px 0} -.lt .lt_title {display:block;padding:10px 0 8px} -.lt .lt_more {position:absolute;top:10px;right:0} -.lt .cnt_cmt {display:inline-block;margin:0 0 0 3px;font-weight:bold} \ No newline at end of file + +.lat {position:relative;margin-bottom:20px;overflow:hidden;border: 1px solid #c6cacc;background:#fff} +.lat .lat_title {display:block;padding:0 20px;line-height:45px;font-size:1.083em;border-bottom:1px solid #e2e2e2;color:#253dbe;background:#fcfcfc} +.lat .lat_title a{color:#253dbe;display:inline-block;position:relative} +.lat .lat_title a:after{position:absolute;bottom:-1px;left:0;width:100%;height:2px;background:#253dbe;content:''} +.lat ul{padding:15px 20px} +.lat li {position:relative;line-height:18px;padding:3px 0;padding-right:50px;padding-left:10px;position:relative} +.lat li:before{position: absolute;top: 12px;left: 0px;width: 4px;height: 4px;background: #aaa;content: '';border-radius: 50%;} +.lat li a:hover{color:#a22121} +.lat li .fa-heart{color:#ff0000;} +.lat li .fa-lock{display: inline-block;line-height: 14px;width: 16px;font-size: 0.833em;color: #4f818c;background: #cbe3e8;text-align: center;border-radius: 2px;font-size: 12px;border:1px solid #a2c6ce} +.lat li .new_icon{display:inline-block;width: 16px;line-height:16px;font-size:0.833em;color:#ffff00;background:#6db142;text-align:center;border-radius: 2px;} +.lat li .hot_icon{display:inline-block;width: 16px;line-height:16px ;font-size:0.833em;color:#fff;background:#e52955;text-align:center;border-radius: 2px;} +.lat li .fa-caret-right{color:#bbb} +.lat .lt_date{position:absolute;top:3px;right:0;color:#888} +.lat .empty_li{line-height:145px ;color:#666;text-align:center;padding:0;} +.lat .empty_li:before{background:none;padding:0} + +.lat .lt_cmt{background:#5c85c1;color:#fff; font-size:11px;height:16px;line-height:16px;padding:0 5px;border-radius:3px; +-webkit-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +-moz-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +box-shadow: inset 0 2px 5px rgba(255,255,255,0.4);} +.lat .lt_more {position:absolute;top:11px;right:10px;display:block;width:25px;line-height:25px;color:#aaa;border-radius:3px;text-align:center;} +.lat .lt_more:hover{color:#777} \ No newline at end of file diff --git a/theme/basic/skin/latest/notice/latest.skin.php b/theme/basic/skin/latest/notice/latest.skin.php new file mode 100644 index 000000000..5091d3178 --- /dev/null +++ b/theme/basic/skin/latest/notice/latest.skin.php @@ -0,0 +1,53 @@ +', 0); +add_javascript('', 10); +?> + +
    +

    + + +
    + + + \ No newline at end of file diff --git a/theme/basic/skin/latest/notice/style.css b/theme/basic/skin/latest/notice/style.css new file mode 100644 index 000000000..3867cde8e --- /dev/null +++ b/theme/basic/skin/latest/notice/style.css @@ -0,0 +1,16 @@ +@charset "utf-8"; +/* 새글 스킨 (latest) */ +.notice {position:relative;padding:15px 50px;border-bottom:1px solid #d0d6e4} +.notice li{text-overflow: ellipsis;overflow: hidden;white-space: nowrap;} +.notice li a:hover{color:#a22121} +.notice li .lock_icon{display: inline-block;line-height: 14px;width: 16px;font-size: 0.833em;color: #4f818c;background: #cbe3e8;text-align: center;border-radius: 2px;font-size: 12px;border:1px solid #a2c6ce;vertical-align:top} +.notice li .new_icon{display:inline-block;line-height:16px;width:16px;font-size:0.833em;color:#ffff00;background:#6db142;text-align:center;margin-right:3px;border-radius:2px;vertical-align:top} +.notice .cnt_cmt{background:#5c85c1;color:#fff; font-size:11px;height:16px;line-height:16px;padding:0 5px;border-radius:3px;white-space: nowrap;margin-left:5px; +-webkit-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +-moz-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +box-shadow: inset 0 2px 5px rgba(255,255,255,0.4)} + +.notice h2{position:absolute;top:50%;left:10px;margin-top:-15px;left:5;line-height:30px} +.notice h2 a{display:inline-block;width:30px;line-height:30px;border-radius:25px;background:#4158d1;color:#fff;text-align:center;color:#fff} +.notice .bx-next{position:absolute;top:50%;right:10px;;width:26px;height:26px;line-height:24px;text-align:center;background:#fff;border:1px solid #d1d1d1;margin-top:-12px} +.notice .bx-prev{position:absolute;top:50%;right:35px;width:26px;height:26px;line-height:24px;text-align:center;background:#fff;border:1px solid #d1d1d1;margin-top:-12px} diff --git a/theme/basic/skin/latest/pic_basic/latest.skin.php b/theme/basic/skin/latest/pic_basic/latest.skin.php new file mode 100644 index 000000000..3e826bd9c --- /dev/null +++ b/theme/basic/skin/latest/pic_basic/latest.skin.php @@ -0,0 +1,67 @@ +', 0); +$thumb_width = 210; +$thumb_height = 150; +?> + +
    +

    +
      + '; + ?> +
    • + + 비밀글 "; + + if ($list[$i]['icon_new']) echo "N새글"; + + if ($list[$i]['icon_hot']) echo "H인기글"; + + + echo " "; + if ($list[$i]['is_notice']) + echo "".$list[$i]['subject'].""; + else + echo $list[$i]['subject']; + + + + echo ""; + + // if ($list[$i]['link']['count']) { echo "[{$list[$i]['link']['count']}]"; } + // if ($list[$i]['file']['count']) { echo "<{$list[$i]['file']['count']}>"; } + + //echo $list[$i]['icon_reply']." "; + // if ($list[$i]['icon_file']) echo " " ; + //if ($list[$i]['icon_link']) echo " " ; + + if ($list[$i]['comment_cnt']) echo " + + ".$list[$i]['wr_comment'].""; + + ?> + + +
    • + + +
    • 게시물이 없습니다.
    • + +
    + 더보기 + +
    diff --git a/theme/basic/skin/latest/pic_basic/style.css b/theme/basic/skin/latest/pic_basic/style.css new file mode 100644 index 000000000..9945e8d26 --- /dev/null +++ b/theme/basic/skin/latest/pic_basic/style.css @@ -0,0 +1,24 @@ +@charset "utf-8"; +/* 새글 스킨 (latest) */ +.pic_lt{position:relative;margin-bottom:20px;overflow:hidden;border: 1px solid #c6cacc;background:#fff} +.pic_lt .lat_title {display:block;background:#fcfcfc;padding:0 20px;line-height:45px;font-size:1.083em;border-bottom:1px solid #e2e2e2;color:#253dbe;} +.pic_lt .lat_title a{color:#253dbe;display:inline-block;position:relative} +.pic_lt .lat_title a:after{position:absolute;bottom:-1px;left:0;width:100%;height:2px;background:#253dbe;content:''} +.pic_lt .lt_more {position:absolute;top:11px;right:10px;display:block;width:25px;line-height:25px;color:#aaa;border-radius:3px;text-align:center;} +.pic_lt .lt_more:hover{color:#777} +.pic_lt ul:after {display:block;visibility:hidden;clear:both;content:""} +.pic_lt ul{padding:20px 15px } +.pic_lt li{float:left;width:20%;padding:0 10px} +.pic_lt li .lt_img{margin:5px 0;display:block} +.pic_lt li .lt_img img{width:100%;height:auto} +.pic_lt li a:hover{color:#a22121} +.pic_lt li .fa-heart{color:#ff0000;} +.pic_lt li .fa-lock{display: inline-block;line-height: 14px;width: 16px;font-size: 0.833em;color: #4f818c;background: #cbe3e8;text-align: center;border-radius: 2px;font-size: 12px;border:1px solid #a2c6ce} +.pic_lt li .new_icon{display:inline-block;width: 16px;line-height:16px ;font-size:0.833em;color:#ffff00;background:#6db142;text-align:center;border-radius: 2px;} +.pic_lt li .hot_icon{display:inline-block;width: 16px;line-height:16px ;font-size:0.833em;color:#fff;background:#e52955;text-align:center;border-radius: 2px;} +.pic_lt li .fa-caret-right{color:#bbb} +.pic_lt .lt_cmt{background:#5c85c1;color:#fff; font-size:11px;height:16px;line-height:16px;padding:0 5px;border-radius:3px;white-space: nowrap; +-webkit-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +-moz-box-shadow: inset 0 2px 5px rgba(255,255,255,0.4); +box-shadow: inset 0 2px 5px rgba(255,255,255,0.4);} +.pic_lt .lt_date{display:block;margin-top:5px;color: #888;} diff --git a/theme/basic/skin/member/basic/formmail.skin.php b/theme/basic/skin/member/basic/formmail.skin.php index 274bbc96e..42b5520de 100644 --- a/theme/basic/skin/member/basic/formmail.skin.php +++ b/theme/basic/skin/member/basic/formmail.skin.php @@ -6,7 +6,7 @@ add_stylesheet('', ?> -
    +

    님께 메일보내기

    @@ -17,59 +17,58 @@ add_stylesheet('', -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    메일쓰기
    형식 +
    +

    메일쓰기

    +
      + +
    • + + +
    • +
    • + + +
    • + +
    • + + +
    • +
    • + 형식 -
    - - 첨부 파일은 누락될 수 있으므로 메일을 보낸 후 파일이 첨부 되었는지 반드시 확인해 주시기 바랍니다. -
    자동등록방지
    + +
  • + + +
  • +
  • +
    + + +
    +
    첨부 파일은 누락될 수 있으므로 메일을 보낸 후 파일이 첨부 되었는지 반드시 확인해 주시기 바랍니다.
    + +
  • +
  • +
    + + +
    +
  • +
  • + 자동등록방지 + +
  • + +
    + + +
    -
    - - -
    diff --git a/theme/basic/skin/member/basic/login.skin.php b/theme/basic/skin/member/basic/login.skin.php index 86772c70d..6bd3c820d 100644 --- a/theme/basic/skin/member/basic/login.skin.php +++ b/theme/basic/skin/member/basic/login.skin.php @@ -14,33 +14,30 @@ add_stylesheet('',
    회원로그인 - - - - + + + +
    + + - - +
    - \ No newline at end of file + diff --git a/theme/basic/skin/member/basic/member_confirm.skin.php b/theme/basic/skin/member/basic/member_confirm.skin.php index 3ea749ba7..457a318b4 100644 --- a/theme/basic/skin/member/basic/member_confirm.skin.php +++ b/theme/basic/skin/member/basic/member_confirm.skin.php @@ -23,20 +23,15 @@ add_stylesheet('',
    - 회원아이디 + 회원아이디 - - - + +
    - -
    - \ No newline at end of file + diff --git a/theme/basic/skin/member/basic/register_form.skin.php b/theme/basic/skin/member/basic/register_form.skin.php index 436bee0e9..c69447e72 100644 --- a/theme/basic/skin/member/basic/register_form.skin.php +++ b/theme/basic/skin/member/basic/register_form.skin.php @@ -6,61 +6,51 @@ add_stylesheet('', ?> -
    - - - - + + + + -
    - - - - - - - - date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400))) { // 닉네임수정일이 지나지 않았다면 ?> - - - - -
    - - - - - - - - - - - - - - - - -
    사이트 이용정보 입력
    - 영문자, 숫자, _ 만 입력 가능. 최소 3자이상 입력하세요. - class="frm_input " minlength="3" maxlength="20"> + + + + + + + + + date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400))) { // 닉네임수정일이 지나지 않았다면 ?> + + + +
    +
    +

    사이트 이용정보 입력

    +
      +
    • + + class="frm_input half_input " minlength="3" maxlength="20" placeholder="아이디"> -
    class="frm_input " minlength="3" maxlength="20">
    class="frm_input " minlength="3" maxlength="20">
    + 영문자, 숫자, _ 만 입력 가능. 최소 3자이상 입력하세요. + +
  • + + class="frm_input half_input " minlength="3" maxlength="20" placeholder="비밀번호"> + + + class="frm_input half_input right_input " minlength="3" maxlength="20" placeholder="비밀번호 확인"> +
  • +
    - - - - - - - - - - - - - + + 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. + - - - - + + + - - - - - - + +
  • + + class="frm_input full_input " size="70" maxlength="255" placeholder="홈페이지"> +
  • + - - - - - - +
  • + + + + class="frm_input half_input " maxlength="20" placeholder="전화번호"> + - -
  • - - - - + + - - - - - - - -
    개인정보 입력
    - - 아이핀 본인확인 후에는 이름이 자동 입력되고 휴대폰 본인확인 후에는 이름과 휴대폰번호가 자동 입력되어 수동으로 입력할수 없게 됩니다. - - class="frm_input " size="10"> +

    개인정보 입력

    + +
      +
    • + + class="frm_input half_input " size="10" placeholder="이름"> ', else $mb_cert = '휴대폰'; ?> +
      본인확인성인인증 완료
      -
    - - 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    - 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. -
    - - - -
    + + + +
  • + + + + + + + 공백없이 한글,영문,숫자만 입력 가능 (한글2자, 영문4자 이상)
    + 닉네임을 바꾸시면 앞으로 일 이내에는 변경 할 수 없습니다. +
    + +
  • + + +
  • + + @@ -109,160 +104,176 @@ add_stylesheet('', - -
  • class="frm_input " size="70" maxlength="255">
    class="frm_input " maxlength="20">
    - class="frm_input " maxlength="20"> + + + + class="frm_input right_input half_input " maxlength="20" placeholder="휴대폰번호"> -
    - 주소 + + +
  • 필수 -
  • - class="frm_input " size="5" maxlength="6"> + class="frm_input " size="5" maxlength="6" placeholder="우편번호">
    - class="frm_input frm_address " size="50"> -
    - - + class="frm_input frm_address full_input " size="50" placeholder="기본주소"> +
    + +
    - - + + -
    + + + +
    - - - - - - - - - +

    기타 개인설정

    +
      + +
    • + + +
    • + - -
    - - - - + +
  • + + +
  • + - = $config['cf_icon_level']) { ?> - - - - - + + + - - - - + + - - - - - - + +
  • + + + > + 휴대폰 문자메세지를 받겠습니다. + +
  • + - - - - - - - - - - - + + + - - - - - - + - - - - - -
    기타 개인설정
    + = $config['cf_icon_level']) { ?> +
  • + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    - gif만 가능하며 용량 바이트 이하만 등록됩니다. + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다.
    - + 회원아이콘 -
  • + = $config['cf_icon_level'] && $config['cf_member_img_size'] && $config['cf_member_img_width'] && $config['cf_member_img_height']) { ?> +
  • + + + + + 이미지 크기는 가로 픽셀, 세로 픽셀 이하로 해주세요.
    + gif, jpg, png파일만 가능하며 용량 바이트 이하만 등록됩니다. +
    + + + 회원아이콘 + + + + +
  • + + +
  • + > 정보 메일을 받겠습니다. -
  • - > - 휴대폰 문자메세지를 받겠습니다. -
    - - 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. - + +
  • + id="reg_mb_open"> 다른분들이 나의 정보를 볼 수 있도록 합니다. -
  • 정보공개 + + 정보공개를 바꾸시면 앞으로 일 이내에는 변경이 안됩니다. + + + +
  • + 정보공개 + 정보공개는 수정후 일 이내, 까지는 변경이 안됩니다.
    이렇게 하는 이유는 잦은 정보공개 수정으로 인하여 쪽지를 보낸 후 받지 않는 경우를 막기 위해서 입니다.
    - -
  • 자동등록방지
    + +
  • + + +
  • + + +
  • + 자동등록방지 + +
  • +
    - -
    - - 취소 -
    -
    + +
    +
    + 취소 + +
    + -
    \ No newline at end of file diff --git a/theme/basic/skin/member/basic/register_result.skin.php b/theme/basic/skin/member/basic/register_result.skin.php index 1267d20ee..2072485a3 100644 --- a/theme/basic/skin/member/basic/register_result.skin.php +++ b/theme/basic/skin/member/basic/register_result.skin.php @@ -6,13 +6,13 @@ add_stylesheet('', ?> -
    - -

    +

    +

    회원가입이 완료되었습니다.

    +

    님의 회원가입을 진심으로 축하합니다.

    - +

    회원 가입 시 입력하신 이메일 주소로 인증메일이 발송되었습니다.
    발송된 인증메일을 확인하신 후 인증처리를 하시면 사이트를 원활하게 이용하실 수 있습니다. @@ -38,9 +38,7 @@ add_stylesheet('', 감사합니다.

    - + 메인으로
    \ No newline at end of file diff --git a/theme/basic/skin/member/basic/scrap.skin.php b/theme/basic/skin/member/basic/scrap.skin.php index e89053522..c2a7c52ce 100644 --- a/theme/basic/skin/member/basic/scrap.skin.php +++ b/theme/basic/skin/member/basic/scrap.skin.php @@ -6,41 +6,28 @@ add_stylesheet('', ?> -
    -

    +
    +

    -
    - - - - - - - - - - - - - - - - - - - - - +
    +
    "; ?> - -
    스크랩 목록
    번호게시판제목보관일시삭제
    삭제
    자료가 없습니다.
    + 자료가 없습니다."; ?> +
    - +
    \ No newline at end of file diff --git a/theme/basic/skin/member/basic/scrap_popin.skin.php b/theme/basic/skin/member/basic/scrap_popin.skin.php index 81f82a5a9..ad3ed8b28 100644 --- a/theme/basic/skin/member/basic/scrap_popin.skin.php +++ b/theme/basic/skin/member/basic/scrap_popin.skin.php @@ -6,35 +6,34 @@ add_stylesheet('', ?> -
    +

    스크랩하기

    -
    +
    -
    - - - - - - - - - - - - -
    제목 확인 및 댓글 쓰기
    제목
    -
    +
    +

    제목 확인 및 댓글 쓰기

    +
      +
    • + 제목 + +
    • +
    • + + +
    • +
    +
    -

    - 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. -

    +

    + 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. +

    -
    - +
    + +
    diff --git a/theme/basic/skin/member/basic/style.css b/theme/basic/skin/member/basic/style.css index b86359a68..b3a308714 100644 --- a/theme/basic/skin/member/basic/style.css +++ b/theme/basic/skin/member/basic/style.css @@ -1,5 +1,4 @@ @charset "utf-8"; -/* SIR 지운아빠 */ /* ### 기본 스타일 커스터마이징 시작 ### */ @@ -22,6 +21,7 @@ .mbskin .win_btn input {} .mbskin .win_btn a {} .mbskin .win_btn a:focus, .mbskin .win_btn a:hover {} + /* 게시판용 버튼 */ .mbskin a.btn_b01 {} .mbskin a.btn_b01:focus, .mbskin .btn_b01:hover {} @@ -30,7 +30,30 @@ .mbskin a.btn_admin {} /* 관리자 전용 버튼 */ .mbskin a.btn_admin:focus, .mbskin a.btn_admin:hover {} +/* 기본박스 */ +.mbskin{position: relative;margin:100px auto 0;border:1px solid #ddd;width:400px;background:#fff;text-align:center; +} +.mbskin:before,.mbskin:after{ +content:""; +position:absolute;z-index:-1;top:2%;bottom:0;left:10px;right:10px; +-webkit-box-shadow:0 0 20px rgba(0,0,0,0.8); + -moz-box-shadow:0 0 20px rgba(0,0,0,0.8); + box-shadow:0 0 20px rgba(0,0,0,0.8); +-moz-border-radius:100px / 10px; + border-radius:100px / 10px;} +.mbskin:after{right:10px;left:auto; + -webkit-transform:skew(8deg) rotate(3deg); + -moz-transform:skew(8deg) rotate(3deg); + -ms-transform:skew(8deg) rotate(3deg); + -o-transform:skew(8deg) rotate(3deg); + transform:skew(8deg) rotate(3deg);} +.mbskin .frm_input{width:100%} +.mbskin .btn_submit{width:100%;margin:10px 0 0;height:45px;font-weight:bold;font-size:1.25em} +.mbskin h1{margin: 60px 0 30px;font-size: 2em;} + + /* 기본테이블 */ + .mbskin .tbl_head01 {} .mbskin .tbl_head01 caption {} .mbskin .tbl_head01 thead th {} @@ -82,95 +105,158 @@ /* ### 기본 스타일 커스터마이징 끝 ### */ /* 회원가입 약관 */ -#fregister section {margin:0 0 20px;padding:20px 0} -#fregister h2 {margin:0 0 20px;text-align:center} -#fregister textarea {display:block;margin-bottom:10px;padding:5px;width:98%;height:150px;border:1px solid #e9e9e9;background:#f7f7f7} -#fregister .fregister_agree {padding:10px 0 0;text-align:right} -#fregister .fregister_agree label {display:inline-block;margin-right:5px} -#fregister p {color:#e8180c;text-align:center} -#fregister .btn_confirm {margin-bottom:20px} -#fregister_private .tbl_head01 th{;text-align:center;border:1px solid #d1dee2;width:33%} -#fregister_private .tbl_head01 td {border:1px solid #e9e9e9} -#fregister_private .tbl_head01 caption{position:absolute;font-size:0;line-height:0;overflow:hidden} +#fregister p{text-align:center;color: #c7254e;background: #f9f2f4;padding:10px;border:1px solid #ecc7d2;margin:0 0 5px} +#fregister section {;margin:10px auto 30px;border:1px solid #dbdbdb;position:relative;border-radius:3px 3px 0 0 ; +-webkit-box-shadow: 0 1px 3px #eee; +-moz-box-shadow: 0 1px 3px #eee; +box-shadow: 0 1px 3px #eee; +} +#fregister_chkall{text-align:right} +#fregister h2 {text-align:left;padding:15px 20px;border-bottom:1px solid #dbdbdb;background:#f8f8f8} +#fregister textarea {display:block;padding:20px;width:100%;height:150px;background:#fff;border:0;line-height:1.6em} +#fregister .fregister_agree {position:absolute;top:0;right:0;;padding:15px} +#fregister_private div{padding:20px;background:#fff} +#fregister_private table{width:100%;border-collapse:collapse} +#fregister_private table caption {position:absolute;font-size:0;line-height:0;overflow:hidden} +#fregister_private table th{background:#646982;width:33.33%;color:#fff;padding:10px;border:1px solid #555971} +#fregister_private table td{border:1px solid #ddd;padding:10px;} +#fregister .btn_confirm{text-align:center;} +#fregister .btn_confirm .btn_submit{height:50px;padding:0 40px;font-weight:bold;font-size:1.083em} /* 회원가입 입력 */ -#fregisterform textarea {height:50px} - +#register_form{background:#fff;padding:20px;margin-bottom:20px} #fregisterform #msg_certify {margin:5px 0 0;padding:5px;border:1px solid #dbecff;background:#eaf4ff;text-align:center} - #fregisterform .frm_address {margin:5px 0 0} #fregisterform #mb_addr3 {display:inline-block;margin:5px 0 0;vertical-align:middle} #fregisterform #mb_addr_jibeon {display:block;margin:5px 0 0} +#fregisterform .btn_confirm{text-align:center} +#fregisterform .btn_confirm .btn_submit{height:45px;;padding:0 30px;font-weight:bold;font-size:1.083em} +#fregisterform .btn_confirm .btn_cancel{line-height:45px;height:45px;padding:0 30px;font-weight:bold;font-size:1.083em} +#fregisterform .frm_info{display:block;color:#3497d9;font-size:0.92em} +#fregisterform .form_01 div{margin: 0 0 50px} +#fregisterform .captcha{display:block;margin:5px 0 0} +#fregisterform .reg_mb_img_file img{max-width:100%;height:auto} + /* 회원가입 완료 */ -#reg_result {padding:50px 0 0} +#reg_result {padding:100px 0 40px;text-align:center;background:#fff} +#reg_result h2{font-size:2em;margin:0 0 20px} +#reg_result h2 strong{color:#ed6478} #reg_result #result_email {margin:20px 0;padding:10px 50px;border-top:1px solid #e9e9e9;border-bottom:1px solid #dde4e9;background:#fff;line-height:2em} #reg_result #result_email span {display:inline-block;width:150px} #reg_result #result_email strong {color:#e8180c;font-size:1.2em} #reg_result p {line-height:1.8em} #reg_result .btn_confirm {margin:50px 0} +#reg_result .reg_result_p{font-size:1.25em;margin:0 0 10px;} +#reg_result .reg_result_p strong{color:#3497d9} +#reg_result .btn_submit{padding: 0 30px;font-weight:bold;height:40px;line-height:40px;display:inline-block;margin:30px 0 0 ;font-size:1.083em} /* 아이디/비밀번호 찾기 */ #find_info #mb_hp_label {display:inline-block;margin-left:10px} -#find_info #info_fs {margin:0 20px 20px;padding:0;background:#fff} -#find_info #info_fs .frm_input {width:70%} -#find_info p {margin:0 0 10px;line-height:1.8em} -#find_info #captcha {margin:0 20px} +#find_info p {line-height:1.5em} +#find_info #mb_email{margin:10px 0;} /* 로그인 */ -#mb_login {margin:0 auto;padding:100px 0;width:500px} -#mb_login h1 {margin:0 0 20px;font-size:1.3em} -#mb_login h2 {margin:0} -#mb_login p {padding:10px 0;line-height:1.5em} -#mb_login #login_fs {position:relative;margin:0;padding:20px 20px 20px 95px;border:1px solid #cfded8;border-bottom:0;background:#fff} -#mb_login #login_fs legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} -#mb_login #login_fs label {letter-spacing:-0.1em} -#mb_login #login_fs .login_id {position:absolute;top:26px;left:95px} -#mb_login #login_fs .login_pw {position:absolute;top:52px;left:95px} -#mb_login #login_fs .frm_input {display:block;margin:0 0 5px 80px;width:162px} -#mb_login #login_fs .btn_submit {position:absolute;top:20px;right:95px;width:60px;height:53px} -#mb_login #login_info {margin:0 0 30px;padding:20px;border:1px solid #cfded8;background:#f5f6fa} -#mb_login #login_info div {text-align:right} +#mb_login {} +#login_fs{padding:0 50px} +#mb_login #login_fs .frm_input{margin:0 0 10px} +#mb_login #login_fs .btn_submit {margin:0 0 20px} +#mb_login #login_info{background:#f6f6f6;padding:25px 10px;border-top:1px solid #e8e8e8;margin:40px 0 0 } +#mb_login #login_info:after {display:block;visibility:hidden;clear:both;content:""} +#mb_login #login_info h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#mb_login #login_info a{display:inline-block;width:50%;float:left} +#login_password_lost{border-right:1px solid #ddd} + +#mb_login_notmb{margin:30px auto;padding:20px 30px } +#mb_login_notmb h2{font-size:1.25em;margin:20px 0 10px} +#guest_privacy{border:1px solid #ccc;text-align:left;line-height:1.6em;color:#666;background:#fafafa;padding:10px;height:150px;margin:10px 0;overflow-y:auto} +#mb_login_notmb .btn_submit{display:block;text-align:center;line-height:45px} + +#mb_login_od_wr{margin:30px auto;padding:20px 30px } +#mb_login_od_wr h2{font-size:1.25em;margin:20px 0 10px} +#mb_login_od_wr .frm_input{margin:10px 0 0 } +#mb_login_od_wr p{background:#f3f3f3;margin:20px 0 0 ;padding:15px 20px;line-height:1.5em} /* 쪽지 */ -#memo_view_contents {margin:0 auto 20px;width:90%} -#memo_view_contents h1 {position:absolute;font-size:0;line-height:0;overflow:hidden} -#memo_view_ul {margin:0;padding:0 0 10px;border-bottom:1px solid #eee;list-style:none} -.memo_view_li {position:relative;padding:5px 0} -.memo_view_subj {display:inline-block;width:65px} -#memo_view p {padding:10px 0;min-height:150px;height:auto !important;height:150px;background:#fff;line-height:1.8em} +#memo_list .memo_name,#memo_list .memo_name .sv_wrap{font-weight:bold} +#memo_list .memo_datetime{float:right;font-size:0.92em;color:#777;font-style:italic} +#memo_list .memo_del{margin-left: 5px; color: #49857c;font-size: 15px;} + +#memo_view_contents {margin:10px 0;border:1px solid #ddd;} +#memo_view_contents h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#memo_view_ul {margin:0;border-bottom:1px solid #eee;list-style:none;background:#f3f3f3;} +#memo_view_ul:after {display:block;visibility:hidden;clear:both;content:""} +.memo_view_li {position:relative;padding:10px;float:left;width:50%;} +.memo_view_name strong,.memo_view_name .sv_wrap{font-weight:bold !important} +.memo_view_subj{display: inline-block;height: 20px;line-height: 18px;border: 1px solid #3497d9;color: #3497d9;padding: 0 5px;border-radius: 15px;font-size: 11px;} +.memo_view_li .profile_img img{border-radius:50%} +.memo_view_date{text-align:right;color:#555;font-style:italic} +.memo_view_date strong{font-weight:normal} +#memo_view .btn_b02{float:right} +#memo_view p {padding:10px;border-top:1px solid #ddd;min-height:150px;height:auto !important;height:150px;background:#fff;line-height:1.8em} #memo_write textarea {height:100px} /* 스크랩 */ +#scrap .scrap_tit{font-weight:bold;display:block;font-size:1.083em;margin-bottom:5px;line-height:1.3em} +#scrap .scrap_cate{ display:block;color:#3598db ;font-size:0.92em;float:left} +#scrap .scrap_datetime{;color:#777;font-style:italic;float:right} +#scrap .scrap_del{position:absolute;top:5px;right:10px;font-size:18px;color:#49857c} +#scrap .scrap_del:hover{color:#98ca69} #scrap_do table {margin:0 0 10px;width:100%} #scrap_do textarea {height:100px} +#scrap_do .scrap_tit{background:#f3f3f3;padding:10px 15px;font-size:1.083em;font-weight:bold} +#scrap_do label{display:block;margin:0 0 5px;font-size:0.92em} +/*포인트*/ +#point .point_top{line-height:15px;margin:0 0 5px} +#point .point_top:after {display:block;visibility:hidden;clear:both;content:""} +#point .point_tit{font-weight:bold;float:left;font-size:1.083em;display:block;} +#point .point_num{font-size:1.25em;color:#00c4ac;font-weight:bold;float:right;} +#point .point_date1{float:left;color:#555;font-style:italic} +#point .point_date{float:right;color:#555;font-style:italic} +#point .txt_expired {color:#aaa;} +#point .point_all{background:#ae99da;border:0;border-bottom:2px solid #9781c5;color:#fff;font-weight:bold;font-size:1.083em} +#point .point_all span,#point .point_status span{float:right;} +#point .point_status{background:#737373;border:0;color:#fff;font-weight:bold;font-size:1.083em} +#point .point_status span{margin-left:10px} /* 회원 비밀번호 확인 */ -#mb_confirm {margin:0 auto;padding:100px 0;width:500px} -#mb_confirm h1 {margin:0 0 20px;font-size:1.3em} -#mb_confirm p {padding:20px;border:1px solid #dde4e9;border-bottom:0;background:#fff} -#mb_confirm p strong {display:block} -#mb_confirm fieldset {margin:0 0 30px;padding:30px 0;border:1px solid #e9e9e9;background:#f5f6fa;text-align:center} +#mb_confirm {} +#mb_confirm h1 {margin:60px 0 30px;font-size:2em} +#mb_confirm p {padding:0 20px 40px;border-bottom:1px solid #e9e9e9;font-size:1.083em;line-height:1.4em;color:#656565} +#mb_confirm p strong {display:block;color:#3ca1ff;font-size:1.167em;margin:0 0 5px} +#mb_confirm fieldset {;padding:50px;text-align:left} #mb_confirm fieldset .frm_input {background-color:#fff !important} #mb_confirm label {letter-spacing:-0.1em} -#mb_confirm_id {display:inline-block;margin-right:20px;font-weight:bold} +#mb_confirm_id {display:block;margin:5px 0 10px;font-weight:bold} +#mb_confirm .confirm_id{font-size:0.92em;color:#666} /* 비밀글 비밀번호 확인 */ -#pw_confirm {margin:0 auto;padding:100px 0;width:500px} -#pw_confirm h1 {margin:0 0 20px;font-size:1.3em} -#pw_confirm p {padding:20px;border:1px solid #dde4e9;border-bottom:0;background:#fff} -#pw_confirm p strong {display:block} -#pw_confirm fieldset {margin:0 0 30px;padding:30px 0;border:1px solid #e9e9e9;background:#f5f6fa;text-align:center} +#pw_confirm h1 {margin:60px 20px 30px;font-size:2em} +#pw_confirm p {padding:0 20px 40px;border-bottom:1px solid #e9e9e9;font-size:1.083em;line-height:1.4em;color:#656565} +#pw_confirm p strong {display:block;color:#3ca1ff;font-size:1.167em;margin:0 0 5px} +#pw_confirm fieldset {;padding:50px;text-align:center} #pw_confirm fieldset .frm_input {background-color:#fff !important} #pw_confirm label {letter-spacing:-0.1em} #pw_confirm_id {display:inline-block;margin-right:20px;font-weight:bold} +#mb_confirm_id{} /* 폼메일 */ -#formmail #subject {width:386px} #formmail textarea {height:100px} +#formmail .formmail_flie{position:relative} +#formmail .formmail_flie .file_wr {border: 1px solid #ccc;background: #fff;color: #000;vertical-align: middle;border-radius: 3px;padding: 5px;height: 40px;margin: 0;} +#formmail .lb_icon {position: absolute;top: 1px;left: 1px;border-radius: 3px 0 0 3px;height: 38px;line-height: 38px;width: 40px;background: #eee;text-align: center;color: #888;} +#formmail .frm_file {padding-left: 50px;} +#formmail .frm_info{color: #3497d9;font-size: 0.92em;} /* 자기소개 */ +#profile h1 a{color:#fff} #profile table {margin-bottom:0} -#profile section {margin:0 auto 20px;padding:20px;width:86%} -#profile h2 {margin:0} \ No newline at end of file +#profile table th{text-align:left;padding:10px;width:100px} +#profile section {color: #2d4c7b;background: #eff9f9;padding: 10px;border: 1px solid #bfd4dc;margin: 10px 0;} +#profile h2 {margin:0 0 5px} +#profile .profile_name{text-align:center;font-weight:bold} +#profile .my_profile_img{display:block;margin:20px 0 5px;} +#profile .my_profile_img img{border-radius:50%;border:1px solid #aaa} +#profile .profile_img img{border-radius:50%} +#profile .profile_name .sv_wrap{font-weight:bold;text-align:left} \ No newline at end of file diff --git a/theme/basic/skin/new/basic/new.skin.php b/theme/basic/skin/new/basic/new.skin.php index 2558d8118..9401f2b50 100644 --- a/theme/basic/skin/new/basic/new.skin.php +++ b/theme/basic/skin/new/basic/new.skin.php @@ -22,8 +22,8 @@ add_stylesheet('', 0);
    - - 목록 + 목록 + +
    diff --git a/theme/basic/skin/search/basic/search.skin.php b/theme/basic/skin/search/basic/search.skin.php index e341efa3f..c6386f500 100644 --- a/theme/basic/skin/search/basic/search.skin.php +++ b/theme/basic/skin/search/basic/search.skin.php @@ -23,8 +23,10 @@ add_stylesheet('', - - + + + + - id="sop_or" name="sop"> - - id="sop_and" name="sop"> - + + id="sop_or" name="sop"> + + id="sop_and" name="sop"> + + @@ -68,7 +72,7 @@ add_stylesheet('', if ($board_count) { ?>
    -

    전체검색 결과

    +

    전체검색 결과

    게시판
    @@ -109,7 +113,7 @@ add_stylesheet('', for ($i=0; $i', ?>
  • - - 새창 +
    + + 새창 +

    - - +
    + + +
  • - +
    diff --git a/theme/basic/skin/search/basic/style.css b/theme/basic/skin/search/basic/style.css index 8adf23a45..94d01dc26 100644 --- a/theme/basic/skin/search/basic/style.css +++ b/theme/basic/skin/search/basic/style.css @@ -1,29 +1,53 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* 전체검색결과 스킨 */ -#sch_res_detail {padding:0 0 10px;border-bottom:1px solid #e9e9e9;text-align:center} +#sch_res_detail {background:#fff;padding:30px;border:1px solid #ccc;text-align:center;margin:0 0 10px} #sch_res_detail legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} -#sch_res_ov {margin:0 0 10px;padding:10px;border-bottom:1px solid #e9e9e9;background:#f5f6fa;zoom:1} +#sch_res_detail select{border:1px solid #646982;height:40px;padding:0 5px} +#sch_res_detail .frm_input{border:1px solid #646982;border-radius:0;} +#sch_res_detail .sch_wr{position:relative;display:inline-block} +#sch_res_detail .btn_submit{padding:0 10px;height:40px;color:#000;font-size:1.083em;font-weight:bold;color:#fff;background:#253dbe} +#sch_res_detail .sch_rd{display:block;margin:5px 0 0;font-size:0.92em;color:#666} + +#sch_res_ov {text-align:center;zoom:1} #sch_res_ov:after {display:block;visibility:hidden;clear:both;content:""} -#sch_res_ov h2 {float:left} -#sch_res_ov dl {float:left;margin:0 0 0 10px} +#sch_res_ov h2 {text-align:center;margin:30px 0 10px;font-size:1.5em;} +#sch_res_ov h2 strong{color:#00c4ac;} +#sch_res_ov dl {display:inline-block;line-height: 30px;font-size: 0.92em;color: #4e546f;background: #d4d4d4;padding: 0 10px;border-radius: 5px;} +#sch_res_ov dl:after {display:block;visibility:hidden;clear:both;content:""} #sch_res_ov dt {float:left} #sch_res_ov dd {float:left;margin:0 10px 0 5px} -#sch_res_ov p {float:right;margin:0;padding:0;line-height:1em} +#sch_res_ov dd .sch_word{color:#000} +#sch_res_ov p {margin:0;padding:0;line-height:1em;color:#777;font-size:0.92em} + + +#sch_res_board {background:#ecf2f3;padding:7px;margin:10px 0;border:1px solid #bed1d4} +#sch_res_board h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#sch_res_board ul {zoom:1} +#sch_res_board ul:after {display:block;visibility:hidden;clear:both;content:""} +#sch_res_board li {display:inline-block;padding:2px;} +#sch_res_board a {display:block;line-height:26px;padding:0 10px;border-radius:3px;border:1px solid transparent} +#sch_res_board a:focus, #sch_res_board a:hover {text-decoration:none;background:#d2d6dc;} +#sch_res_board .cnt_cmt {font-weight:normal !important;display:inline-block;background:#c4dce0;margin-left:3px;color:#3497d9;border-radius:15px;height:18px;padding:0 5px;line-height:18px;font-size:0.92em} +#sch_res_board .sch_on {z-index:2;background:#3497d9;color:#fff;font-weight:bold;border-bottom-color:#1977b5; +-webkit-box-shadow: inset 0 2px 5px rgb(33, 135, 202); +-moz-box-shadow: inset 0 2px 5px rgb(33, 135, 202); +box-shadow:inset 0 2px 5px rgb(33, 135, 202);} +#sch_res_board .sch_on:hover{;background:#3497d9;color:#fff;} + + -#sch_res_board {margin:0 0 10px;padding-left:1px;list-style:none;zoom:1} -#sch_res_board:after {display:block;visibility:hidden;clear:both;content:""} -#sch_res_board li {float:left;margin-bottom:-1px} -#sch_res_board a {display:block;position:relative;margin-left:-1px;padding:6px 0 5px;width:180px;border:1px solid #ddd;text-align:center;letter-spacing:-0.1em;line-height:1.2em;cursor:pointer} -#sch_res_board a:focus, #sch_res_board a:hover, #sch_res_board a:active {text-decoration:none} -#sch_res_board .cnt_cmt {font-weight:normal !important} .sch_res_list {margin:0 0 10px;padding:10px 0 15px} -.sch_res_list h2 {margin:0 0 15px;font-size:1.2em} -.sch_res_list ul {margin:0;padding:0;list-style:none} -.sch_res_list li {margin:0 0 10px;padding:0 0 10px;border-bottom:1px solid #e9e9e9} +.sch_res_list h2 {margin:0 0 10px;font-size:1.2em} +.sch_res_list ul {margin:0;padding:0;list-style:none;border-top:1px solid #000} +.sch_res_list li {;border-bottom:1px solid #e0e0e0;background:#fff;position:relative} +.sch_res_list .sch_tit{display:block;background:#f4f4f4;padding:10px 70px 10px 10px} +.sch_res_list .pop_a{position:absolute;top:10px;right:10px;color:#666;} .sch_res_title {display:inline-block;margin:0 0 5px} -.sch_res_list p {margin:0 0 10px;line-height:1.8em} -.sch_more {text-align:right} -.sch_on {color:#ff3061} \ No newline at end of file +.sch_res_list p {padding:10px;color:#666;line-height:1.5em} +.sch_res_list .sch_info{padding:10px;color:#777} +.sch_res_list .sch_info:after {display:block;visibility:hidden;clear:both;content:""} +.sch_res_list .profile_img img{border-radius:50%} +.sch_res_list .sch_datetime{float:right;} +.sch_more {text-align:right;margin:10px 0 30px} +.sch_more a{display:inline-block;color:#f2664f} diff --git a/theme/basic/skin/visit/basic/style.css b/theme/basic/skin/visit/basic/style.css index 6b061cb27..039875a6a 100644 --- a/theme/basic/skin/visit/basic/style.css +++ b/theme/basic/skin/visit/basic/style.css @@ -1,13 +1,15 @@ @charset "utf-8"; -/* SIR 지운아빠 */ - /* 방문자 집계 */ -#visit {border-bottom:1px dotted #dde4e9} -#visit div {margin:0 auto;width:970px;zoom:1} -#visit div:after {display:block;visibility:hidden;clear:both;content:""} -#visit h2 {float:left;padding:10px 45px 10px 0} -#visit dl {float:left;margin:0 0 0 10px;padding:0} -#visit dt {float:left;margin:0;padding:10px 0 10px} -#visit dd {float:left;margin:0 30px 0 0;padding:10px} -#visit a {display:inline-block;padding:10px;text-decoration:none} -#visit a:focus, #visit a:hover {} \ No newline at end of file +#visit {border: 1px solid #d2d9e6; border-bottom: 1px solid #c1ccda;margin:40px 20px 20px;background:#fff;position:relative; +-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.1); +-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.1); +box-shadow:0 1px 2px rgba(0,0,0,0.1)} +#visit .btn_admin{position:absolute;top:10px;right:10px;height:25px;line-height:25px;padding:0 5px;border-radius:3px} +#visit h2 {font-size:1.167em;text-align:center;padding-bottom:15px;padding-top:25px;color:#16b3d6;position:relative} +#visit h2 i{position:absolute;top:-22px;left:50%;width:44px;line-height:44px;margin-left:-22px;border-radius:25px;background:#16b3d6;color:#fff} +#visit dl {border-top:1px solid #e9e9e9;padding:10px 15px;border-radius:5px} +#visit dl:after {display:block;visibility:hidden;clear:both;content:""} +#visit dt {float:left;width:20%;padding:0 5px;line-height:23px;height:23px;color:#555} +#visit dt span{display:inline-block;width:5px;height:5px;border-radius:50%;vertical-align: middle;} +#visit dd {float:left;;width:30%;padding:0 5px;;text-align:right;text-align:right;font-weight:bold;line-height:23px;height:23px;font-size:0.92em} +#visit dd strong{display:inline-block;padding:0 5px;border-radius:20px;line-height:15px;color:#fff;} diff --git a/theme/basic/skin/visit/basic/visit.skin.php b/theme/basic/skin/visit/basic/visit.skin.php index 87e481d2e..768a58829 100644 --- a/theme/basic/skin/visit/basic/visit.skin.php +++ b/theme/basic/skin/visit/basic/visit.skin.php @@ -9,19 +9,17 @@ add_stylesheet('', 0
    -
    -

    접속자집계

    -
    -
    오늘
    -
    -
    어제
    -
    -
    최대
    -
    -
    전체
    -
    -
    - 상세보기 -
    +

    접속자집계

    +
    +
    오늘
    +
    +
    어제
    +
    +
    최대
    +
    +
    전체
    +
    +
    + 상세보기
    \ No newline at end of file diff --git a/theme/basic/tail.php b/theme/basic/tail.php index c7997cfcd..33d3dcb76 100644 --- a/theme/basic/tail.php +++ b/theme/basic/tail.php @@ -8,33 +8,53 @@ if (G5_IS_MOBILE) { ?>
    +
    + + + + +
    +

    - - -
    <?php echo G5_VERSION ?>
    -
    -
    -
    -
    + +
    + +
    <?php echo G5_VERSION ?>
    +
    Copyright © 소유하신 도메인. All rights reserved.
    + + +
    -모바일 버전으로 보기 'basic', // FAQ 스킨 'cf_mobile_faq_skin' => 'basic', // 모바일 FAQ 스킨 'bo_gallery_cols' => 4, // 갤러리 이미지 수 - 'bo_gallery_width' => 174, // 갤러리 이미지 폭 - 'bo_gallery_height' => 124, // 갤러리 이미지 높이 + 'bo_gallery_width' => 210, // 갤러리 이미지 폭 + 'bo_gallery_height' => 150, // 갤러리 이미지 높이 'bo_mobile_gallery_width' => 125, // 모바일 갤러리 이미지 폭 'bo_mobile_gallery_height' => 100, // 모바일 갤러리 이미지 높이 'bo_image_width' => 600, // 게시판 뷰 이미지 폭