Search Results for '웹 프로그래밍'

ATOM Icon

43 POSTS

  1. 2009/10/10 홈피에 자바스크립트로 만든 색상선택기(ColorPicker) 붙여보기. by 프로그래머 (6)
  2. 2009/07/05 시계 가젯을 만들어 보고 구글과 블로그에 띄워보자! by 프로그래머
  3. 2009/06/26 야후 세계 지도 활용하기, 야후 거기 지도 오픈 API 매시업 by 프로그래머 (1)
  4. 2009/06/25 다음 지도를 내 것으로 만들기, 다음 지도 API 매쉬업 by 프로그래머 (2)
  5. 2009/06/24 나만의 네이버 지도 만들기, 지도 API 매쉬업(Mashup) by 프로그래머 (4)
  6. 2009/06/21 자바스크립트로 지도 만들기, 구글 지도 API 매시업(Mashup) by 프로그래머 (8)
  7. 2009/06/07 jQuery 로 텍스트 입력 박스(TextArea)에 크기 조절 막대 추가하기. by 프로그래머 (1)
  8. 2009/06/06 PHP 시간 관련 함수를 써서 시간 차이 계산하기, DATEDIFF by 프로그래머 (2)
  9. 2009/03/22 jQuery 애니메이트로 만들어보는 이미지 슬라이더와 전광판 by 프로그래머 (1)
  10. 2009/03/09 jQuery를 활용한 홈페이지 개발의 기본인 입력폼 제작 by 프로그래머 (6)
  11. 2009/01/27 jQuery UI로 달력과 날짜입력기(DatePicker)를 붙여보기. by 프로그래머
  12. 2009/01/26 PHP 또는 자바스크립트로 달력 만들기 소스 코드 by 프로그래머 (5)
  13. 2009/01/20 스핑크스 검색엔진으로 내 블로그 검색 성능을 높이자. by 프로그래머
  14. 2009/01/18 웹 기반의 WYSIWYG 에디터, FCKeditor를 사용해보자. by 프로그래머
  15. 2009/01/17 엑셀 문서 파일을 데이타베이스에 업로드 하는 PHP 소스 코드 by 프로그래머 (1)
  16. 2009/01/04 동적 HTML 객체 모델 요소의 위치와 면적 계산 by 프로그래머
  17. 2009/01/04 자바스크립트, 객체의 속성과 메소드와 이벤트 핸들러 by 프로그래머
  18. 2009/01/04 HTML과 자바스크립트에서 스타일시트 속성 by 프로그래머 (2)
  19. 2009/01/03 자바스크립트, 모서리가 둥근 테이블 만들기. by 프로그래머
  20. 2008/12/16 이미지 썸네일을 생성하는 PHP 함수 소스 코드 by 프로그래머 (2)
  21. 2008/12/06 내 블로그 검색에 오픈 소스 검색엔진을 붙여보자! by 프로그래머 (1)
  22. 2008/10/15 자바스크립트 복수 게시물 더보기/접기(more/less) 소스 by 프로그래머 (6)
  23. 2008/09/30 자바스크립트로 아날로그 시계 만들기 by 프로그래머 (1)
  24. 2008/09/27 클립보드 복사 기능 구현을 위한 소스 코드 by 프로그래머 (1)
  25. 2008/09/16 홈페이지 동시접속자수 구현을 위한 PHP 소스 코드 by 프로그래머 (3)
  26. 2008/06/26 미리보기 이미지 썸네일 만들기 함수 PHP 소스 코드 by 프로그래머 (1)
  27. 2008/05/20 공개보드 게시물을 텍스트큐브 또는 태터툴즈로 복사하기. by 프로그래머 (1)
  28. 2008/05/16 PHP로 첨부파일이 있는 이메일 보내기 샘플 소스 코드 by 프로그래머 (1)
  29. 2008/05/15 삽질할 수 있는 PHP로 이메일 보내기 샘플 소스 코드 by 프로그래머
  30. 2008/03/26 자바스크립트 createElement, insertBefore, replaceChild, appendChild by 프로그래머 (1)
홈페이지 개발에서 색상 선택기를 만들어 붙여야 할 일이 드물기는 하지만 언제가는 필요할 때가 있으므로 jQuery 플러그인을 가져다가 입맛에 맞는 ColorPicker 를 만들어봅시다. 검색해본 여러가지 ColorPicker 플러그인 중에 이 것(http://www.eyecon.ro/colorpicker/)이 쓸만해 보여서 약간 불편한 부분과 IE6에서 화면이 깨지는 부분을 수정한 후 예제를 만들어 봤습니다. 아래는 색상 선택기 예제 실행 화면이고 하단에는 예제 소스 코드입니다.

[jQuery 색상 선택기 (ColorPicker) 예제 실행 화면]
http://www.hompydesign.com/javascript/colorpicker/
사용자 삽입 이미지

[jQuery 색상 선택기 (ColorPicker) 예제 소스 코드]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Color Picker</TITLE>
<link rel="stylesheet" href="./colorpicker.css" type="text/css" />
<link rel="stylesheet" href="./index.css" type="text/css" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="./colorpicker.js"></script>
<script>
$(document).ready(function(){
    $('#colorpicker_0,#colorpicker_1,#colorpicker_2,#colorpicker_3,#colorpicker_4').ColorPicker({
        onSubmit: function(hsb, hex, rgb, el) {
            check_colorpicker(el, hex);
        },
        onBeforeShow: function () {
            $(this).ColorPickerSetColor(this.value);
        },
        onChange: function (hsb, hex, rgb, el) {
        }
    })
    .bind('keyup', function(){
        $(this).ColorPickerSetColor(this.value);
    });
    $('.colorpicker_holder').each(function(){
        var el = $(this).parent().find("input");
        var color = el.val().toUpperCase();
        el.val(color);
        $(this).css("backgroundColor", "#"+color );
        $(this).click(function(){
            $(this).parent().find("input").ColorPickerShow();
        });
    });
});
function check_colorpicker(el, hex){
    $(el).val(hex.toUpperCase());
    $(el).ColorPickerHide();
    $(el).parent().parent().find(".colorpicker_holder").css('backgroundColor', '#' + hex);
    var pos = el.id;
}
</script>
</HEAD>
<BODY>
...
</BODY>
</HTML>


웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/588

Posted by 프로그래머

2009/10/10 22:49 2009/10/10 22:49

간단한 시계 가젯을 만들어 보겠습니다. 우선 구글에 로그인하고 구글 가젯 에디터(Google Gadget Editor) 정보 페이지에서 "바로 추가" 버튼을 클릭하면 아이구글(iGoogle)에 가젯을 편집할 수 있는 위젯이 추가 됩니다. 에디터에 아래 보이는 시계 가젯 소스를 입력한 후 적당한 파일명(simpleclock.xml)으로 저장(Save) 하고 발행(Publish) 버튼을 누릅니다.

사용자 삽입 이미지

그리고 "Add to my iGoogle page" 링크를 클릭하면 발행한 가젯을 내 아이구글 페이지에 붙일 수 있습니다. "Publish to iGoogle Directory" 링크를 클릭하면 아이구글 가젯 디렉토리에 발행할 수 있습니다. "Add to a webpage" 링크를 클릭하면 네 홈페이지나 블로그로 가져와서 붙일 수 있는 코드를 생성해 주는 페이지로 이동합니다. 바로 아래 보이는 시계는 완성된 가젯의 코드를 가져와 본 게시물에 코드를 추가해서 보여지는 것입니다. 구글 가젯 개발에 관심이 있는 분은 구글 가젯 API 개발 페이지에서 관련 정보를 확인해보세요.

[시계 가젯 코드 가져와서 띄운 화면]

[시계 가젯을 만들기 위한 소스 코드]
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="HOMPY CLOCK" directory_title="HOMPY CLOCK" description="HOMPY CLOCK" category="tools" screenshot="http://www.hompydesign.com/images/gadget/simpleclock.jpg" thumbnail="http://www.hompydesign.com/images/gadget/simpleclock.jpg" title_url="hompy.info/584" author="hompy" author_email="hompy.info@gmail.com" author_link="http://hompy.info/584" author_location="Korea, Seoul" author_affiliation="hompydesign.com" width="180" height="48" scrolling="false" author_aboutme="web programmer" />
<UserPref name="bgcolor" display_name="배경색" default_value="#99aa99"/>
<UserPref name="datecolor" display_name="날짜색" default_value="#ffffff"/>
<UserPref name="timecolor" display_name="시간색" default_value="darkgreen"/>
<Content type="html">
<![CDATA[
<div id="my_content">
<div id="my_date"></div>
<div id="my_clock"></div>
</div>
<style>
#my_content { font-size : 12px; padding : 5px; background-color:#99aa99;}
#my_date {font-family:verdana,돋음; font-size : 11px; color : #ffffff; padding : 2px; text-align : left; }
#my_clock {font-family:verdana,돋음; font-size : 14px; color : darkgreen; padding : 2px; text-align : center; font-weight : bold; background-color:#ffffff; }
</style>

<script type="text/javascript">
var prefs = new gadgets.Prefs();
function init_clock() {
      var params = {};
      var bgcolor, datecolor, timecolor;
      params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;
      params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = 10 * 60;
      bgcolor = prefs.getString("bgcolor");
      datecolor = prefs.getString("datecolor");
      timecolor = prefs.getString("timecolor");
      document.getElementById('my_content').style.backgroundColor = bgcolor;
      document.getElementById('my_date').style.color = datecolor;
      document.getElementById('my_clock').style.color = timecolor;
      print_hour();
      window.setInterval("print_hour()", 100);
}

function print_hour(){
      var today = new Date();
      var year = today.getFullYear();
      var month = today.getMonth()+1;
      var date = today.getDate();
      var hour = today.getHours();
      var min = today.getMinutes();
      var sec = today.getSeconds();
      document.getElementById('my_date').innerHTML = year + '-' + get_number_str(month) + '-' + get_number_str(date);
      document.getElementById('my_clock').innerHTML = get_number_str(hour) + ':' + get_number_str(min) + ' ' + get_number_str(sec);
}

function get_number_str(num){
      if (num<10) num = '0' + num;
      return num;
}

gadgets.util.registerOnLoadHandler(init_clock);
</script>
]]>
</Content>
</Module>

[구글 가젯 에디터]

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/584

Posted by 프로그래머

2009/07/05 17:03 2009/07/05 17:03
, , , , , , , , ,
Response
No Trackback , No Comment
RSS :
http://hompy.info/rss/response/584

야후 세계 지도 API 를 활용해서 지도를 만드는 비교적 간단한 샘플입니다. 아래 소개된 소스 코드를 실행하면 100개의 마커가 뿌려지고 해당 마커를 클릭하면 이미지를 보여주는 다음과 같은 실행 화면을 확인할 수 있습니다. 자신의 홈페이지에서 테스트 하기 위해서는 야후 거기 지도 오픈 API 키를 해당 홈페이지 (http://kr.open.gugi.yahoo.com/Regist/regist.php) 에서 얻을 수 있으며 키 값($yahoo_map_api_key)을 얻은 API 키로 교체해야 합니다. 참고로 구글 지도 API에도 관심이 있는 분은 앞서 소개한 "자바스크립트로 지도 만들기, 구글 지도 API 매시업(Mashup)" 포스트도 참고하세요.

[실행 화면] http://www.hompydesign.com/map/yahoo.html


[소스 코드]
<HTML>
<HEAD>
<TITLE><?=$hompy_title?></TITLE>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="http://kr.open.gugi.yahoo.com/Client/AjaxMap.php?v=3.7&appid=$yahoo_map_api_key"></script>
<style type="text/css">

#map_box {position:relative;}
#map_canvas { width: 578px; height: 460px; margin: 0; padding: 0; border: 0; }

#map_box {width:578px; border: 4px solid #cccccc; padding:2px;}
#display_loading_box {width:578px; height:460px; position:absolute; background-color:#000000; z-index:1000; opacity: 0.5; filter: alpha(opacity = 50);}
#display_loading_box_icon {margin: 214px 273px; width:32px; height:32px;}

body,td,tr { font-size:12px; font-family:돋움,verdana,arial,sans serif;}

.window_image {border:1px solid #cccccc; width:140px; height:100px; margin:6px;}

</style>
<script type='text/javascript'>
<!--

var map = null;
var current_lon = 127.046;
var current_lat = 37.5066;
var current_zoom = 14;
var person_list = [];

$(document).ready(function(){
      display_loading();
      map = new YMap($("#map_canvas")[0]);

      map.addTypeControl();
      map.addZoomLong();
      map.addPanControl();
      //map.drawZoomAndCenter(encodeURIComponent("강남역"), 4);
      map.drawZoomAndCenter(new YGeoPoint(current_lat,current_lon), 4);
      map.setMapType(YAHOO_MAP_REG);

      display_marker({user:0,lat:current_lat,lon:current_lon});
      for (record in person_list) {
            display_marker(person_list[record]);
      }
      setTimeout(display_loaded, 1000);
});

function display_loading(){
      var html = "<div id='display_loading_box'><img src='images/loading.gif' id='display_loading_box_icon' /></div>";
      $('#map_canvas').before(html);
}

function display_loaded(){
      $('#display_loading_box').remove();
}

function display_marker(record){
      with (record) {
            var point = new YGeoPoint(Number(lat),Number(lon));
            var marker = create_marker(point, user);
      }
      map.addOverlay(marker);
      //map.setCenter(point, current_zoom, G_NORMAL_MAP);
}

function create_marker(point, person) {
      var icon = new YImage();
      icon.src = 'images/pot.png';;
      icon.size = new YSize(36, 36);
      icon.offset.x = -18; icon.offset.y = 0;      

      var marker= new YMarker(point, icon);
      //marker.addAutoExpand("pos:"+person);
      var html = '<a href="http://hompy.info/583"><img src="/hompydesign.com?seq='+person+'" class="window_image"></a>';
      YEvent.Capture(marker, EventsList.MouseClick, function(){
            marker.openSmartWindow(html);
      });
      return marker;
}

person_list =
[{user:1,lon:127.034,lat:37.5059},{user:2,lon:127.029,lat:37.5125},{user:3,lon:127.032,lat:37.5306},{user:4,lon:127.034,lat:37.4994},{user:5,lon:127.036,lat:37.5169}];

-->
</script>
</HEAD>

<BODY>
<div id="map_box">
<div class="map" id="map_canvas"></div>
</div>
</BODY>
</HTML>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/583

Posted by 프로그래머

2009/06/26 20:51 2009/06/26 20:51
, , , , , , , , ,
Response
No Trackback , a comment
RSS :
http://hompy.info/rss/response/583

다음 지도 API 를 활용해서 지도를 만드는 비교적 간단한 샘플입니다. 아래 소개된 소스 코드를 실행하면 100개의 마커가 뿌려지고 해당 마커를 클릭하면 이미지를 보여주는 다음과 같은 실행 화면을 확인할 수 있습니다. 자신의 홈페이지에서 테스트 하기 위해서는 다음 지도 API 키를 해당 홈페이지 (https://apis.daum.net/register/mapsapi.daum) 에서 얻을 수 있으며 키 값($daum_map_api_key)을 얻은 API 키로 교체해야 합니다. 참고로 구글 지도 API에도 관심이 있는 분은 앞서 소개한 "자바스크립트로 지도 만들기, 구글 지도 API 매시업(Mashup)" 포스트도 참고하세요.

[실행 화면] http://www.hompydesign.com/map/daum.html


[소스 코드]
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE><?=$hompy_title?></TITLE>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="http://apis.daum.net/maps/maps.js?apikey=<?=$daum_map_api_key;?>" charset="utf-8"></script>
<style type="text/css">

#map_box {position:relative;}
#map_canvas { width: 578px; height: 460px; margin: 0; padding: 0; border: 0; }

#map_box {width:578px; border: 4px solid #cccccc; padding:2px;}
#display_loading_box {width:578px; height:460px; position:absolute; background-color:#000000; z-index:1000; opacity: 0.5; filter: alpha(opacity = 50);}
#display_loading_box_icon {margin: 214px 273px; width:32px; height:32px;}

body,td,tr { font-size:12px; font-family:돋움,verdana,arial,sans serif;}

.window_image {border:1px solid #cccccc; width:140px; height:100px; margin:6px;}

</style>
<script type='text/javascript'>
<!--

var map = null;
var current_lon = 127.046;
var current_lat = 37.5066;
var current_zoom = 14;
var person_list = [];

$(document).ready(function(){
      display_loading();
      map = new DMap("map_canvas");
      map.setCenter(new DLatLng(current_lat, current_lon), 4);
      //map.addControl(new DIndexMapControl());
      map.addControl(new DZoomControl());

      display_marker({user:0,lat:current_lat,lon:current_lon});
      for (record in person_list) {
            display_marker(person_list[record]);
      }
      setTimeout(display_loaded, 1000);
});

function display_loading(){
      var html = "<div id='display_loading_box'><img src='images/loading.gif' id='display_loading_box_icon' /></div>";
      $('#map_canvas').before(html);
}

function display_loaded(){
      $('#display_loading_box').remove();
}

function display_marker(record){
      var icon = new DIcon("http://localimg.daum-img.net/localimages/07/2008/map/i_mks_b1.gif", new DSize(13, 16));
      var point = new DLatLng(Number(record.lat),Number(record.lon));
      var marker = create_marker(point, record.user);
      map.addOverlay(marker, {mark:icon});
      //map.addOverlay(marker);
}

function create_marker(point, person) {
      var html = '<a href="http://hompy.info/582"><img src="/hompydesign.com?seq='+person+'" class="window_image"></a>';
      var marker= new DMark(point, { infowindow : new DInfoWindow(html), draggable : false });
      //marker.addAutoExpand("pos:"+person);
      return marker;
}

person_list =
[{user:1,lon:127.034,lat:37.5059},{user:2,lon:127.029,lat:37.5125},{user:3,lon:127.032,lat:37.5306},{user:4,lon:127.034,lat:37.4994},{user:5,lon:127.036,lat:37.5169}];

-->
</script>
</HEAD>

<BODY>
<div id="map_box">
<div class="map" id="map_canvas"></div>
</div>
</BODY>
</HTML>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/582

Posted by 프로그래머

2009/06/25 21:13 2009/06/25 21:13
, , , , , , , , ,
Response
No Trackback , 2 Comments
RSS :
http://hompy.info/rss/response/582

네이버 지도 API 를 활용해서 지도를 만드는 비교적 간단한 샘플입니다. 아래 소개된 소스 코드를 실행하면 100개의 마커가 뿌려지고 해당 마커를 클릭하면 이미지를 보여주는 다음과 같은 실행 화면을 확인할 수 있습니다. 자신의 홈페이지에서 테스트 하기 위해서는 네이버 지도 API 키를 해당 홈페이지 (http://dev.naver.com/openapi/register) 에서 얻을 수 있으며 키 값($naver_map_api_key)을 얻은 API 키로 교체해야 합니다. 참고로 구글 지도 API에도 관심이 있는 분은 앞서 소개한 "자바스크립트로 지도 만들기, 구글 지도 API 매시업(Mashup)" 포스트도 참고하세요.

[실행 화면] http://www.hompydesign.com/map/naver.html


[소스 코드]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><?=$hompy_title?></title>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="http://map.naver.com/js/naverMap.naver?key=<?=$naver_map_api_key?>"></script>
<style type="text/css">

#map_box {position:relative;}
#map_canvas { width: 578px; height: 460px; margin: 0; padding: 0; border: 0; }

#map_box {width:578px; border: 4px solid #cccccc; padding:2px;}
#display_loading_box {width:578px; height:460px; position:absolute; background-color:#000000; z-index:1000; opacity: 0.5; filter: alpha(opacity = 50);}
#display_loading_box_icon {margin: 214px 273px; width:32px; height:32px;}

body,td,tr { font-size:12px; font-family:돋움,verdana,arial,sans serif;}

.window_image {border:1px solid #cccccc; width:140px; height:100px;}

</style>
<script type="text/javascript">

var map;
var tm128 = new NPoint(315741,544301);
var latlng;
var person_list;
var infowin;

$(document).ready(function(){
      display_loading();
      map = new NMap($('#map_canvas')[0],578,460);
      map.setCenterAndZoom(tm128, 4);
      //map.addControl(new NIndexMap());
      map.addControl(new NZoomControl());
      map.addControl(new NMapBtns());
      map.enableWheelZoom();
      for (record in person_list) {
            display_marker(person_list[record]);
      }
      display_marker({user:0,lon:127.046,lat:37.5066});
      map.setCenter(latlng);

      NEvent.addListener(map,"click",function (latlng){
            if (infowin) map.removeOverlay(infowin);
      });

      NEvent.addListener(map,"startDrag",function (latlng){
            if (infowin) map.removeOverlay(infowin);
      });
      setTimeout(display_loaded, 1000);
});

function transFromTM128ToLatLng() {
      latlng = map.fromTM128ToLatLng(tm128);
      document.getElementById("display").innerHTML = latlng;
}

function moveLatLng() {
      map.setCenter(latlng);
}

function display_marker(record) {
      latlng = new NLatLng(record.lat, record.lon);
      var marker = new NMark(latlng, new NIcon('http://static.naver.com/maps/ic_spot.png',new NSize(52,41),new NSize(14,40)));
      var html = '<a href="http://hompy.info/580"><img src="/hompydesign.com?seq='+record.user+'" class="window_image"></a>';
      map.addOverlay(marker);
      NEvent.addListener(marker,"click",function (latlng){
            if (infowin) map.removeOverlay(infowin);
            infowin = new NInfoWindow();
            map.addOverlay(infowin);
            infowin.set(latlng, "<TABLE style='width:100px;height:50px;background-color:#FFFFFF; border:solid 1px #666666'><TR><TD>"+html+"</TD></TR></TABLE>");
            infowin.showWindow();
            //NEvent.addListener(infowin,"mouseout",function () {infowin.hideWindow();});
      });
}

function display_loading(){
      var html = "<div id='display_loading_box'><img src='images/loading.gif' id='display_loading_box_icon' /></div>";
      $('#map_canvas').before(html);
}

function display_loaded(){
      $('#display_loading_box').remove();
}

person_list =
[{user:1,lon:127.034,lat:37.5059},{user:2,lon:127.029,lat:37.5125},{user:3,lon:127.032,lat:37.5306},{user:4,lon:127.034,lat:37.4994},{user:5,lon:127.036,lat:37.5169}];

</script>
</head>
<body>

<div id="map_box">
<div class="map" id="map_canvas"></div>
</div>

</body>
</html>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/581

Posted by 프로그래머

2009/06/24 20:41 2009/06/24 20:41
, , , , , , , , ,
Response
No Trackback , 4 Comments
RSS :
http://hompy.info/rss/response/581

구글 지도 API 를 활용해서 지도를 만드는 비교적 간단한 샘플입니다. 아래 소개된 소스 코드를 실행하면 100개의 마커가 뿌려지고 해당 마커를 클릭하면 이미지를 보여주는 다음과 같은 실행 화면을 확인할 수 있습니다. 자신의 홈페이지에서 테스트 하기 위해서는 구글 지도 API 키를 해당 홈페이지 (http://code.google.com/apis/maps/) 에서 얻을 수 있으며 키 값($google_map_api_key)을 얻은 API 키로 대입해야 합니다.

[실행 화면] http://www.hompydesign.com/map/


[소스 코드]
<HTML>
<HEAD>
<TITLE><?=$hompy_title?></TITLE>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=<?=$google_map_api_key?>"></script>
<style type="text/css">

#map_box {position:relative;}
#map_canvas { width: 578px; height: 460px; margin: 0; padding: 0; border: 0; }

#map_box {width:578px; border: 4px solid #cccccc; padding:2px;}
#display_loading_box {width:578px; height:460px; position:absolute; background-color:#000000; z-index:1000; opacity: 0.5; filter: alpha(opacity = 50);}
#display_loading_box_icon {margin: 214px 273px; width:32px; height:32px;}

body,td,tr { font-size:12px; font-family:돋움,verdana,arial,sans serif;}

</style>
<script type='text/javascript'>
<!--

var map = null;
var current_lon = 127.046;
var current_lat = 37.5066;
var current_zoom = 14;
var person_list = [];

$(document).ready(function(){
      display_loading();
      map = new google.maps.Map2($("#map_canvas")[0]);
      map.disableDoubleClickZoom();
      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      map.addControl(new GScaleControl());
      map.enableScrollWheelZoom();
      map.setCenter(new GLatLng(current_lat, current_lon), current_zoom);
      display_marker({user:0,lat:current_lat,lon:current_lon});
      for (record in person_list) {
            display_marker(person_list[record]);
      }
      setTimeout(display_loaded, 1000);
});

function display_loading(){
      var html = "<div id='display_loading_box'><img src='images/loading.gif' id='display_loading_box_icon' /></div>";
      $('#map_canvas').before(html);
}

function display_loaded(){
      $('#display_loading_box').remove();
}

function display_marker(record){
      with (record) {
            var point = new GLatLng(Number(lat),Number(lon));
            var marker = create_marker(point, user);
      }
      map.addOverlay(marker);
      //map.setCenter(point, current_zoom, G_NORMAL_MAP);
}

function create_marker(point, person) {
      var icon = new GIcon(G_DEFAULT_ICON);
      if (person) {
            icon.image = "images/marker"+(person%10)+".png";
            icon.iconSize = new GSize(20,34);
      }
      var marker = new GMarker(point,{'icon': icon});
      marker.person = person;
      GEvent.addListener(marker, "click", function() {
            marker.openInfoWindowHtml('<img src="/hompydesign.com?seq='+person+'" width=140 height=100>');
      });
      return marker;
}

person_list =
[{user:1,lon:127.034,lat:37.5059},{user:2,lon:127.029,lat:37.5125},{user:3,lon:127.032,lat:37.5306},{user:4,lon:127.034,lat:37.4994},{user:5,lon:127.036,lat:37.5169}];

-->
</script>
</HEAD>

<BODY>
<div id="map_box">
<div class="map" id="map_canvas"></div>
</div>
</BODY>
</HTML>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/580

Posted by 프로그래머

2009/06/21 12:52 2009/06/21 12:52
, , , , , , , , ,
Response
No Trackback , 8 Comments
RSS :
http://hompy.info/rss/response/580

자바스크립트 프레임워크 jQuery 를 활용해서 텍스트 입력 박스 (TextArea) 에 크기 조절 막대를 추가해 봅시다. 아래 소개한 소스를 실행하면 입력 박스 하단에 막대가 추가 되며 이 막대를 위 아래로 드래그 할 수 있으며 드래그 방향에 따라 텍스트 박스 크기를 늘리거나 줄일 수 있습니다.

[크기 조절 막대 예제 자바스크립트 소스 코드]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>TextArea Resize Demo</title>
<style type="text/css">
#in_content {width:511px; height:40px; border:1px solid #666666}
.resize_bar {background: url("images/resize_bar.gif"); cursor:s-resize; height:12px; width:100%;}
</style>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type='text/javascript'>
<!--
jQuery.fn.resizehandle = function() {
      return this.each(function() {
            var me = jQuery(this);
            me.after(
                  jQuery('<div class="resize_bar"></div>')
                        .bind('mousedown', function(e) {
                              var h = me.height();
                              var y = e.clientY;
                              var movehandler = function(e) {
                                    me.height(Math.max(40, e.clientY + h - y));
                              };
                              var uphandler = function(e) {
                                    jQuery('html').unbind('mousemove',movehandler)
                                          .unbind('mouseup',uphandler);
                              };
                              jQuery('html') .bind('mousemove', movehandler)
                                    .bind('mouseup', uphandler);
                        })
            );
      });
}
$(document).ready(function(){
      $("textarea").resizehandle();
});
</script>
</head>
<body>

<table cellspacing=0 cellpadding=0 border=0><tr><td>
<textarea name="in_content" id="in_content">아래 크기조절 막대를 이동해보세요.</textarea>
</td></tr></table>
</body>
</html>

[크기 조절 막대 예제 실행 결과]

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/577

Posted by 프로그래머

2009/06/07 11:54 2009/06/07 11:54

시간 차이를 계산하고 이를 출력하는 함수를 만들어 보고 이를 통해 시간 관련 함수 date, strtotime 사용법을 알아보도록 합시다. 아래 PHP 소스 코드는 사용자 정의 함수 datetimediff 를 호출해서 현재 시간 또는 특정 시간을 기준으로 참조 시간과의 시간차를 계산하고 출력합니다.

[시간 차이 계산 실행 결과]

2009-06-06 12:02:28
2009-06-06 09:11:04
2009-06-06 13:15:03
2시간 전
2시간 51분 24초 전
4시간 3분 59초 전

[시간 차이 계산 PHP 소스 코드]
<?

$ctime = date('Y-m-d H:i:s');
//$rtime = "1942-01-01 00:00:01";
//$rtime = "1941-05-19 09:00:00";
//$rtime = "20090606";
//$rtime = "20090606093924";
//$rtime = "2009-06-06 09:39:24";
$rtime = date('Y-m-d H:i:s', strtotime("-2 hours -51 minutes -24 seconds"));
$xtime = date('Y-m-d H:i:s', strtotime("+1 hours 12 minutes 35 seconds"));

echo
"$ctime<br>\n";
echo "$rtime<br>\n";
echo "$xtime<br>\n";

echo datetimediff($rtime) . "<br>\n";
echo datetimediff($rtime, null, "ALL") . "<br>\n";
echo datetimediff($rtime, $xtime, "ALL") . "<br>\n";

function datetimediff($rtime, $ctime = null, $option = null){
      if ($ctime) $cur_time = strtotime($ctime);
      else $cur_time = time();
      $ref_time = strtotime($rtime);

      $cur_date = floor($cur_time / 86400);
      $ref_date = floor($ref_time / 86400);

      $datetimediff = $cur_time - $ref_time;
      $datedist = $cur_date - $ref_date;
      $datediff = floor($datetimediff / 86400);
      $weekdiff = floor($datediff / 7);
      $timediff = $datetimediff % 86400;

      $hour = floor($timediff / 3600);
      $min = floor($timediff % 3600 / 60);
      $sec = floor($timediff % 3600 % 60);

      $result = "";
      if ($datedist>34) {
            $result = date("Y년 n월 j일", $ref_time);
      } else if ($weekdiff>0) {
            $result = $weekdiff . "주 전";
      } else {
            if ($datediff>0) {
                  $result = $datedist . "일 전";
            } else if ($timediff<=0) {
                  $result = "1초 전";
            } else {
                  if ($hour) $result = $hour . "시간";
                  else if ($min) $result = $min . "분";
                  else $result = $sec . "초";
                  if ($result) $result .= " 전";
            }
      }
      if ($option=='ALL') {
            $result = "";
            if ($datediff) $result .= ($result?" ":"") . $datediff."일";
            if ($hour) $result .= ($result?" ":"") . $hour."시간";
            if ($min) $result .= ($result?" ":"") . $min ."분";
            if ($sec) $result .= ($result?" ":"") . $sec . "초";
            $result .= " 전";
      }
      return $result;
}

?>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/576

Posted by 프로그래머

2009/06/06 12:05 2009/06/06 12:05

자바스크립트 프레임워크 라이브러리 jQuery의 애니메이션 관련 메소드를 이용해서 학습용 이미지 슬라이더와 전광판을 만들어 봤습니다. jQuery의 "animate()"라는 메소드로 개별 엘리먼트에 모션 이펙트를 부여할 수 있으며 자바스크립트 메소드인 "setInterval()" 를 이용해서 끊임없이 반복되는 애니메이션을 만들 수 있습니다. jQuery 의 "hover()" 이벤트 핸들러와 자바스크립트 "clearInterval()" 메소드를 활용해서 잠시 멈춤 효과를 만들 수 있지요. 추가로 "jQuery Easing v1.3"을 활용해서 다양한 이펙트 옵션을 테스트 할 수 있도록 했습니다. 하단부에 있는 옵션명을 클릭하면 개별 이펙트를 확인할 수 있습니다.

[전광판과 이미지 슬라이더 실행 화면]
http://www.hompydesign.com/javascript/animate/


[전광판과 이미지 슬라이더 소스 코드]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery Animate</title>
<link type="text/css" href="/ui/ui.all.css" rel="stylesheet" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/jquery.easing.1.3.js"></script>
<style type="text/css">
body {font-size: 12px; font-family:"Dotum", "Tahoma";}
img {border:0px;}
a:link {color:#3366CC; text-decoration:none;}
a:active {color:#FF9966; text-decoration:none;}
a:visited {color:#3366CC; text-decoration:none;}
a:hover {color:#FF9966; text-decoration:underline;}

.body {width:440px; height:280px; border:1px solid #CCCCCC; padding:10px; background-color:#FAFDE2}
#navi_tool {position:relative; width:400px; height:16px; overflow:hidden;}
#navi {position:absolute; left:0px; top:0px;}
#navi div {height:20px;}

#album_tool {position:relative; width:380px; height:120px; overflow:hidden;}
#album {position:absolute; width:2000px; left:0px; top:0px;}
#album div {float:left; margin:0px; padding:0px;}
</style>
<script type="text/javascript">
$(document).ready(function(){
    $("#navi").attr("motion", "easeInOutSine");
    $("#album").attr("motion", "easeInOutExpo")

    $("#navi").attr("top", "0");
    $("#album").attr("top", "0")

    $("#navi").attr("height", $("#navi>div").eq(0).height());
    $("#album").attr("width", $("#album>div").eq(0).width());

    $("#navi").attr("total", $("#navi>div").size());
    $("#navi>div").eq(0).clone().appendTo($("#navi"));
    $("#navi").hover(function(){
        clearInterval($("#navi").attr("timer"));
    },function(){
        $("#navi").attr("timer", setInterval(my_rotate, 3000));
        my_rotate();
    });
    $("#navi").attr("timer", setInterval(my_rotate, 3000));

    $("#album").attr("total", $("#album>div").size());
    $("#album>div").eq(0).clone().appendTo($("#album"));
    $("#album>div").eq(1).clone().appendTo($("#album"));
    $("#album").hover(function(){
        clearInterval($("#album").attr("timer"));
    },function(){
        $("#album").attr("timer", setInterval(my_album, 3000));
        my_album();
    });
    $("#album").attr("timer", setInterval(my_album, 3000));

    $("#motion_tool>a").click(function(){
        $("#navi").attr("motion", $(this).text());
        $("#album").attr("motion", $(this).text())
    });

});
function my_rotate(){
    if ($("#navi:animated").size()) return false;
    var height = $("#navi").attr("height");
    var pos = (parseInt($("#navi").attr("top"))+1);
    var px = pos * height;
    $("#navi").attr("top", pos);
    $("#navi").animate({
        top: ((px * -1) + "px")
    }, 1000, $("#navi").attr("motion"),
        function() {
            var pos = parseInt($("#navi").attr("top"));
            var total = parseInt($("#navi").attr("total"));
            if (pos>=total) {
                $("#navi").attr("top", 0);
                $("#navi").css("top", "0px");
            }
        }
    );
}
function my_album(){
    if ($("#album:animated").size()) return false;
    var width = $("#album").attr("width");
    var pos = (parseInt($("#album").attr("top"))+1);
    var px = pos * width;
    $("#album").attr("top", pos);
    $("#album").animate({
        left: ((px * -1) + "px")
    }, 1000, $("#album").attr("motion"),
        function() {
            var pos = parseInt($("#album").attr("top"));
            var total = parseInt($("#album").attr("total"));
            if (pos>=total) {
                $("#album").attr("top", 0);
                $("#album").css("left", "0px");
            }
        }
    );
}
</script>
</head>
<body>
<div class="body">
<div class="demo">
<div id="navi_tool">
    <div id="navi">
        <div><a href="http://hompy.info/574" target="_blank">1. jQuery 애니메이트로 만들어보는 이미지 슬라이더와 전광판</a></div>
        <div><a href="http://hompy.info/569" target="_blank">2. 심심풀이용 플래시 타워 디펜스 게임들과 플레이 동영상</a></div>
        <div><a href="http://hompy.info/570" target="_blank">3. 잘만든 인기 플래시 게임 버블탱크2와 젬크래프트</a></div>
        <div><a href="http://hompy.info/571" target="_blank">4. 포털에서 운영하는 채용정보 검색, 취업 검색, 취업 센터</a></div>
        <div><a href="http://hompy.info/572" target="_blank">5. jQuery를 활용한 홈페이지 개발의 기본인 입력폼 제작</a></div>
    </div>
</div>
<br />
<div id="album_tool">
    <div id="album">
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=1' width=190></a></div>
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=2' width=190></a></div>
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=3' width=190></a></div>
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=4' width=190></a></div>
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=5' width=190></a></div>
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=6' width=190></a></div>
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=7' width=190></a></div>
        <div><a href="http://hompy.info/24" target="_blank"><img src='http://www.hompydesign.com/hompydesign.com?no=8' width=190></a></div>
    </div>
</div>
<br />
<div id="motion_tool">
<a href="#">easeInQuad</a>
<a href="#">easeOutQuad</a>
<a href="#">easeInOutQuad</a>
<a href="#">easeInCubic</a>
<a href="#">easeOutCubic</a>
<a href="#">easeInOutCubic</a>
<a href="#">easeInQuart</a>
<a href="#">easeOutQuart</a>
<a href="#">easeInOutQuart</a>
<a href="#">easeInQuint</a>
<a href="#">easeOutQuint</a>
<a href="#">easeInOutQuint</a>
<a href="#">easeInSine</a>
<a href="#">easeOutSine</a>
<a href="#">easeInOutSine</a>
<a href="#">easeInExpo</a>
<a href="#">easeOutExpo</a>
<a href="#">easeInOutExpo</a>
<a href="#">easeInCirc</a>
<a href="#">easeOutCirc</a>
<a href="#">easeInOutCirc</a>
<a href="#">easeInElastic</a>
<a href="#">easeOutElastic</a>
<a href="#">easeInOutElastic</a>
<a href="#">easeInBack</a>
<a href="#">easeOutBack</a>
<a href="#">easeInOutBack</a>
<a href="#">easeInBounce</a>
<a href="#">easeOutBounce</a>
<a href="#">easeInOutBounce</a>
</div>
</div>
</body>
</html>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/574

Posted by 프로그래머

2009/03/22 17:48 2009/03/22 17:48

jQuery 자바스크립트 프레임워크 라이브러리를 이용하면 홈페이지 만들기의 기본인 입력폼을 비교적 손쉽게 만들 수 있습니다. 물론 단순한 양식 뿐만 아니라 입력 값이 유효한지 점검한다던지 날짜를 손쉽게 입력할 수 있도록 달력을 뿌려준다거나 새창 팝업 대신 레이어 팝업창을 손쉽게 띄워주고 있습니다. 그리고 파일 업로드 버튼을 이미지로 처리하는 부분과 버튼의 색이 바뀌고 입력창 크기를 조절하는 간단한 액션을 추가해서 생동감을 심어주는 부분도 있습니다. 아래 동영상을 보면 어떤 모습인지 확인 할 수 있고 이 영상은 동영상 아래 보이는 소스를 실행한 것입니다. 이에 대해 관심이 있는 분들은 jQuery 홈페이지에 있는 문서들을 참고하세요.



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="author" content="웹프로그래머" />
<meta name="description" content="홈페이지 정보 블로그" />
<meta name="keywords" content="자바스크립트,jQuery,JavaScript,UI,datepicker,dialog,validate,filestyle,effects" />
<meta name="classification" content="자바스크립트,jQuery,JavaScript,UI,datepicker,dialog,validate,filestyle,effects" />
<title>홈페이지 정보 블로그 데모</title>
<link type="text/css" href="/theme/ui.all.css" rel="stylesheet" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/jquery.bgiframe.js"></script>
<script type="text/javascript" src="/js/jquery.validate.js"></script>
<script type="text/javascript" src="/js/jquery.filestyle.js"></script>
<script type="text/javascript" src="/ui/ui.core.js"></script>
<script type="text/javascript" src="/ui/ui.datepicker.js"></script>
<script type="text/javascript" src="/ui/ui.draggable.js"></script>
<script type="text/javascript" src="/ui/ui.resizable.js"></script>
<script type="text/javascript" src="/ui/ui.dialog.js"></script>
<script type="text/javascript" src="/ui/effects.core.js"></script>
<style type="text/css">
* { margin: 0; padding: 0; vertical-align: middle; }
a:link {color:#3366CC; text-decoration:none;}
a:active {color:#FF9966; text-decoration:none;}
a:visited {color:#3366CC; text-decoration:none;}
a:hover {color:#FF9966; text-decoration:underline;}
img { border: 0; }
body {font-family:돋움, verdana, arial, helvetica, sans-serif; font-size:12px; padding:10px;}

label {font-family:돋움, verdana, arial, helvetica, sans-serif; font-size:11px;}
label.error { float: none; color: red;       background: url('/images/icon_alert.gif') no-repeat left; padding-left:16px; padding-top:1px;}

.my_input_text { border-color:#999999; border-width: 1px; border-style:solid; font-size:12px; padding:2px 1px 1px;; background-color:#F9F9F9;}
.my_input_text.error { border-color:#FFC22B; background-color:#FFEDD6; }
.my_input_select { font-size:12px; background-color:#F9F9F9;}
.my_input_select.error { background-color:#FFEDD6; }
.my_input_check { background-color:#FFFFFF; }
.my_input_check.error { background-color:#FFFFFE; }

#my_title {font-size:14px; float:left;}
#my_content {padding:10px; width:430px; border-color:#EFEFEF; border-width: 3px; border-style:solid;}
#my_dialog {display:none}
#dialog_link {float:right; font-size:11px; padding-top:4px;}
#in_date {width:80px; margin-right:2px;}
#in_title {width:350px;}
#in_content {width:400px; height:60px;}
#in_form {magin:0px;}

.my_line {height:1px; background-color:#EFEFEF;}
.my_line2 {height:2px; background-color:#C4D2E2;}

#bt_submit {border:0px solid #EFEFEF; color:white; background-color:#666666; font-size:12px; padding:2px; cursor:pointer;}
#bt_reset {border:0px solid #EFEFEF; color:white; background-color:#666666; font-size:12px; padding:2px; cursor:pointer;}

#bt_plus_height {cursor:pointer; border:0px;}
#bt_minus_height {cursor:pointer; border:0px;}

.ui-datepicker-calendar td {padding:1px;}
.ui-datepicker-trigger {cursor:pointer;}
</style>
<script type="text/javascript">
$.validator.addMethod("alphanumeric", function(value, element) {
return this.optional(element) || /^\w[\w\s]*$/.test(value);
}, "알파벳이나 숫자를 입력하세요.");

$.validator.addMethod("mbmaxlength", function(value, element, param) {
      return this.optional(element) || value.length+(escape(value)+"%u").match(/%u/g).length-1<=param;
}, "글자수가 초과 되었습니다.");

$.ui.dialog.defaults.bgiframe = true;

$(document).ready(function(){
      $("#in_file").filestyle({
            image: "/images/icon_filefind.gif",
            imageheight : 20,
            imagewidth : 66,
            width : 284
      });

      $('#dialog').dialog({
            autoOpen: false,
            width: 360,
            modal: true,
            bgiframe: true,
            overlay: { backgroundColor: '#000', opacity: 0.5 },
            buttons: {
                  "확인": function() {
                        $(this).dialog("close");
                  },
                  "닫기": function() {
                        $(this).dialog("close");
                  }
            }
      });

      $('#dialog_link').click(function(){
            $('#dialog').dialog('open');
            return false;
      });

      $("#in_date").datepicker({
            maxDate: '+30d',
            minDate: '-0d',
            monthNames: ['년 1월','년 2월','년 3월','년 4월','년 5월','년 6월','년 7월','년 8월','년 9월','년 10월','년 11월','년 12월'],
            dayNamesMin: ['일', '월', '화', '수', '목', '금', '토'],
            showMonthAfterYear:true,
            showOn: "both",
            showAnim: "show",
            showOptions: {},
            duration: 200,
            dateFormat: 'yy-mm-dd',
            buttonImage: "/ui/images/calendar.gif",
            buttonText: '달력',
            buttonImageOnly: true,
            onSelect: function(date) {
                  var date_arr = date.split('-');
                  if (date_arr.length==3){
                        var date_str = date_arr[0]+'년 '+date_arr[1]+'월 '+date_arr[2]+'일';
                        $("#span_in_last_date").html(date_str);
                  }
            },
            onClose: function(dateText) {
                  $('#in_date').valid();
            }
      })

$("#in_form").validate({
            submitHandler: function(form) {
                  if (!confirm("저장하겠습니까?")) return false;
                  form.submit();
                  return true;
            },
            rules: {
                  in_format: { required: true },
                  in_open: { required: true },
                  in_part: { required: true },
                  in_date: { required: true },
                  in_title: { required: true, minlength: 2, maxlength: 100 },
                  in_content: { required: true, minlength: 2, mbmaxlength: 8000 }
            },
            messages: {
                  in_format: { required: "형식을 선택하세요.<br>" },
                  in_open: { required: "공개방법을 선택하세요.<br>" },
                  in_part: { required: "말머리를 선택하세요.<br>" },
                  in_date: { required: "날짜를 입력하세요.<br>" },
                  in_title: {
                        required: "제목을 입력하세요.<br>",
                        minlength: "2자 이상으로 입력하세요.<br>",
                        maxlength: "100자 이하로 입력하세요.<br>"
                  },
                  in_content: {
                        required: "내용을 입력하세요.<br>",
                        minlength: "2자 이상으로 입력하세요.<br>",
                        mbmaxlength: "4000자 이하로 입력하세요.<br>"
                  }
            },
            errorPlacement: function(error, element) {
                  var er = element.attr("name");
                  error.appendTo( element.parent().find("span.my_error_display") );
            }
      });

      $('#bt_plus_height').click(function(){
            var h = parseInt($('#in_content').css("height"));
            if (h<400) $('#in_content').animate({height:h + 50},200,null);
      });

      $('#bt_minus_height').click(function(){
            var h = parseInt($('#in_content').css("height"));
            if (h>100) $('#in_content').animate({height:h - 50},200,null);
      });

      $("#bt_submit,#bt_reset").hover(
            function (){
                  $(this).stop();
                  $(this).animate({ backgroundColor: "#660000" }, 500);
            },
            function (){
                  $(this).stop();
                  $(this).animate({ backgroundColor: "#666666" }, 500);
            }
      );

});
</script>
</head>
<body>
<div id="my_container">

<div id="my_header">
</div>

<div id="my_sidebar">
</div>

<div id="my_content">
<form name="in_form" id="in_form" method="post" enctype="multipart/form-data">
<table id="my_table">
<tr><th colspan="2"><span id="my_title">자유게시판</span> <a href="#" id="dialog_link">도움말</a></th></tr>
<tr><td colspan="2" class="my_line2"></td></tr>
<tr><td>형식:</td><td><input type="checkbox" name="in_format" id="in_format" value="HTML" class="my_input_check" />HTML <input type="checkbox" name="in_format" id="in_format" value="BR" class="my_input_check" />BR <span class="my_error_display"></span></td></tr>
<tr><td colspan="2" class="my_line"></td></tr>
<tr><td>공개:</td><td><input type="radio" name="in_open" id="in_open" value="1" class="my_input_check" />전체 <input type="radio" name="in_open" id="in_sex" value="2" class="my_input_check" />일촌만 <span class="my_error_display"></span></td></tr>
<tr><td colspan="2" class="my_line"></td></tr>
<tr><td>말머리:</td><td>
<select name="in_part" id="in_part" class="my_input_select">
      <option value="">선택</option>
      <option value="1">잡담</option>
      <option value="2">의견</option>
      <option value="9">안내</option>
</select>
<span class="my_error_display"></span>
</td></tr>
<tr><td colspan="2" class="my_line"></td></tr>
<tr><td>날짜:</td><td><input type="text" name="in_date" id="in_date" class="my_input_text" readonly /> <span class="my_error_display"></span></td></tr>
<tr><td colspan="2" class="my_line"></td></tr>
<tr><td>파일:</td><td><span class="my_error_display"></span><input type="file" name="in_file" id="in_file" class="my_input_text" /></td></tr>
<tr><td colspan="2" class="my_line"></td></tr>
<tr><td>제목:</td><td><span class="my_error_display"></span><input type="text" name="in_title" id="in_title" class="my_input_text" /></td></tr>
<tr><td colspan="2" class="my_line"></td></tr>
<tr><td colspan="2">
      <img src="/images/icon_down.gif" id="bt_plus_height">
      <img src="/images/icon_up.gif" id="bt_minus_height">
</td></tr>
<tr><td colspan="2">
<span class="my_error_display"></span>
<textarea name="in_content" id="in_content" class="my_input_text"></textarea></td></tr>
<tr><td colspan="2"><input id='bt_submit' type="submit" value="저장" /> <input id="bt_reset" type="reset" value="취소" /></td></tr>
</table>
</form>
</div>

<div id="my_footer">
</div>

</div>

<div id="dialog" title="자유게시판 도움말">
자유게시판에 대해 설명합니다.
</div>

</body>

</html>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/572

Posted by 프로그래머

2009/03/09 09:06 2009/03/09 09:06

자바스크립트 라이브러리인 jQuery UI 위젯(Widgets)을 이용해서 달력(Calendar)과 날짜입력기(DatePicker)를 내 블로그나 홈페이지에 붙여 활용해보세요. 쓸만한 달력을 직접 만들려면 상당한 공을 드려야 하지만 jQuery UI 위젯을 활용하면 손쉽게 달력을 이용할 수 있을 뿐만 아니라 다양한 설정도 할 수 있으며 스킨도 비교적 손쉽게 교체할 수 있습니다. 하단 예제 소스 코드와 실행 화면을 참고하시면 사용법을 대략 짐작하실 수 있을 것입니다.
참고로 자바스크립트 프레임워크 라이브러리에는 Prototype, Script.aculo.us, jQuery, YUI, Dojo Toolkit, Ext JS, Google Web Toolkit, MooTools 등이 있습니다. 그리고 달력을 직접 제작해보려면 이전에 소개한 "PHP 또는 자바스크립트로 달력 만들기 소스 코드" 게시물을 참고하세요.

[jQuery UI 홈페이지]
http://ui.jquery.com/
http://ui.jquery.com/demos/datepicker

[jQuery UI DatePicker 실행 화면]
http://www.hompydesign.com/javascript/calendar/


[jQuery UI DatePicker 예제 소스 코드]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery UI Datepicker</title>
<link type="text/css" href="/ui/ui.all.css" rel="stylesheet" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/ui/ui.core.js"></script>
<script type="text/javascript" src="/ui/effects.core.js"></script>
<script type="text/javascript" src="/ui/effects.blind.js"></script>
<script type="text/javascript" src="/ui/effects.drop.js"></script>
<script type="text/javascript" src="/ui/effects.explode.js"></script>
<script type="text/javascript" src="/ui/ui.datepicker.js"></script>
<style>
body {font-size: 62.5%; font-family:"Dotum", "Tahoma";}
.body {width:440px; height:280px; border:1px solid #CCCCCC; padding:10px; background-color:#FAFDE2}
.demo {width:330px; border:1px solid #CCCCCC; padding:10px; background-color:#FFFFFF}
.text {font-size:12px; margin-right:4px; width:80px; line-height:20px;}
.datepicker_input1 {border:1px solid #999999; margin-right:4px; width:70px;}
.datepicker_input2 {border:1px solid #999999; margin-right:4px; width:70px;}
.datepicker1_div {margin-right:10px; float:left;}
</style>
<script type="text/javascript">
$.datepicker.setDefaults({
    //monthNames: ['년 1월','년 2월','년 3월','년 4월','년 5월','년 6월','년 7월','년 8월','년 9월','년 10월','년 11월','년 12월'],
    //dayNamesMin: ['일', '월', '화', '수', '목', '금', '토'],
    //showMonthAfterYear:true,
    dateFormat: 'yy-mm-dd',
    buttonImageOnly: true,
    buttonText: "달력",
    buttonImage: "/ui/images/calendar.gif"
});
$(document).ready(function(){
    $("#datepicker2").val($.datepicker.formatDate($.datepicker.ATOM, new Date(2009, 1 - 1, 18)));
    $("#datepicker1").datepicker({
        inline: true,
        defaultDate: new Date(2009, 1 - 1, 18),
        onSelect: function(date) { $("#datepicker2").val(date); }
    })
    $("#datepicker2").datepicker({
        defaultDate: new Date(2009, 1 - 1, 27),
        showOn: "both", // focus, button, both
        showAnim: "blind", // blind, clip, drop, explode, fold, puff, slide, scale, size, pulsate, bounce, highlight, shake, transfer
        showOptions: {direction: 'horizontal'},
        duration: 200
    })
    $("#datepicker3").datepicker({
        defaultDate: new Date(2009, 1 - 1, 28),
        showOn: "both", // focus, button, both
        showAnim: "drop", // blind, clip, drop, explode, fold, puff, slide, scale, size, pulsate, bounce, highlight, shake, transfer
        showOptions: {direction: 'horizontal'},
        duration: 200
    })
    $("#datepicker4").datepicker({
        defaultDate: new Date(2009, 1 - 1, 29),
        showOn: "button", // focus, button, both
        showAnim: "explode",
        showOptions: {pieces: 4},
        duration: 500
    })
    $(".datepicker_input2").datepicker({
        defaultDate: new Date(2009, 1 - 1, 30),
        showOn: "both", // focus, button, both
        showAnim: "show", // show, fadeIn, slideDown
        duration: 200
    })
});
</script>
</head>
<body>
<div class="body">
<div class="demo">
<div id="datepicker1" class="datepicker1_div" /></div>
<span class="text">날짜</span> <input type="text" id="datepicker2" class="datepicker_input1"><br />
<span class="text">날짜</span> <input type="text" id="datepicker3" class="datepicker_input1"><br />
<span class="text">날짜</span> <input type="text" id="datepicker4" class="datepicker_input1"><br />
<span class="text">날짜</span> <input type="text" class="datepicker_input2"><br />
</div>
<br />
<span class="text">
jQuery UI Datepicker<br />
jQuery UI 날짜 입력기<br />
jQuery UI Calendar, 달력<br />
</span>
</div>
</body>
</html>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/566

Posted by 프로그래머

2009/01/27 10:29 2009/01/27 10:29

아래 소개하고 있는 소스 코드는 스크립트 언어 PHP 또는 자바스크립트를 이용해 달력을 출력하는 비교적 간단한 웹프로그램입니다. 두가지 소스중 하나를 실행 시키면 아래와 같은 이미지 처럼 출력이 됩니다. 달력을 만들기 위해서는 그 달의 첫 날짜와 마지막 날짜를 계산해야 하며 요일에 따라 글자의 색을 변화 시켜 줘야 합니다. 이해를 돕기 위해 되도록 소스 코드를 단순화 시켰으므로 코드를 차근 차근 살펴보면 이해가 되리라 생각됩니다. 달력이 투박해 보인다면 좀더 세련되게 업그레이드 해보세요.^^

사용자 삽입 이미지

[PHP로 달력 만들기 소스 코드]
<?php
function calendar(){
    $year = date("Y");
    $month = date("n");
    $day = date("d");
    $day_max = date("t",mktime(0,0,0,$month,1,$year));
    $week_start = date("w",mktime(0,0,0,$month,1,$year));
    $i = 0;
    $j = 0;
    $html = "<div class='calendar_box'><div class='calendar_title B'>".sprintf("%d-%02d-%02d",$year,$month,$day)."</div>";
    while ($j<$day_max){
        if ($i<$week_start) {
            $html .= "<div class='calendar_text'>·</div>";
        } else {
            if ($i%7==0) $font_color = " RED";
            else if ($i%7==6) $font_color = " BLUE";
            else $font_color = "";
            if ($day == ($j+1)) $font_weight = " B"; else $font_weight = "";
            $html .= "<div class='calendar_text$font_color$font_weight'>" . ($j+1) . "</div>";
            $j ++;
        }
        $i ++;
    }
    while ($i%7!==0){
        $html .= "<div class='calendar_text'>·</div>";
        $i ++;
    }
    $html .= "<div class='calendar_tail'></div></div>";
    return $html;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
body {font-family: Verdana, Dotum; line-height:20px;}
.B {font-weight:bold}
.box {width:185px; text-align:center; border:1px solid #dddddd}
.calendar_box {width:175px; padding:5px}
.calendar_text {width:25px; float:left; text-align:center; font-size:12px}
.RED {color:red}
.BLUE {color:blue}
.calendar_title {margin:0px; text-align:center; font-size:12px; background-color:#999999; color:#ffffff}
.calendar_tail {clear:both;}
</style>
<title>PHP로 달력 만들기</title>
</head>
<body>
<div class="box">
<?=calendar();?>
</div>
</body>
</html>

[자바스크립트로 달력 만들기 소스 코드]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>자바스크립트로 달력 만들기</title>
<style>
body {font-family: Verdana, Dotum; line-height:20px;}
.B {font-weight:bold}
.box {width:185px; text-align:center; border:1px solid #dddddd}
.calendar_box {width:175px; padding:5px}
.calendar_text {width:25px; float:left; text-align:center; font-size:12px}
.RED {color:red}
.BLUE {color:blue}
.calendar_title {margin:0px; text-align:center; font-size:12px; background-color:#999999; color:#ffffff}
.calendar_tail {clear:both;}
</style>
<script>
function calendar(){
    var today = new Date();
    var year = today.getFullYear();
    var month = today.getMonth() + 1;
    var day = today.getDate();
    var week_start = new Date(year,month-1,1).getDay();
    var day_max = get_day_max(year,month-1);
    var i = 0;
    var j = 0;
    var html = "<div class='calendar_box'><div class='calendar_title B'>" + year + "-" + get_number_str(month) + "-" + get_number_str(day) + "</div>";
    while (j < day_max){
        if (i < week_start) {
            html += "<div class='calendar_text'>·</div>";
        } else {
            if (i%7==0) font_color = " RED";
            else if (i%7==6) font_color = " BLUE";
            else font_color = "";
            if (day == (j+1)) font_weight = " B"; else font_weight = "";
            html += "<div class='calendar_text" + font_color + font_weight + "'>" + (j+1) + "</div>";
            j ++;
        }
        i ++;
    }
    while (i%7!==0){
        html += "<div class='calendar_text'>·</div>";
        i ++;
    }
    html += "<div class='calendar_tail'></div></div>";
    return html;
}
function get_day_max(year,month){
    var i = 29, cday;
    while(i<32){
        cday = new Date(year,month,i);
        if (cday.getFullYear()!=year || cday.getMonth()!=month) break;
        i++;
    }
    return i-1;
}
function get_number_str(num){
    if (num<10) num = '0' + num;
    return num;
}
</script>
</head>
<body>
<div class="box">
<script>
document.write(calendar());
</script>
</div>
</body>
</html>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/565

Posted by 프로그래머

2009/01/26 15:08 2009/01/26 15:08
, , , , , , ,
Response
No Trackback , 5 Comments
RSS :
http://hompy.info/rss/response/565

PHP 스크립트 API를 지원하는 스핑크스(Sphinx) Full-Text 검색엔진으로 텍스트큐브 블로그 검색을 구현하는 샘플 소스 코드입니다. 예제를 테스트 해보면 알 수 있지만 MySQL과 같은 데이타베이스만으로 구현한 검색 보다 검색 속도가 빨라지고 검색 속도 걱정 없이 복수 검색어 키워드(Keyword)를 사용할 수 있고 다양한 검색 옵션을 적용할 수 있습니다. 그러나 검색 데몬을 띄울 수 있어야 하므로 개인 서버를 가지고 있어야 운영이 가능하며 포스트를 추가할 때마다 레코드 추가에 따른 주기적인 인덱싱(Indexing)을 하거나 증분에 대한 인덱싱을 별도로 해줘야 합니다.
아래 예제 소스와 관련 문서를 참고하고 오픈 소스 검색엔진 스핑크스를 활용해 블로그와 홈페이지 검색의 성능을 높이고 더불어 검색 쿼리 요청으로 발행하는 데이타베이스 서버의 부담을 줄여보세요.

[블로그 검색 테스트]
http://www.hompydesign.com/blog/find/

[스핑크스 검색 엔진 참고 문서]
http://www.sphinxsearch.com/docs/current.html

[blog_search.php]
<?php
header("Content-Type: text/html; charset=UTF-8");
require("sphinxapi.php");
$conn = mysql_connect("192.168.0.11", "blog", "password");
if ($conn) {
    mysql_select_db("blog", $conn);
    mysql_query("set names utf8", $conn);
}

$host = "192.168.0.41";
$port = 3312;
$index = "blog_search";

$q = $_POST[q];
$limit = 10;
$sortby = "@id DESC";
$mode = SPH_MATCH_ANY; //$mode = SPH_MATCH_ALL; //$mode = SPH_MATCH_PHRASE;
$ranker = SPH_RANK_PROXIMITY_BM25;

$cl = new SphinxClient ();
$cl->SetServer ( $host, $port );
$cl->SetConnectTimeout ( 1 );
$cl->SetMatchMode ( $mode );
if ( $sortby ) $cl->SetSortMode ( SPH_SORT_EXTENDED, $sortby );
if ( $limit ) $cl->SetLimits ( 0, $limit, ( $limit>1000 ) ? $limit : 1000 );
$cl->SetArrayResult ( true );
$res = $cl->Query ( $q, $index );
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>검색 테스트</title>
<style>
body {font-size:12px;}
form {margin:0px;}
</style>
</head>
<body>
<form method=post>
<input type=text name="q" value="<?=$q;?>" style="width:400px">
<input type="submit" value="검색"><br>
</form>
<?
if ( $res===false ){
    print "질의 실패: " . $cl->GetLastError() . ".<br />\n";
    exit;
}
if ( $cl->GetLastWarning() ) print "경고: " . $cl->GetLastWarning() . "<br />\n<br />\n";
print "'$q' 검색 결과 $res[total] 건 / $res[total_found] 건, 검색 시간 $res[time] 초.<br />\n";
print "<br />\n";
if ( is_array($res["matches"]) ){
    $n = 1;
    foreach ( $res["matches"] as $doc => $docinfo ) {
        $idz[] = $docinfo[id]; $n++;
    }
    $query = "select * from tt_Entries where id in(". implode(',', $idz) .")";
    $result = mysql_query($query);
    if ($result)
    while ($row = mysql_fetch_array($result)) {
        echo "{$row[id]} : {$row[title]}<br>";
        echo mb_substr(strip_tags($row[content]),0,512,"UTF-8");
        echo "<br><br>";
    }
}
?>
</body>
</html>

[/usr/local/etc/sphinx.conf]
source blog_search
{
    type = mysql

    sql_host = 192.168.0.11
    sql_user = blog
    sql_pass = password
    sql_db     = blog
    sql_port = 3306 # optional, default is 3306

    sql_query_pre = SET NAMES utf8
    sql_query_pre = SET CHARACTER SET UTF8


    sql_query_range = SELECT MIN(id),MAX(id) FROM tt_Entries
    sql_range_step = 128

    sql_query = \
    SELECT id, title, content, slogan, comments, published, created, modified FROM tt_Entries \
    WHERE blogid=1 AND userid=1 AND draft=0 AND visibility AND id>=$start AND id<=$end

    sql_attr_uint = comments
    sql_attr_timestamp = published
    sql_attr_timestamp = created
    sql_attr_timestamp = modified
    sql_attr_str2ordinal = slogan

    sql_query_info = SELECT * FROM tt_Entries WHERE id=$id
}

index blog_search
{
    source = blog_search
    path = /home/blog/sphinx/blog_search
    docinfo = extern

    mlock = 0
    morphology = none
    min_word_len = 1
    charset_type = utf-8
    min_prefix_len = 0
    min_infix_len = 2
    enable_star = 1
    ngram_len = 0
    html_strip = 0

    charset_table = \
U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z, A..Z->a..z, a..z, \
U+F900->U+8C48, U+F901->U+66F4, U+F902->U+8ECA, U+F903->U+8CC8, U+F904->U+6ED1, \
U+F905->U+4E32, U+F906->U+53E5, U+F907->U+9F9C, U+F908->U+9F9C, U+F909->U+5951, \
U+F90A->U+91D1, U+F90B->U+5587, U+F90C->U+5948, U+F90D->U+61F6, U+F90E->U+7669, \
U+F90F->U+7F85, U+F910->U+863F, U+F911->U+87BA, U+F912->U+88F8, U+F913->U+908F, \
U+F914->U+6A02, U+F915->U+6D1B, U+F916->U+70D9, U+F917->U+73DE, U+F918->U+843D, \
U+F919->U+916A, U+F91A->U+99F1, U+F91B->U+4E82, U+F91C->U+5375, U+F91D->U+6B04, \
U+F91E->U+721B, U+F91F->U+862D, U+F920->U+9E1E, U+F921->U+5D50, U+F922->U+6FEB, \
U+F923->U+85CD, U+F924->U+8964, U+F925->U+62C9, U+F926->U+81D8, U+F927->U+881F, \
U+F928->U+5ECA, U+F929->U+6717, U+F92A->U+6D6A, U+F92B->U+72FC, U+F92C->U+90CE, \
U+F92D->U+4F86, U+F92E->U+51B7, U+F92F->U+52DE, U+F930->U+64C4, U+F931->U+6AD3, \
U+F932->U+7210, U+F933->U+76E7, U+F934->U+8001, U+F935->U+8606, U+F936->U+865C, \
U+F937->U+8DEF, U+F938->U+9732, U+F939->U+9B6F, U+F93A->U+9DFA, U+F93B->U+788C, \
U+F93C->U+797F, U+F93D->U+7DA0, U+F93E->U+83C9, U+F93F->U+9304, U+F940->U+9E7F, \
U+F941->U+8AD6, U+F942->U+58DF, U+F943->U+5F04, U+F944->U+7C60, U+F945->U+807E, \
U+F946->U+7262, U+F947->U+78CA, U+F948->U+8CC2, U+F949->U+96F7, U+F94A->U+58D8, \
U+F94B->U+5C62, U+F94C->U+6A13, U+F94D->U+6DDA, U+F94E->U+6F0F, U+F94F->U+7D2F, \
U+F950->U+7E37, U+F951->U+964B, U+F952->U+52D2, U+F953->U+808B, U+F954->U+51DC, \
U+F955->U+51CC, U+F956->U+7A1C, U+F957->U+7DBE, U+F958->U+83F1, U+F959->U+9675, \
U+F95A->U+8B80, U+F95B->U+62CF, U+F95C->U+6A02, U+F95D->U+8AFE, U+F95E->U+4E39, \
U+F95F->U+5BE7, U+F960->U+6012, U+F961->U+7387, U+F962->U+7570, U+F963->U+5317, \
U+F964->U+78FB, U+F965->U+4FBF, U+F966->U+5FA9, U+F967->U+4E0D, U+F968->U+6CCC, \
U+F969->U+6578, U+F96A->U+7D22, U+F96B->U+53C3, U+F96C->U+585E, U+F96D->U+7701, \
U+F96E->U+8449, U+F96F->U+8AAA, U+F970->U+6BBA, U+F971->U+8FB0, U+F972->U+6C88, \
U+F973->U+62FE, U+F974->U+82E5, U+F975->U+63A0, U+F976->U+7565, U+F977->U+4EAE, \
U+F978->U+5169, U+F979->U+51C9, U+F97A->U+6881, U+F97B->U+7CE7, U+F97C->U+826F, \
U+F97D->U+8AD2, U+F97E->U+91CF, U+F97F->U+52F5, U+F980->U+5442, U+F981->U+5973, \
U+F982->U+5EEC, U+F983->U+65C5, U+F984->U+6FFE, U+F985->U+792A, U+F986->U+95AD, \
U+F987->U+9A6A, U+F988->U+9E97, U+F989->U+9ECE, U+F98A->U+529B, U+F98B->U+66C6, \
U+F98C->U+6B77, U+F98D->U+8F62, U+F98E->U+5E74, U+F98F->U+6190, U+F990->U+6200, \
U+F991->U+649A, U+F992->U+6F23, U+F993->U+7149, U+F994->U+7489, U+F995->U+79CA, \
U+F996->U+7DF4, U+F997->U+806F, U+F998->U+8F26, U+F999->U+84EE, U+F99A->U+9023, \
U+F99B->U+934A, U+F99C->U+5217, U+F99D->U+52A3, U+F99E->U+54BD, U+F99F->U+70C8, \
U+F9A0->U+88C2, U+F9A1->U+8AAA, U+F9A2->U+5EC9, U+F9A3->U+5FF5, U+F9A4->U+637B, \
U+F9A5->U+6BAE, U+F9A6->U+7C3E, U+F9A7->U+7375, U+F9A8->U+4EE4, U+F9A9->U+56F9, \
U+F9AA->U+5BE7, U+F9AB->U+5DBA, U+F9AC->U+601C, U+F9AD->U+73B2, U+F9AE->U+7469, \
U+F9AF->U+7F9A, U+F9B0->U+8046, U+F9B1->U+9234, U+F9B2->U+96F6, U+F9B3->U+9748, \
U+F9B4->U+9818, U+F9B5->U+4F8B, U+F9B6->U+79AE, U+F9B7->U+91B4, U+F9B8->U+96B8, \
U+F9B9->U+60E1, U+F9BA->U+4E86, U+F9BB->U+50DA, U+F9BC->U+5BEE, U+F9BD->U+5C3F, \
U+F9BE->U+6599, U+F9BF->U+6A02, U+F9C0->U+71CE, U+F9C1->U+7642, U+F9C2->U+84FC, \
U+F9C3->U+907C, U+F9C4->U+9F8D, U+F9C5->U+6688, U+F9C6->U+962E, U+F9C7->U+5289, \
U+F9C8->U+677B, U+F9C9->U+67F3, U+F9CA->U+6D41, U+F9CB->U+6E9C, U+F9CC->U+7409, \
U+F9CD->U+7559, U+F9CE->U+786B, U+F9CF->U+7D10, U+F9D0->U+985E, U+F9D1->U+516D, \
U+F9D2->U+622E, U+F9D3->U+9678, U+F9D4->U+502B, U+F9D5->U+5D19, U+F9D6->U+6DEA, \
U+F9D7->U+8F2A, U+F9D8->U+5F8B, U+F9D9->U+6144, U+F9DA->U+6817, U+F9DB->U+7387, \
U+F9DC->U+9686, U+F9DD->U+5229, U+F9DE->U+540F, U+F9DF->U+5C65, U+F9E0->U+6613, \
U+F9E1->U+674E, U+F9E2->U+68A8, U+F9E3->U+6CE5, U+F9E4->U+7406, U+F9E5->U+75E2, \
U+F9E6->U+7F79, U+F9E7->U+88CF, U+F9E8->U+88E1, U+F9E9->U+91CC, U+F9EA->U+96E2, \
U+F9EB->U+533F, U+F9EC->U+6EBA, U+F9ED->U+541D, U+F9EE->U+71D0, U+F9EF->U+7498, \
U+F9F0->U+85FA, U+F9F1->U+96A3, U+F9F2->U+9C57, U+F9F3->U+9E9F, U+F9F4->U+6797, \
U+F9F5->U+6DCB, U+F9F6->U+81E8, U+F9F7->U+7ACB, U+F9F8->U+7B20, U+F9F9->U+7C92, \
U+F9FA->U+72C0, U+F9FB->U+7099, U+F9FC->U+8B58, U+F9FD->U+4EC0, U+F9FE->U+8336, \
U+F9FF->U+523A, U+FA00->U+5207, U+FA01->U+5EA6, U+FA02->U+62D3, U+FA03->U+7CD6, \
U+FA04->U+5B85, U+FA05->U+6D1E, U+FA06->U+66B4, U+FA07->U+8F3B, U+FA08->U+884C, \
U+FA09->U+964D, U+FA0A->U+898B, U+FA0B->U+5ED3, U+FA0C->U+5140, U+FA0D->U+55C0, \
U+FA10->U+585A, U+FA12->U+6674, U+FA15->U+51DE, U+FA16->U+732A, U+FA17->U+76CA, \
U+FA18->U+793C, U+FA19->U+795E, U+FA1A->U+7965, U+FA1B->U+798F, U+FA1C->U+9756, \
U+FA1D->U+7CBE, U+FA1E->U+7FBD, U+FA20->U+8612, U+FA22->U+8AF8, U+FA25->U+9038, \
U+FA26->U+90FD, U+FA2A->U+98EF, U+FA2B->U+98FC, U+FA2C->U+9928, U+FA2D->U+9DB4, \
U+FA30->U+4FAE, U+FA31->U+50E7, U+FA32->U+514D, U+FA33->U+52C9, U+FA34->U+52E4, \
U+FA35->U+5351, U+FA36->U+559D, U+FA37->U+5606, U+FA38->U+5668, U+FA39->U+5840, \
U+FA3A->U+58A8, U+FA3B->U+5C64, U+FA3C->U+5C6E, U+FA3D->U+6094, U+FA3E->U+6168, \
U+FA3F->U+618E, U+FA40->U+61F2, U+FA41->U+654F, U+FA42->U+65E2, U+FA43->U+6691, \
U+FA44->U+6885, U+FA45->U+6D77, U+FA46->U+6E1A, U+FA47->U+6F22, U+FA48->U+716E, \
U+FA49->U+722B, U+FA4A->U+7422, U+FA4B->U+7891, U+FA4C->U+793E, U+FA4D->U+7949, \
U+FA4E->U+7948, U+FA4F->U+7950, U+FA50->U+7956, U+FA51->U+795D, U+FA52->U+798D, \
U+FA53->U+798E, U+FA54->U+7A40, U+FA55->U+7A81, U+FA56->U+7BC0, U+FA57->U+7DF4, \
U+FA58->U+7E09, U+FA59->U+7E41, U+FA5A->U+7F72, U+FA5B->U+8005, U+FA5C->U+81ED, \
U+FA5D->U+8279, U+FA5E->U+8279, U+FA5F->U+8457, U+FA60->U+8910, U+FA61->U+8996, \
U+FA62->U+8B01, U+FA63->U+8B39, U+FA64->U+8CD3, U+FA65->U+8D08, U+FA66->U+8FB6, \
U+FA67->U+9038, U+FA68->U+96E3, U+FA69->U+97FF, U+FA6A->U+983B, U+FA70->U+4E26, \
U+FA71->U+51B5, U+FA72->U+5168, U+FA73->U+4F80, U+FA74->U+5145, U+FA75->U+5180, \
U+FA76->U+52C7, U+FA77->U+52FA, U+FA78->U+559D, U+FA79->U+5555, U+FA7A->U+5599, \
U+FA7B->U+55E2, U+FA7C->U+585A, U+FA7D->U+58B3, U+FA7E->U+5944, U+FA7F->U+5954, \
U+FA80->U+5A62, U+FA81->U+5B28, U+FA82->U+5ED2, U+FA83->U+5ED9, U+FA84->U+5F69, \
U+FA85->U+5FAD, U+FA86->U+60D8, U+FA87->U+614E, U+FA88->U+6108, U+FA89->U+618E, \
U+FA8A->U+6160, U+FA8B->U+61F2, U+FA8C->U+6234, U+FA8D->U+63C4, U+FA8E->U+641C, \
U+FA8F->U+6452, U+FA90->U+6556, U+FA91->U+6674, U+FA92->U+6717, U+FA93->U+671B, \
U+FA94->U+6756, U+FA95->U+6B79, U+FA96->U+6BBA, U+FA97->U+6D41, U+FA98->U+6EDB, \
U+FA99->U+6ECB, U+FA9A->U+6F22, U+FA9B->U+701E, U+FA9C->U+716E, U+FA9D->U+77A7, \
U+FA9E->U+7235, U+FA9F->U+72AF, U+FAA0->U+732A, U+FAA1->U+7471, U+FAA2->U+7506, \
U+FAA3->U+753B, U+FAA4->U+761D, U+FAA5->U+761F, U+FAA6->U+76CA, U+FAA7->U+76DB, \
U+FAA8->U+76F4, U+FAA9->U+774A, U+FAAA->U+7740, U+FAAB->U+78CC, U+FAAC->U+7AB1, \
U+FAAD->U+7BC0, U+FAAE->U+7C7B, U+FAAF->U+7D5B, U+FAB0->U+7DF4, U+FAB1->U+7F3E, \
U+FAB2->U+8005, U+FAB3->U+8352, U+FAB4->U+83EF, U+FAB5->U+8779, U+FAB6->U+8941, \
U+FAB7->U+8986, U+FAB8->U+8996, U+FAB9->U+8ABF, U+FABA->U+8AF8, U+FABB->U+8ACB, \
U+FABC->U+8B01, U+FABD->U+8AFE, U+FABE->U+8AED, U+FABF->U+8B39, U+FAC0->U+8B8A, \
U+FAC1->U+8D08, U+FAC2->U+8F38, U+FAC3->U+9072, U+FAC4->U+9199, U+FAC5->U+9276, \
U+FAC6->U+967C, U+FAC7->U+96E3, U+FAC8->U+9756, U+FAC9->U+97DB, U+FACA->U+97FF, \
U+FACB->U+980B, U+FACC->U+983B, U+FACD->U+9B12, U+FACE->U+9F9C, U+FACF->U+2284A, \
U+FAD0->U+22844, U+FAD1->U+233D5, U+FAD2->U+3B9D, U+FAD3->U+4018, U+FAD4->U+4039, \
U+FAD5->U+25249, U+FAD6->U+25CD0, U+FAD7->U+27ED3, U+FAD8->U+9F43, U+FAD9->U+9F8E, \
U+2F800->U+4E3D, U+2F801->U+4E38, U+2F802->U+4E41, U+2F803->U+20122, U+2F804->U+4F60, \
U+2F805->U+4FAE, U+2F806->U+4FBB, U+2F807->U+5002, U+2F808->U+507A, U+2F809->U+5099, \
U+2F80A->U+50E7, U+2F80B->U+50CF, U+2F80C->U+349E, U+2F80D->U+2063A, U+2F80E->U+514D, \
U+2F80F->U+5154, U+2F810->U+5164, U+2F811->U+5177, U+2F812->U+2051C, U+2F813->U+34B9, \
U+2F814->U+5167, U+2F815->U+518D, U+2F816->U+2054B, U+2F817->U+5197, U+2F818->U+51A4, \
U+2F819->U+4ECC, U+2F81A->U+51AC, U+2F81B->U+51B5, U+2F81C->U+291DF, U+2F81D->U+51F5, \
U+2F81E->U+5203, U+2F81F->U+34DF, U+2F820->U+523B, U+2F821->U+5246, U+2F822->U+5272, \
U+2F823->U+5277, U+2F824->U+3515, U+2F825->U+52C7, U+2F826->U+52C9, U+2F827->U+52E4, \
U+2F828->U+52FA, U+2F829->U+5305, U+2F82A->U+5306, U+2F82B->U+5317, U+2F82C->U+5349, \
U+2F82D->U+5351, U+2F82E->U+535A, U+2F82F->U+5373, U+2F830->U+537D, U+2F831->U+537F, \
U+2F832->U+537F, U+2F833->U+537F, U+2F834->U+20A2C, U+2F835->U+7070, U+2F836->U+53CA, \
U+2F837->U+53DF, U+2F838->U+20B63, U+2F839->U+53EB, U+2F83A->U+53F1, U+2F83B->U+5406, \
U+2F83C->U+549E, U+2F83D->U+5438, U+2F83E->U+5448, U+2F83F->U+5468, U+2F840->U+54A2, \
U+2F841->U+54F6, U+2F842->U+5510, U+2F843->U+5553, U+2F844->U+5563, U+2F845->U+5584, \
U+2F846->U+5584, U+2F847->U+5599, U+2F848->U+55AB, U+2F849->U+55B3, U+2F84A->U+55C2, \
U+2F84B->U+5716, U+2F84C->U+5606, U+2F84D->U+5717, U+2F84E->U+5651, U+2F84F->U+5674, \
U+2F850->U+5207, U+2F851->U+58EE, U+2F852->U+57CE, U+2F853->U+57F4, U+2F854->U+580D, \
U+2F855->U+578B, U+2F856->U+5832, U+2F857->U+5831, U+2F858->U+58AC, U+2F859->U+214E4, \
U+2F85A->U+58F2, U+2F85B->U+58F7, U+2F85C->U+5906, U+2F85D->U+591A, U+2F85E->U+5922, \
U+2F85F->U+5962, U+2F860->U+216A8, U+2F861->U+216EA, U+2F862->U+59EC, U+2F863->U+5A1B, \
U+2F864->U+5A27, U+2F865->U+59D8, U+2F866->U+5A66, U+2F867->U+36EE, U+2F868->U+36FC, \
U+2F869->U+5B08, U+2F86A->U+5B3E, U+2F86B->U+5B3E, U+2F86C->U+219C8, U+2F86D->U+5BC3, \
U+2F86E->U+5BD8, U+2F86F->U+5BE7, U+2F870->U+5BF3, U+2F871->U+21B18, U+2F872->U+5BFF, \
U+2F873->U+5C06, U+2F874->U+5F53, U+2F875->U+5C22, U+2F876->U+3781, U+2F877->U+5C60, \
U+2F878->U+5C6E, U+2F879->U+5CC0, U+2F87A->U+5C8D, U+2F87B->U+21DE4, U+2F87C->U+5D43, \
U+2F87D->U+21DE6, U+2F87E->U+5D6E, U+2F87F->U+5D6B, U+2F880->U+5D7C, U+2F881->U+5DE1, \
U+2F882->U+5DE2, U+2F883->U+382F, U+2F884->U+5DFD, U+2F885->U+5E28, U+2F886->U+5E3D, \
U+2F887->U+5E69, U+2F888->U+3862, U+2F889->U+22183, U+2F88A->U+387C, U+2F88B->U+5EB0, \
U+2F88C->U+5EB3, U+2F88D->U+5EB6, U+2F88E->U+5ECA, U+2F88F->U+2A392, U+2F890->U+5EFE, \
U+2F891->U+22331, U+2F892->U+22331, U+2F893->U+8201, U+2F894->U+5F22, U+2F895->U+5F22, \
U+2F896->U+38C7, U+2F897->U+232B8, U+2F898->U+261DA, U+2F899->U+5F62, U+2F89A->U+5F6B, \
U+2F89B->U+38E3, U+2F89C->U+5F9A, U+2F89D->U+5FCD, U+2F89E->U+5FD7, U+2F89F->U+5FF9, \
U+2F8A0->U+6081, U+2F8A1->U+393A, U+2F8A2->U+391C, U+2F8A3->U+6094, U+2F8A4->U+226D4, \
U+2F8A5->U+60C7, U+2F8A6->U+6148, U+2F8A7->U+614C, U+2F8A8->U+614E, U+2F8A9->U+614C, \
U+2F8AA->U+617A, U+2F8AB->U+618E, U+2F8AC->U+61B2, U+2F8AD->U+61A4, U+2F8AE->U+61AF, \
U+2F8AF->U+61DE, U+2F8B0->U+61F2, U+2F8B1->U+61F6, U+2F8B2->U+6210, U+2F8B3->U+621B, \
U+2F8B4->U+625D, U+2F8B5->U+62B1, U+2F8B6->U+62D4, U+2F8B7->U+6350, U+2F8B8->U+22B0C, \
U+2F8B9->U+633D, U+2F8BA->U+62FC, U+2F8BB->U+6368, U+2F8BC->U+6383, U+2F8BD->U+63E4, \
U+2F8BE->U+22BF1, U+2F8BF->U+6422, U+2F8C0->U+63C5, U+2F8C1->U+63A9, U+2F8C2->U+3A2E, \
U+2F8C3->U+6469, U+2F8C4->U+647E, U+2F8C5->U+649D, U+2F8C6->U+6477, U+2F8C7->U+3A6C, \
U+2F8C8->U+654F, U+2F8C9->U+656C, U+2F8CA->U+2300A, U+2F8CB->U+65E3, U+2F8CC->U+66F8, \
U+2F8CD->U+6649, U+2F8CE->U+3B19, U+2F8CF->U+6691, U+2F8D0->U+3B08, U+2F8D1->U+3AE4, \
U+2F8D2->U+5192, U+2F8D3->U+5195, U+2F8D4->U+6700, U+2F8D5->U+669C, U+2F8D6->U+80AD, \
U+2F8D7->U+43D9, U+2F8D8->U+6717, U+2F8D9->U+671B, U+2F8DA->U+6721, U+2F8DB->U+675E, \
U+2F8DC->U+6753, U+2F8DD->U+233C3, U+2F8DE->U+3B49, U+2F8DF->U+67FA, U+2F8E0->U+6785, \
U+2F8E1->U+6852, U+2F8E2->U+6885, U+2F8E3->U+2346D, U+2F8E4->U+688E, U+2F8E5->U+681F, \
U+2F8E6->U+6914, U+2F8E7->U+3B9D, U+2F8E8->U+6942, U+2F8E9->U+69A3, U+2F8EA->U+69EA, \
U+2F8EB->U+6AA8, U+2F8EC->U+236A3, U+2F8ED->U+6ADB, U+2F8EE->U+3C18, U+2F8EF->U+6B21, \
U+2F8F0->U+238A7, U+2F8F1->U+6B54, U+2F8F2->U+3C4E, U+2F8F3->U+6B72, U+2F8F4->U+6B9F, \
U+2F8F5->U+6BBA, U+2F8F6->U+6BBB, U+2F8F7->U+23A8D, U+2F8F8->U+21D0B, U+2F8F9->U+23AFA, \
U+2F8FA->U+6C4E, U+2F8FB->U+23CBC, U+2F8FC->U+6CBF, U+2F8FD->U+6CCD, U+2F8FE->U+6C67, \
U+2F8FF->U+6D16, U+2F900->U+6D3E, U+2F901->U+6D77, U+2F902->U+6D41, U+2F903->U+6D69, \
U+2F904->U+6D78, U+2F905->U+6D85, U+2F906->U+23D1E, U+2F907->U+6D34, U+2F908->U+6E2F, \
U+2F909->U+6E6E, U+2F90A->U+3D33, U+2F90B->U+6ECB, U+2F90C->U+6EC7, U+2F90D->U+23ED1, \
U+2F90E->U+6DF9, U+2F90F->U+6F6E, U+2F910->U+23F5E, U+2F911->U+23F8E, U+2F912->U+6FC6, \
U+2F913->U+7039, U+2F914->U+701E, U+2F915->U+701B, U+2F916->U+3D96, U+2F917->U+704A, \
U+2F918->U+707D, U+2F919->U+7077, U+2F91A->U+70AD, U+2F91B->U+20525, U+2F91C->U+7145, \
U+2F91D->U+24263, U+2F91E->U+719C, U+2F91F->U+243AB, U+2F920->U+7228, U+2F921->U+7235, \
U+2F922->U+7250, U+2F923->U+24608, U+2F924->U+7280, U+2F925->U+7295, U+2F926->U+24735, \
U+2F927->U+24814, U+2F928->U+737A, U+2F929->U+738B, U+2F92A->U+3EAC, U+2F92B->U+73A5, \
U+2F92C->U+3EB8, U+2F92D->U+3EB8, U+2F92E->U+7447, U+2F92F->U+745C, U+2F930->U+7471, \
U+2F931->U+7485, U+2F932->U+74CA, U+2F933->U+3F1B, U+2F934->U+7524, U+2F935->U+24C36, \
U+2F936->U+753E, U+2F937->U+24C92, U+2F938->U+7570, U+2F939->U+2219F, U+2F93A->U+7610, \
U+2F93B->U+24FA1, U+2F93C->U+24FB8, U+2F93D->U+25044, U+2F93E->U+3FFC, U+2F93F->U+4008, \
U+2F940->U+76F4, U+2F941->U+250F3, U+2F942->U+250F2, U+2F943->U+25119, U+2F944->U+25133, \
U+2F945->U+771E, U+2F946->U+771F, U+2F947->U+771F, U+2F948->U+774A, U+2F949->U+4039, \
U+2F94A->U+778B, U+2F94B->U+4046, U+2F94C->U+4096, U+2F94D->U+2541D, U+2F94E->U+784E, \
U+2F94F->U+788C, U+2F950->U+78CC, U+2F951->U+40E3, U+2F952->U+25626, U+2F953->U+7956, \
U+2F954->U+2569A, U+2F955->U+256C5, U+2F956->U+798F, U+2F957->U+79EB, U+2F958->U+412F, \
U+2F959->U+7A40, U+2F95A->U+7A4A, U+2F95B->U+7A4F, U+2F95C->U+2597C, U+2F95D->U+25AA7, \
U+2F95E->U+25AA7, U+2F95F->U+7AEE, U+2F960->U+4202, U+2F961->U+25BAB, U+2F962->U+7BC6, \
U+2F963->U+7BC9, U+2F964->U+4227, U+2F965->U+25C80, U+2F966->U+7CD2, U+2F967->U+42A0, \
U+2F968->U+7CE8, U+2F969->U+7CE3, U+2F96A->U+7D00, U+2F96B->U+25F86, U+2F96C->U+7D63, \
U+2F96D->U+4301, U+2F96E->U+7DC7, U+2F96F->U+7E02, U+2F970->U+7E45, U+2F971->U+4334, \
U+2F972->U+26228, U+2F973->U+26247, U+2F974->U+4359, U+2F975->U+262D9, U+2F976->U+7F7A, \
U+2F977->U+2633E, U+2F978->U+7F95, U+2F979->U+7FFA, U+2F97A->U+8005, U+2F97B->U+264DA, \
U+2F97C->U+26523, U+2F97D->U+8060, U+2F97E->U+265A8, U+2F97F->U+8070, U+2F980->U+2335F, \
U+2F981->U+43D5, U+2F982->U+80B2, U+2F983->U+8103, U+2F984->U+440B, U+2F985->U+813E, \
U+2F986->U+5AB5, U+2F987->U+267A7, U+2F988->U+267B5, U+2F989->U+23393, U+2F98A->U+2339C, \
U+2F98B->U+8201, U+2F98C->U+8204, U+2F98D->U+8F9E, U+2F98E->U+446B, U+2F98F->U+8291, \
U+2F990->U+828B, U+2F991->U+829D, U+2F992->U+52B3, U+2F993->U+82B1, U+2F994->U+82B3, \
U+2F995->U+82BD, U+2F996->U+82E6, U+2F997->U+26B3C, U+2F998->U+82E5, U+2F999->U+831D, \
U+2F99A->U+8363, U+2F99B->U+83AD, U+2F99C->U+8323, U+2F99D->U+83BD, U+2F99E->U+83E7, \
U+2F99F->U+8457, U+2F9A0->U+8353, U+2F9A1->U+83CA, U+2F9A2->U+83CC, U+2F9A3->U+83DC, \
U+2F9A4->U+26C36, U+2F9A5->U+26D6B, U+2F9A6->U+26CD5, U+2F9A7->U+452B, U+2F9A8->U+84F1, \
U+2F9A9->U+84F3, U+2F9AA->U+8516, U+2F9AB->U+273CA, U+2F9AC->U+8564, U+2F9AD->U+26F2C, \
U+2F9AE->U+455D, U+2F9AF->U+4561, U+2F9B0->U+26FB1, U+2F9B1->U+270D2, U+2F9B2->U+456B, \
U+2F9B3->U+8650, U+2F9B4->U+865C, U+2F9B5->U+8667, U+2F9B6->U+8669, U+2F9B7->U+86A9, \
U+2F9B8->U+8688, U+2F9B9->U+870E, U+2F9BA->U+86E2, U+2F9BB->U+8779, U+2F9BC->U+8728, \
U+2F9BD->U+876B, U+2F9BE->U+8786, U+2F9BF->U+45D7, U+2F9C0->U+87E1, U+2F9C1->U+8801, \
U+2F9C2->U+45F9, U+2F9C3->U+8860, U+2F9C4->U+8863, U+2F9C5->U+27667, U+2F9C6->U+88D7, \
U+2F9C7->U+88DE, U+2F9C8->U+4635, U+2F9C9->U+88FA, U+2F9CA->U+34BB, U+2F9CB->U+278AE, \
U+2F9CC->U+27966, U+2F9CD->U+46BE, U+2F9CE->U+46C7, U+2F9CF->U+8AA0, U+2F9D0->U+8AED, \
U+2F9D1->U+8B8A, U+2F9D2->U+8C55, U+2F9D3->U+27CA8, U+2F9D4->U+8CAB, U+2F9D5->U+8CC1, \
U+2F9D6->U+8D1B, U+2F9D7->U+8D77, U+2F9D8->U+27F2F, U+2F9D9->U+20804, U+2F9DA->U+8DCB, \
U+2F9DB->U+8DBC, U+2F9DC->U+8DF0, U+2F9DD->U+208DE, U+2F9DE->U+8ED4, U+2F9DF->U+8F38, \
U+2F9E0->U+285D2, U+2F9E1->U+285ED, U+2F9E2->U+9094, U+2F9E3->U+90F1, U+2F9E4->U+9111, \
U+2F9E5->U+2872E, U+2F9E6->U+911B, U+2F9E7->U+9238, U+2F9E8->U+92D7, U+2F9E9->U+92D8, \
U+2F9EA->U+927C, U+2F9EB->U+93F9, U+2F9EC->U+9415, U+2F9ED->U+28BFA, U+2F9EE->U+958B, \
U+2F9EF->U+4995, U+2F9F0->U+95B7, U+2F9F1->U+28D77, U+2F9F2->U+49E6, U+2F9F3->U+96C3, \
U+2F9F4->U+5DB2, U+2F9F5->U+9723, U+2F9F6->U+29145, U+2F9F7->U+2921A, U+2F9F8->U+4A6E, \
U+2F9F9->U+4A76, U+2F9FA->U+97E0, U+2F9FB->U+2940A, U+2F9FC->U+4AB2, U+2F9FD->U+29496, \
U+2F9FE->U+980B, U+2F9FF->U+980B, U+2FA00->U+9829, U+2FA01->U+295B6, U+2FA02->U+98E2, \
U+2FA03->U+4B33, U+2FA04->U+9929, U+2FA05->U+99A7, U+2FA06->U+99C2, U+2FA07->U+99FE, \
U+2FA08->U+4BCE, U+2FA09->U+29B30, U+2FA0A->U+9B12, U+2FA0B->U+9C40, U+2FA0C->U+9CFD, \
U+2FA0D->U+4CCE, U+2FA0E->U+4CED, U+2FA0F->U+9D67, U+2FA10->U+2A0CE, U+2FA11->U+4CF8, \
U+2FA12->U+2A105, U+2FA13->U+2A20E, U+2FA14->U+2A291, U+2FA15->U+9EBB, U+2FA16->U+4D56, \
U+2FA17->U+9EF9, U+2FA18->U+9EFE, U+2FA19->U+9F05, U+2FA1A->U+9F0F, U+2FA1B->U+9F16, \
U+2FA1C->U+9F3B, U+2FA1D->U+2A600, U+2F00->U+4E00, U+2F01->U+4E28, U+2F02->U+4E36, \
U+2F03->U+4E3F, U+2F04->U+4E59, U+2F05->U+4E85, U+2F06->U+4E8C, U+2F07->U+4EA0, \
U+2F08->U+4EBA, U+2F09->U+513F, U+2F0A->U+5165, U+2F0B->U+516B, U+2F0C->U+5182, \
U+2F0D->U+5196, U+2F0E->U+51AB, U+2F0F->U+51E0, U+2F10->U+51F5, U+2F11->U+5200, \
U+2F12->U+529B, U+2F13->U+52F9, U+2F14->U+5315, U+2F15->U+531A, U+2F16->U+5338, \
U+2F17->U+5341, U+2F18->U+535C, U+2F19->U+5369, U+2F1A->U+5382, U+2F1B->U+53B6, \
U+2F1C->U+53C8, U+2F1D->U+53E3, U+2F1E->U+56D7, U+2F1F->U+571F, U+2F20->U+58EB, \
U+2F21->U+5902, U+2F22->U+590A, U+2F23->U+5915, U+2F24->U+5927, U+2F25->U+5973, \
U+2F26->U+5B50, U+2F27->U+5B80, U+2F28->U+5BF8, U+2F29->U+5C0F, U+2F2A->U+5C22, \
U+2F2B->U+5C38, U+2F2C->U+5C6E, U+2F2D->U+5C71, U+2F2E->U+5DDB, U+2F2F->U+5DE5, \
U+2F30->U+5DF1, U+2F31->U+5DFE, U+2F32->U+5E72, U+2F33->U+5E7A, U+2F34->U+5E7F, \
U+2F35->U+5EF4, U+2F36->U+5EFE, U+2F37->U+5F0B, U+2F38->U+5F13, U+2F39->U+5F50, \
U+2F3A->U+5F61, U+2F3B->U+5F73, U+2F3C->U+5FC3, U+2F3D->U+6208, U+2F3E->U+6236, \
U+2F3F->U+624B, U+2F40->U+652F, U+2F41->U+6534, U+2F42->U+6587, U+2F43->U+6597, \
U+2F44->U+65A4, U+2F45->U+65B9, U+2F46->U+65E0, U+2F47->U+65E5, U+2F48->U+66F0, \
U+2F49->U+6708, U+2F4A->U+6728, U+2F4B->U+6B20, U+2F4C->U+6B62, U+2F4D->U+6B79, \
U+2F4E->U+6BB3, U+2F4F->U+6BCB, U+2F50->U+6BD4, U+2F51->U+6BDB, U+2F52->U+6C0F, \
U+2F53->U+6C14, U+2F54->U+6C34, U+2F55->U+706B, U+2F56->U+722A, U+2F57->U+7236, \
U+2F58->U+723B, U+2F59->U+723F, U+2F5A->U+7247, U+2F5B->U+7259, U+2F5C->U+725B, \
U+2F5D->U+72AC, U+2F5E->U+7384, U+2F5F->U+7389, U+2F60->U+74DC, U+2F61->U+74E6, \
U+2F62->U+7518, U+2F63->U+751F, U+2F64->U+7528, U+2F65->U+7530, U+2F66->U+758B, \
U+2F67->U+7592, U+2F68->U+7676, U+2F69->U+767D, U+2F6A->U+76AE, U+2F6B->U+76BF, \
U+2F6C->U+76EE, U+2F6D->U+77DB, U+2F6E->U+77E2, U+2F6F->U+77F3, U+2F70->U+793A, \
U+2F71->U+79B8, U+2F72->U+79BE, U+2F73->U+7A74, U+2F74->U+7ACB, U+2F75->U+7AF9, \
U+2F76->U+7C73, U+2F77->U+7CF8, U+2F78->U+7F36, U+2F79->U+7F51, U+2F7A->U+7F8A, \
U+2F7B->U+7FBD, U+2F7C->U+8001, U+2F7D->U+800C, U+2F7E->U+8012, U+2F7F->U+8033, \
U+2F80->U+807F, U+2F81->U+8089, U+2F82->U+81E3, U+2F83->U+81EA, U+2F84->U+81F3, \
U+2F85->U+81FC, U+2F86->U+820C, U+2F87->U+821B, U+2F88->U+821F, U+2F89->U+826E, \
U+2F8A->U+8272, U+2F8B->U+8278, U+2F8C->U+864D, U+2F8D->U+866B, U+2F8E->U+8840, \
U+2F8F->U+884C, U+2F90->U+8863, U+2F91->U+897E, U+2F92->U+898B, U+2F93->U+89D2, \
U+2F94->U+8A00, U+2F95->U+8C37, U+2F96->U+8C46, U+2F97->U+8C55, U+2F98->U+8C78, \
U+2F99->U+8C9D, U+2F9A->U+8D64, U+2F9B->U+8D70, U+2F9C->U+8DB3, U+2F9D->U+8EAB, \
U+2F9E->U+8ECA, U+2F9F->U+8F9B, U+2FA0->U+8FB0, U+2FA1->U+8FB5, U+2FA2->U+9091, \
U+2FA3->U+9149, U+2FA4->U+91C6, U+2FA5->U+91CC, U+2FA6->U+91D1, U+2FA7->U+9577, \
U+2FA8->U+9580, U+2FA9->U+961C, U+2FAA->U+96B6, U+2FAB->U+96B9, U+2FAC->U+96E8, \
U+2FAD->U+9751, U+2FAE->U+975E, U+2FAF->U+9762, U+2FB0->U+9769, U+2FB1->U+97CB, \
U+2FB2->U+97ED, U+2FB3->U+97F3, U+2FB4->U+9801, U+2FB5->U+98A8, U+2FB6->U+98DB, \
U+2FB7->U+98DF, U+2FB8->U+9996, U+2FB9->U+9999, U+2FBA->U+99AC, U+2FBB->U+9AA8, \
U+2FBC->U+9AD8, U+2FBD->U+9ADF, U+2FBE->U+9B25, U+2FBF->U+9B2F, U+2FC0->U+9B32, \
U+2FC1->U+9B3C, U+2FC2->U+9B5A, U+2FC3->U+9CE5, U+2FC4->U+9E75, U+2FC5->U+9E7F, \
U+2FC6->U+9EA5, U+2FC7->U+9EBB, U+2FC8->U+9EC3, U+2FC9->U+9ECD, U+2FCA->U+9ED1, \
U+2FCB->U+9EF9, U+2FCC->U+9EFD, U+2FCD->U+9F0E, U+2FCE->U+9F13, U+2FCF->U+9F20, \
U+2FD0->U+9F3B, U+2FD1->U+9F4A, U+2FD2->U+9F52, U+2FD3->U+9F8D, U+2FD4->U+9F9C, \
U+2FD5->U+9FA0, U+3042->U+3041, U+3044->U+3043, U+3046->U+3045, U+3048->U+3047, \
U+304A->U+3049, U+304C->U+304B, U+304E->U+304D, U+3050->U+304F, U+3052->U+3051, \
U+3054->U+3053, U+3056->U+3055, U+3058->U+3057, U+305A->U+3059, U+305C->U+305B, \
U+305E->U+305D, U+3060->U+305F, U+3062->U+3061, U+3064->U+3063, U+3065->U+3063, \
U+3067->U+3066, U+3069->U+3068, U+3070->U+306F, U+3071->U+306F, U+3073->U+3072, \
U+3074->U+3072, U+3076->U+3075, U+3077->U+3075, U+3079->U+3078, U+307A->U+3078, \
U+307C->U+307B, U+307D->U+307B, U+3084->U+3083, U+3086->U+3085, U+3088->U+3087, \
U+308F->U+308E, U+3094->U+3046, U+3095->U+304B, U+3096->U+3051, U+30A2->U+30A1, \
U+30A4->U+30A3, U+30A6->U+30A5, U+30A8->U+30A7, U+30AA->U+30A9, U+30AC->U+30AB, \
U+30AE->U+30AD, U+30B0->U+30AF, U+30B2->U+30B1, U+30B4->U+30B3, U+30B6->U+30B5, \
U+30B8->U+30B7, U+30BA->U+30B9, U+30BC->U+30BB, U+30BE->U+30BD, U+30C0->U+30BF, \
U+30C2->U+30C1, U+30C5->U+30C4, U+30C7->U+30C6, U+30C9->U+30C8, U+30D0->U+30CF, \
U+30D1->U+30CF, U+30D3->U+30D2, U+30D4->U+30D2, U+30D6->U+30D5, U+30D7->U+30D5, \
U+30D9->U+30D8, U+30DA->U+30D8, U+30DC->U+30DB, U+30DD->U+30DB, U+30E4->U+30E3, \
U+30E6->U+30E5, U+30E8->U+30E7, U+30EF->U+30EE, U+30F4->U+30A6, U+30AB->U+30F5, \
U+30B1->U+30F6, U+30F7->U+30EF, U+30F8->U+30F0, U+30F9->U+30F1, U+30FA->U+30F2, \
U+30AF->U+31F0, U+30B7->U+31F1, U+30B9->U+31F2, U+30C8->U+31F3, U+30CC->U+31F4, \
U+30CF->U+31F5, U+30D2->U+31F6, U+30D5->U+31F7, U+30D8->U+31F8, U+30DB->U+31F9, \
U+30E0->U+31FA, U+30E9->U+31FB, U+30EA->U+31FC, U+30EB->U+31FD, U+30EC->U+31FE, \
U+30ED->U+31FF, U+FF66->U+30F2, U+FF67->U+30A1, U+FF68->U+30A3, U+FF69->U+30A5, \
U+FF6A->U+30A7, U+FF6B->U+30A9, U+FF6C->U+30E3, U+FF6D->U+30E5, U+FF6E->U+30E7, \
U+FF6F->U+30C3, U+FF71->U+30A1, U+FF72->U+30A3, U+FF73->U+30A5, U+FF74->U+30A7, \
U+FF75->U+30A9, U+FF76->U+30AB, U+FF77->U+30AD, U+FF78->U+30AF, U+FF79->U+30B1, \
U+FF7A->U+30B3, U+FF7B->U+30B5, U+FF7C->U+30B7, U+FF7D->U+30B9, U+FF7E->U+30BB, \
U+FF7F->U+30BD, U+FF80->U+30BF, U+FF81->U+30C1, U+FF82->U+30C3, U+FF83->U+30C6, \
U+FF84->U+30C8, U+FF85->U+30CA, U+FF86->U+30CB, U+FF87->U+30CC, U+FF88->U+30CD, \
U+FF89->U+30CE, U+FF8A->U+30CF, U+FF8B->U+30D2, U+FF8C->U+30D5, U+FF8D->U+30D8, \
U+FF8E->U+30DB, U+FF8F->U+30DE, U+FF90->U+30DF, U+FF91->U+30E0, U+FF92->U+30E1, \
U+FF93->U+30E2, U+FF94->U+30E3, U+FF95->U+30E5, U+FF96->U+30E7, U+FF97->U+30E9, \
U+FF98->U+30EA, U+FF99->U+30EB, U+FF9A->U+30EC, U+FF9B->U+30ED, U+FF9C->U+30EF, \
U+FF9D->U+30F3, U+FFA0->U+3164, U+FFA1->U+3131, U+FFA2->U+3132, U+FFA3->U+3133, \
U+FFA4->U+3134, U+FFA5->U+3135, U+FFA6->U+3136, U+FFA7->U+3137, U+FFA8->U+3138, \
U+FFA9->U+3139, U+FFAA->U+313A, U+FFAB->U+313B, U+FFAC->U+313C, U+FFAD->U+313D, \
U+FFAE->U+313E, U+FFAF->U+313F, U+FFB0->U+3140, U+FFB1->U+3141, U+FFB2->U+3142, \
U+FFB3->U+3143, U+FFB4->U+3144, U+FFB5->U+3145, U+FFB6->U+3146, U+FFB7->U+3147, \
U+FFB8->U+3148, U+FFB9->U+3149, U+FFBA->U+314A, U+FFBB->U+314B, U+FFBC->U+314C, \
U+FFBD->U+314D, U+FFBE->U+314E, U+FFC2->U+314F, U+FFC3->U+3150, U+FFC4->U+3151, \
U+FFC5->U+3152, U+FFC6->U+3153, U+FFC7->U+3154, U+FFCA->U+3155, U+FFCB->U+3156, \
U+FFCC->U+3157, U+FFCD->U+3158, U+FFCE->U+3159, U+FFCF->U+315A, U+FFD2->U+315B, \
U+FFD3->U+315C, U+FFD4->U+315D, U+FFD5->U+315E, U+FFD6->U+315F, U+FFD7->U+3160, \
U+FFDA->U+3161, U+FFDB->U+3162, U+FFDC->U+3163, U+3131->U+1100, U+3132->U+1101, \
U+3133->U+11AA, U+3134->U+1102, U+3135->U+11AC, U+3136->U+11AD, U+3137->U+1103, \
U+3138->U+1104, U+3139->U+1105, U+313A->U+11B0, U+313B->U+11B1, U+313C->U+11B2, \
U+313D->U+11B3, U+313E->U+11B4, U+313F->U+11B5, U+3140->U+111A, U+3141->U+1106, \
U+3142->U+1107, U+3143->U+1108, U+3144->U+1121, U+3145->U+1109, U+3146->U+110A, \
U+3147->U+110B, U+3148->U+110C, U+3149->U+110D, U+314A->U+110E, U+314B->U+110F, \
U+314C->U+1110, U+314D->U+1111, U+314E->U+1112, U+314F->U+1161, U+3150->U+1162, \
U+3151->U+1163, U+3152->U+1164, U+3153->U+1165, U+3154->U+1166, U+3155->U+1167, \
U+3156->U+1168, U+3157->U+1169, U+3158->U+116A, U+3159->U+116B, U+315A->U+116C, \
U+315B->U+116D, U+315C->U+116E, U+315D->U+116F, U+315E->U+1170, U+315F->U+1171, \
U+3160->U+1172, U+3161->U+1173, U+3162->U+1174, U+3163->U+1175, U+3165->U+1114, \
U+3166->U+1115, U+3167->U+11C7, U+3168->U+11C8, U+3169->U+11CC, U+316A->U+11CE, \
U+316B->U+11D3, U+316C->U+11D7, U+316D->U+11D9, U+316E->U+111C, U+316F->U+11DD, \
U+3170->U+11DF, U+3171->U+111D, U+3172->U+111E, U+3173->U+1120, U+3174->U+1122, \
U+3175->U+1123, U+3176->U+1127, U+3177->U+1129, U+3178->U+112B, U+3179->U+112C, \
U+317A->U+112D, U+317B->U+112E, U+317C->U+112F, U+317D->U+1132, U+317E->U+1136, \
U+317F->U+1140, U+3180->U+1147, U+3181->U+114C, U+3182->U+11F1, U+3183->U+11F2, \
U+3184->U+1157, U+3185->U+1158, U+3186->U+1159, U+3187->U+1184, U+3188->U+1185, \
U+3189->U+1188, U+318A->U+1191, U+318B->U+1192, U+318C->U+1194, U+318D->U+119E, \
U+318E->U+11A1, U+A490->U+A408, U+A491->U+A1B9, U+4E00..U+9FBB, U+3400..U+4DB5, \
U+20000..U+2A6D6, U+FA0E, U+FA0F, U+FA11, U+FA13, U+FA14, U+FA1F, U+FA21, U+FA23, \
U+FA24, U+FA27, U+FA28, U+FA29, U+3105..U+312C, U+31A0..U+31B7, U+3041, U+3043, \
U+3045, U+3047, U+3049, U+304B, U+304D, U+304F, U+3051, U+3053, U+3055, U+3057, \
U+3059, U+305B, U+305D, U+305F, U+3061, U+3063, U+3066, U+3068, U+306A..U+306F, \
U+3072, U+3075, U+3078, U+307B, U+307E..U+3083, U+3085, U+3087, U+3089..U+308E, \
U+3090..U+3093, U+30A1, U+30A3, U+30A5, U+30A7, U+30A9, U+30AD, U+30AF, U+30B3, \
U+30B5, U+30BB, U+30BD, U+30BF, U+30C1, U+30C3, U+30C4, U+30C6, U+30CA, U+30CB, \
U+30CD, U+30CE, U+30DE, U+30DF, U+30E1, U+30E2, U+30E3, U+30E5, U+30E7, U+30EE, \
U+30F0..U+30F3, U+30F5, U+30F6, U+31F0, U+31F1, U+31F2, U+31F3, U+31F4, U+31F5, \
U+31F6, U+31F7, U+31F8, U+31F9, U+31FA, U+31FB, U+31FC, U+31FD, U+31FE, U+31FF, \
U+AC00..U+D7A3, U+1100..U+1159, U+1161..U+11A2, U+11A8..U+11F9, U+A000..U+A48C, \
U+A492..U+A4C6
}

indexer
{
    mem_limit = 256M
}

searchd
{
    port = 3312
    log = /var/log/searchd.log
    query_log = /var/log/query.log
    read_timeout = 5
    max_children = 30
    pid_file = /var/log/searchd.pid
    max_matches = 1000
    seamless_rotate = 1
    preopen_indexes = 0
    unlink_old = 1
}

[sphinxapi.php]
<?php

//
// $Id: sphinxapi.php 1418 2008-08-28 15:30:05Z shodan $
//

//
// Copyright (c) 2001-2008, Andrew Aksyonoff. All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License. You should have
// received a copy of the GPL license along with this program; if you
// did not, you can find it at http://www.gnu.org/
//

/////////////////////////////////////////////////////////////////////////////
// PHP version of Sphinx searchd client (PHP API)
/////////////////////////////////////////////////////////////////////////////

/// known searchd commands
define ( "SEARCHD_COMMAND_SEARCH",     0 );
define ( "SEARCHD_COMMAND_EXCERPT",     1 );
define ( "SEARCHD_COMMAND_UPDATE",     2 );
define ( "SEARCHD_COMMAND_KEYWORDS",3 );

/// current client-side command implementation versions
define ( "VER_COMMAND_SEARCH",         0x113 );
define ( "VER_COMMAND_EXCERPT",         0x100 );
define ( "VER_COMMAND_UPDATE",         0x101 );
define ( "VER_COMMAND_KEYWORDS",     0x100 );

/// known searchd status codes
define ( "SEARCHD_OK",                 0 );
define ( "SEARCHD_ERROR",             1 );
define ( "SEARCHD_RETRY",             2 );
define ( "SEARCHD_WARNING",             3 );

/// known match modes
define ( "SPH_MATCH_ALL",             0 );
define ( "SPH_MATCH_ANY",             1 );
define ( "SPH_MATCH_PHRASE",         2 );
define ( "SPH_MATCH_BOOLEAN",         3 );
define ( "SPH_MATCH_EXTENDED",         4 );
define ( "SPH_MATCH_FULLSCAN",         5 );
define ( "SPH_MATCH_EXTENDED2",         6 );     // extended engine V2 (TEMPORARY, WILL BE REMOVED)

/// known ranking modes (ext2 only)
define ( "SPH_RANK_PROXIMITY_BM25",     0 );     ///< default mode, phrase proximity major factor and BM25 minor one
define ( "SPH_RANK_BM25",             1 );     ///< statistical mode, BM25 ranking only (faster but worse quality)
define ( "SPH_RANK_NONE",             2 );     ///< no ranking, all matches get a weight of 1
define ( "SPH_RANK_WORDCOUNT",         3 );     ///< simple word-count weighting, rank is a weighted sum of per-field keyword occurence counts

/// known sort modes
define ( "SPH_SORT_RELEVANCE",         0 );
define ( "SPH_SORT_ATTR_DESC",         1 );
define ( "SPH_SORT_ATTR_ASC",         2 );
define ( "SPH_SORT_TIME_SEGMENTS",     3 );
define ( "SPH_SORT_EXTENDED",         4 );
define ( "SPH_SORT_EXPR",             5 );

/// known filter types
define ( "SPH_FILTER_VALUES",         0 );
define ( "SPH_FILTER_RANGE",         1 );
define ( "SPH_FILTER_FLOATRANGE",     2 );

/// known attribute types
define ( "SPH_ATTR_INTEGER",         1 );
define ( "SPH_ATTR_TIMESTAMP",         2 );
define ( "SPH_ATTR_ORDINAL",         3 );
define ( "SPH_ATTR_BOOL",             4 );
define ( "SPH_ATTR_FLOAT",             5 );
define ( "SPH_ATTR_MULTI",             0x40000000 );

/// known grouping functions
define ( "SPH_GROUPBY_DAY",             0 );
define ( "SPH_GROUPBY_WEEK",         1 );
define ( "SPH_GROUPBY_MONTH",         2 );
define ( "SPH_GROUPBY_YEAR",         3 );
define ( "SPH_GROUPBY_ATTR",         4 );
define ( "SPH_GROUPBY_ATTRPAIR",     5 );


/// portably pack numeric to 64 unsigned bits, network order
function sphPack64 ( $v )
{
    assert ( is_numeric($v) );

    // x64 route
    if ( PHP_INT_SIZE>=8 )
    {
        $i = (int)$v;
        return pack ( "NN", $i>>32, $i&((1<<32)-1) );
    }

    // x32 route, bcmath
    $x = "4294967296";
    if ( function_exists("bcmul") )
    {
        $h = bcdiv ( $v, $x, 0 );
        $l = bcmod ( $v, $x );
        return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit
    }

    // x32 route, 15 or less decimal digits
    // we can use float, because its actually double and has 52 precision bits
    if ( strlen($v)<=15 )
    {
        $f = (float)$v;
        $h = (int)($f/$x);
        $l = (int)($f-$x*$h);
        return pack ( "NN", $h, $l );
    }

    // x32 route, 16 or more decimal digits
    // well, let me know if you *really* need this
    die ( "INTERNAL ERROR: packing more than 15-digit numeric on 32-bit PHP is not implemented yet (contact support)" );
}


/// portably unpack 64 unsigned bits, network order to numeric
function sphUnpack64 ( $v )
{
    list($h,$l) = array_values ( unpack ( "N*N*", $v ) );

    // x64 route
    if ( PHP_INT_SIZE>=8 )
    {
        if ( $h<0 ) $h += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again
        if ( $l<0 ) $l += (1<<32);
        return ($h<<32) + $l;
    }

    // x32 route
    $h = sprintf ( "%u", $h );
    $l = sprintf ( "%u", $l );
    $x = "4294967296";

    // bcmath
    if ( function_exists("bcmul") )
        return bcadd ( $l, bcmul ( $x, $h ) );

    // no bcmath, 15 or less decimal digits
    // we can use float, because its actually double and has 52 precision bits
    if ( $h<1048576 )
    {
        $f = ((float)$h)*$x + (float)$l;
        return sprintf ( "%.0f", $f ); // builtin conversion is only about 39-40 bits precise!
    }

    // x32 route, 16 or more decimal digits
    // well, let me know if you *really* need this
    die ( "INTERNAL ERROR: unpacking more than 15-digit numeric on 32-bit PHP is not implemented yet (contact support)" );
}


/// sphinx searchd client class
class SphinxClient
{
    var $_host;             ///< searchd host (default is "localhost")
    var $_port;             ///< searchd port (default is 3312)
    var $_offset;         ///< how many records to seek from result-set start (default is 0)
    var $_limit;         ///< how many records to return from result-set starting at offset (default is 20)
    var $_mode;             ///< query matching mode (default is SPH_MATCH_ALL)
    var $_weights;         ///< per-field weights (default is 1 for all fields)
    var $_sort;             ///< match sorting mode (default is SPH_SORT_RELEVANCE)
    var $_sortby;         ///< attribute to sort by (defualt is "")
    var $_min_id;         ///< min ID to match (default is 0, which means no limit)
    var $_max_id;         ///< max ID to match (default is 0, which means no limit)
    var $_filters;         ///< search filters
    var $_groupby;         ///< group-by attribute name
    var $_groupfunc;     ///< group-by function (to pre-process group-by attribute value with)
    var $_groupsort;     ///< group-by sorting clause (to sort groups in result set with)
    var $_groupdistinct;///< group-by count-distinct attribute
    var $_maxmatches;     ///< max matches to retrieve
    var $_cutoff;         ///< cutoff to stop searching at (default is 0)
    var $_retrycount;     ///< distributed retries count
    var $_retrydelay;     ///< distributed retries delay
    var $_anchor;         ///< geographical anchor point
    var $_indexweights;     ///< per-index weights
    var $_ranker;         ///< ranking mode (default is SPH_RANK_PROXIMITY_BM25)
    var $_maxquerytime;     ///< max query time, milliseconds (default is 0, do not limit)
    var $_fieldweights;     ///< per-field-name weights

    var $_error;         ///< last error message
    var $_warning;         ///< last warning message

    var $_reqs;             ///< requests array for multi-query
    var $_mbenc;         ///< stored mbstring encoding
    var $_arrayresult;     ///< whether $result["matches"] should be a hash or an array
    var $_timeout;         ///< connect timeout

    /////////////////////////////////////////////////////////////////////////////
    // common stuff
    /////////////////////////////////////////////////////////////////////////////

    /// create a new client object and fill defaults
    function SphinxClient ()
    {
        // per-client-object settings
        $this->_host         = "localhost";
        $this->_port         = 3312;

        // per-query settings
        $this->_offset         = 0;
        $this->_limit         = 20;
        $this->_mode         = SPH_MATCH_ALL;
        $this->_weights         = array ();
        $this->_sort         = SPH_SORT_RELEVANCE;
        $this->_sortby         = "";
        $this->_min_id         = 0;
        $this->_max_id         = 0;
        $this->_filters         = array ();
        $this->_groupby         = "";
        $this->_groupfunc     = SPH_GROUPBY_DAY;
        $this->_groupsort     = "@group desc";
        $this->_groupdistinct= "";
        $this->_maxmatches     = 1000;
        $this->_cutoff         = 0;
        $this->_retrycount     = 0;
        $this->_retrydelay     = 0;
        $this->_anchor         = array ();
        $this->_indexweights= array ();
        $this->_ranker         = SPH_RANK_PROXIMITY_BM25;
        $this->_maxquerytime= 0;
        $this->_fieldweights= array();

        $this->_error         = ""; // per-reply fields (for single-query case)
        $this->_warning         = "";
        $this->_reqs         = array ();     // requests storage (for multi-query case)
        $this->_mbenc         = "";
        $this->_arrayresult     = false;
        $this->_timeout         = 0;
    }

    /// get last error message (string)
    function GetLastError ()
    {
        return $this->_error;
    }

    /// get last warning message (string)
    function GetLastWarning ()
    {
        return $this->_warning;
    }

    /// set searchd host name (string) and port (integer)
    function SetServer ( $host, $port )
    {
        assert ( is_string($host) );
        assert ( is_int($port) );
        $this->_host = $host;
        $this->_port = $port;
    }

    /// set server connection timeout (0 to remove)
    function SetConnectTimeout ( $timeout )
    {
        assert ( is_numeric($timeout) );
        $this->_timeout = $timeout;
    }

    /////////////////////////////////////////////////////////////////////////////

    /// enter mbstring workaround mode
    function _MBPush ()
    {
        $this->_mbenc = "";
        if ( ini_get ( "mbstring.func_overload" ) & 2 )
        {
            $this->_mbenc = mb_internal_encoding();
            mb_internal_encoding ( "latin1" );
        }
}

    /// leave mbstring workaround mode
    function _MBPop ()
    {
        if ( $this->_mbenc )
            mb_internal_encoding ( $this->_mbenc );
    }

    /// connect to searchd server
    function _Connect ()
    {
        $errno = 0;
        $errstr = "";
        if ( $this->_timeout<=0 )
            $fp = @fsockopen ( $this->_host, $this->_port, $errno, $errstr );
        else
            $fp = @fsockopen ( $this->_host, $this->_port, $errno, $errstr, $this->_timeout );

        if ( !$fp )
        {
            $errstr = trim ( $errstr );
            $this->_error = "connection to {$this->_host}:{$this->_port} failed (errno=$errno, msg=$errstr)";
            return false;
        }

        // check version
        list(,$v) = unpack ( "N*", fread ( $fp, 4 ) );
        $v = (int)$v;
        if ( $v<1 )
        {
            fclose ( $fp );
            $this->_error = "expected searchd protocol version 1+, got version '$v'";
            return false;
        }

        // all ok, send my version
        fwrite ( $fp, pack ( "N", 1 ) );
        return $fp;
    }

    /// get and check response packet from searchd server
    function _GetResponse ( $fp, $client_ver )
    {
        $response = "";
        $len = 0;

        $header = fread ( $fp, 8 );
        if ( strlen($header)==8 )
        {
            list ( $status, $ver, $len ) = array_values ( unpack ( "n2a/Nb", $header ) );
            $left = $len;
            while ( $left>0 && !feof($fp) )
            {
                $chunk = fread ( $fp, $left );
                if ( $chunk )
                {
                    $response .= $chunk;
                    $left -= strlen($chunk);
                }
            }
        }
        fclose ( $fp );

        // check response
        $read = strlen ( $response );
        if ( !$response || $read!=$len )
        {
            $this->_error = $len
                ? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=$read)"
                : "received zero-sized searchd response";
            return false;
        }

        // check status
        if ( $status==SEARCHD_WARNING )
        {
            list(,$wlen) = unpack ( "N*", substr ( $response, 0, 4 ) );
            $this->_warning = substr ( $response, 4, $wlen );
            return substr ( $response, 4+$wlen );
        }
        if ( $status==SEARCHD_ERROR )
        {
            $this->_error = "searchd error: " . substr ( $response, 4 );
            return false;
        }
        if ( $status==SEARCHD_RETRY )
        {
            $this->_error = "temporary searchd error: " . substr ( $response, 4 );
            return false;
        }
        if ( $status!=SEARCHD_OK )
        {
            $this->_error = "unknown status code '$status'";
            return false;
        }

        // check version
        if ( $ver<$client_ver )
        {
            $this->_warning = sprintf ( "searchd command v.%d.%d older than client's v.%d.%d, some options might not work",
                $ver>>8, $ver&0xff, $client_ver>>8, $client_ver&0xff );
        }

        return $response;
    }

    /////////////////////////////////////////////////////////////////////////////
    // searching
    /////////////////////////////////////////////////////////////////////////////

    /// set offset and count into result set,
    /// and optionally set max-matches and cutoff limits
    function SetLimits ( $offset, $limit, $max=0, $cutoff=0 )
    {
        assert ( is_int($offset) );
        assert ( is_int($limit) );
        assert ( $offset>=0 );
        assert ( $limit>0 );
        assert ( $max>=0 );
        $this->_offset = $offset;
        $this->_limit = $limit;
        if ( $max>0 )
            $this->_maxmatches = $max;
        if ( $cutoff>0 )
            $this->_cutoff = $cutoff;
    }

    /// set maximum query time, in milliseconds, per-index
    /// integer, 0 means "do not limit"
    function SetMaxQueryTime ( $max )
    {
        assert ( is_int($max) );
        assert ( $max>=0 );
        $this->_maxquerytime = $max;
    }

    /// set matching mode
    function SetMatchMode ( $mode )
    {
        assert ( $mode==SPH_MATCH_ALL
            || $mode==SPH_MATCH_ANY
            || $mode==SPH_MATCH_PHRASE
            || $mode==SPH_MATCH_BOOLEAN
            || $mode==SPH_MATCH_EXTENDED
            || $mode==SPH_MATCH_FULLSCAN
            || $mode==SPH_MATCH_EXTENDED2 );
        $this->_mode = $mode;
    }

    /// set ranking mode
    function SetRankingMode ( $ranker )
    {
        assert ( $ranker==SPH_RANK_PROXIMITY_BM25
            || $ranker==SPH_RANK_BM25
            || $ranker==SPH_RANK_NONE
            || $ranker==SPH_RANK_WORDCOUNT );
        $this->_ranker = $ranker;
    }

    /// set matches sorting mode
    function SetSortMode ( $mode, $sortby="" )
    {
        assert (
            $mode==SPH_SORT_RELEVANCE ||
            $mode==SPH_SORT_ATTR_DESC ||
            $mode==SPH_SORT_ATTR_ASC ||
            $mode==SPH_SORT_TIME_SEGMENTS ||
            $mode==SPH_SORT_EXTENDED ||
            $mode==SPH_SORT_EXPR );
        assert ( is_string($sortby) );
        assert ( $mode==SPH_SORT_RELEVANCE || strlen($sortby)>0 );

        $this->_sort = $mode;
        $this->_sortby = $sortby;
    }

    /// bind per-field weights by order
    /// DEPRECATED; use SetFieldWeights() instead
    function SetWeights ( $weights )
    {
        assert ( is_array($weights) );
        foreach ( $weights as $weight )
            assert ( is_int($weight) );

        $this->_weights = $weights;
    }

    /// bind per-field weights by name
    function SetFieldWeights ( $weights )
    {
        assert ( is_array($weights) );
        foreach ( $weights as $name=>$weight )
        {
            assert ( is_string($name) );
            assert ( is_int($weight) );
        }
        $this->_fieldweights = $weights;
    }

    /// bind per-index weights by name
    function SetIndexWeights ( $weights )
    {
        assert ( is_array($weights) );
        foreach ( $weights as $index=>$weight )
        {
            assert ( is_string($index) );
            assert ( is_int($weight) );
        }
        $this->_indexweights = $weights;
    }

    /// set IDs range to match
    /// only match records if document ID is beetwen $min and $max (inclusive)
    function SetIDRange ( $min, $max )
    {
        assert ( is_numeric($min) );
        assert ( is_numeric($max) );
        assert ( $min<=$max );
        $this->_min_id = $min;
        $this->_max_id = $max;
    }

    /// set values set filter
    /// only match records where $attribute value is in given set
    function SetFilter ( $attribute, $values, $exclude=false )
    {
        assert ( is_string($attribute) );
        assert ( is_array($values) );
        assert ( count($values) );

        if ( is_array($values) && count($values) )
        {
            foreach ( $values as $value )
                assert ( is_numeric($value) );

            $this->_filters[] = array ( "type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values );
        }
    }

    /// set range filter
    /// only match records if $attribute value is beetwen $min and $max (inclusive)
    function SetFilterRange ( $attribute, $min, $max, $exclude=false )
    {
        assert ( is_string($attribute) );
        assert ( is_int($min) );
        assert ( is_int($max) );
        assert ( $min<=$max );

        $this->_filters[] = array ( "type"=>SPH_FILTER_RANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max );
    }

    /// set float range filter
    /// only match records if $attribute value is beetwen $min and $max (inclusive)
    function SetFilterFloatRange ( $attribute, $min, $max, $exclude=false )
    {
        assert ( is_string($attribute) );
        assert ( is_float($min) );
        assert ( is_float($max) );
        assert ( $min<=$max );

        $this->_filters[] = array ( "type"=>SPH_FILTER_FLOATRANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max );
    }

    /// setup anchor point for geosphere distance calculations
    /// required to use @geodist in filters and sorting
    /// latitude and longitude must be in radians
    function SetGeoAnchor ( $attrlat, $attrlong, $lat, $long )
    {
        assert ( is_string($attrlat) );
        assert ( is_string($attrlong) );
        assert ( is_float($lat) );
        assert ( is_float($long) );

        $this->_anchor = array ( "attrlat"=>$attrlat, "attrlong"=>$attrlong, "lat"=>$lat, "long"=>$long );
    }

    /// set grouping attribute and function
    function SetGroupBy ( $attribute, $func, $groupsort="@group desc" )
    {
        assert ( is_string($attribute) );
        assert ( is_string($groupsort) );
        assert ( $func==SPH_GROUPBY_DAY
            || $func==SPH_GROUPBY_WEEK
            || $func==SPH_GROUPBY_MONTH
            || $func==SPH_GROUPBY_YEAR
            || $func==SPH_GROUPBY_ATTR
            || $func==SPH_GROUPBY_ATTRPAIR );

        $this->_groupby = $attribute;
        $this->_groupfunc = $func;
        $this->_groupsort = $groupsort;
    }

    /// set count-distinct attribute for group-by queries
    function SetGroupDistinct ( $attribute )
    {
        assert ( is_string($attribute) );
        $this->_groupdistinct = $attribute;
    }

    /// set distributed retries count and delay
    function SetRetries ( $count, $delay=0 )
    {
        assert ( is_int($count) && $count>=0 );
        assert ( is_int($delay) && $delay>=0 );
        $this->_retrycount = $count;
        $this->_retrydelay = $delay;
    }

    /// set result set format (hash or array; hash by default)
    /// PHP specific; needed for group-by-MVA result sets that may contain duplicate IDs
    function SetArrayResult ( $arrayresult )
    {
        assert ( is_bool($arrayresult) );
        $this->_arrayresult = $arrayresult;
    }

    //////////////////////////////////////////////////////////////////////////////

    /// clear all filters (for multi-queries)
    function ResetFilters ()
    {
        $this->_filters = array();
        $this->_anchor = array();
    }

    /// clear groupby settings (for multi-queries)
    function ResetGroupBy ()
    {
        $this->_groupby         = "";
        $this->_groupfunc     = SPH_GROUPBY_DAY;
        $this->_groupsort     = "@group desc";
        $this->_groupdistinct= "";
    }

    //////////////////////////////////////////////////////////////////////////////

    /// connect to searchd server, run given search query through given indexes,
    /// and return the search results
    function Query ( $query, $index="*", $comment="" )
    {
        assert ( empty($this->_reqs) );

        $this->AddQuery ( $query, $index, $comment );
        $results = $this->RunQueries ();
        $this->_reqs = array (); // just in case it failed too early

        if ( !is_array($results) )
            return false; // probably network error; error message should be already filled

        $this->_error = $results[0]["error"];
        $this->_warning = $results[0]["warning"];
        if ( $results[0]["status"]==SEARCHD_ERROR )
            return false;
        else
            return $results[0];
    }

    /// helper to pack floats in network byte order
    function _PackFloat ( $f )
    {
        $t1 = pack ( "f", $f ); // machine order
        list(,$t2) = unpack ( "L*", $t1 ); // int in machine order
        return pack ( "N", $t2 );
    }

    /// add query to multi-query batch
    /// returns index into results array from RunQueries() call
    function AddQuery ( $query, $index="*", $comment="" )
    {
        // mbstring workaround
        $this->_MBPush ();

        // build request
        $req = pack ( "NNNNN", $this->_offset, $this->_limit, $this->_mode, $this->_ranker, $this->_sort ); // mode and limits
        $req .= pack ( "N", strlen($this->_sortby) ) . $this->_sortby;
        $req .= pack ( "N", strlen($query) ) . $query; // query itself
        $req .= pack ( "N", count($this->_weights) ); // weights
        foreach ( $this->_weights as $weight )
            $req .= pack ( "N", (int)$weight );
        $req .= pack ( "N", strlen($index) ) . $index; // indexes
        $req .= pack ( "N", 1 ); // id64 range marker
        $req .= sphPack64 ( $this->_min_id ) . sphPack64 ( $this->_max_id ); // id64 range

        // filters
        $req .= pack ( "N", count($this->_filters) );
        foreach ( $this->_filters as $filter )
        {
            $req .= pack ( "N", strlen($filter["attr"]) ) . $filter["attr"];
            $req .= pack ( "N", $filter["type"] );
            switch ( $filter["type"] )
            {
                case SPH_FILTER_VALUES:
                    $req .= pack ( "N", count($filter["values"]) );
                    foreach ( $filter["values"] as $value )
                        $req .= pack ( "N", floatval($value) ); // this uberhack is to workaround 32bit signed int limit on x32 platforms
                    break;

                case SPH_FILTER_RANGE:
                    $req .= pack ( "NN", $filter["min"], $filter["max"] );
                    break;

                case SPH_FILTER_FLOATRANGE:
                    $req .= $this->_PackFloat ( $filter["min"] ) . $this->_PackFloat ( $filter["max"] );
                    break;

                default:
                    assert ( 0 && "internal error: unhandled filter type" );
            }
            $req .= pack ( "N", $filter["exclude"] );
        }

        // group-by clause, max-matches count, group-sort clause, cutoff count
        $req .= pack ( "NN", $this->_groupfunc, strlen($this->_groupby) ) . $this->_groupby;
        $req .= pack ( "N", $this->_maxmatches );
        $req .= pack ( "N", strlen($this->_groupsort) ) . $this->_groupsort;
        $req .= pack ( "NNN", $this->_cutoff, $this->_retrycount, $this->_retrydelay );
        $req .= pack ( "N", strlen($this->_groupdistinct) ) . $this->_groupdistinct;

        // anchor point
        if ( empty($this->_anchor) )
        {
            $req .= pack ( "N", 0 );
        } else
        {
            $a =& $this->_anchor;
            $req .= pack ( "N", 1 );
            $req .= pack ( "N", strlen($a["attrlat"]) ) . $a["attrlat"];
            $req .= pack ( "N", strlen($a["attrlong"]) ) . $a["attrlong"];
            $req .= $this->_PackFloat ( $a["lat"] ) . $this->_PackFloat ( $a["long"] );
        }

        // per-index weights
        $req .= pack ( "N", count($this->_indexweights) );
        foreach ( $this->_indexweights as $idx=>$weight )
            $req .= pack ( "N", strlen($idx) ) . $idx . pack ( "N", $weight );

        // max query time
        $req .= pack ( "N", $this->_maxquerytime );

        // per-field weights
        $req .= pack ( "N", count($this->_fieldweights) );
        foreach ( $this->_fieldweights as $field=>$weight )
            $req .= pack ( "N", strlen($field) ) . $field . pack ( "N", $weight );

        // comment
        $req .= pack ( "N", strlen($comment) ) . $comment;

        // mbstring workaround
        $this->_MBPop ();

        // store request to requests array
        $this->_reqs[] = $req;
        return count($this->_reqs)-1;
    }

    /// connect to searchd, run queries batch, and return an array of result sets
    function RunQueries ()
    {
        if ( empty($this->_reqs) )
        {
            $this->_error = "no queries defined, issue AddQuery() first";
            return false;
        }

        // mbstring workaround
        $this->_MBPush ();

        if (!( $fp = $this->_Connect() ))
        {
            $this->_MBPop ();
            return false;
        }

        ////////////////////////////
        // send query, get response
        ////////////////////////////

        $nreqs = count($this->_reqs);
        $req = join ( "", $this->_reqs );
        $len = 4+strlen($req);
        $req = pack ( "nnNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, $nreqs ) . $req; // add header

        fwrite ( $fp, $req, $len+8 );
        if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_SEARCH ) ))
        {
            $this->_MBPop ();
            return false;
        }

        $this->_reqs = array ();

        //////////////////
        // parse response
        //////////////////

        $p = 0; // current position
        $max = strlen($response); // max position for checks, to protect against broken responses

        $results = array ();
        for ( $ires=0; $ires<$nreqs && $p<$max; $ires++ )
        {
            $results[] = array();
            $result =& $results[$ires];

            $result["error"] = "";
            $result["warning"] = "";

            // extract status
            list(,$status) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
            $result["status"] = $status;
            if ( $status!=SEARCHD_OK )
            {
                list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                $message = substr ( $response, $p, $len ); $p += $len;

                if ( $status==SEARCHD_WARNING )
                {
                    $result["warning"] = $message;
                } else
                {
                    $result["error"] = $message;
                    continue;
                }
            }

            // read schema
            $fields = array ();
            $attrs = array ();

            list(,$nfields) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
            while ( $nfields-->0 && $p<$max )
            {
                list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                $fields[] = substr ( $response, $p, $len ); $p += $len;
            }
            $result["fields"] = $fields;

            list(,$nattrs) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
            while ( $nattrs-->0 && $p<$max )
            {
                list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                $attr = substr ( $response, $p, $len ); $p += $len;
                list(,$type) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                $attrs[$attr] = $type;
            }
            $result["attrs"] = $attrs;

            // read match count
            list(,$count) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
            list(,$id64) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;

            // read matches
            $idx = -1;
            while ( $count-->0 && $p<$max )
            {
                // index into result array
                $idx++;

                // parse document id and weight
                if ( $id64 )
                {
                    $doc = sphUnpack64 ( substr ( $response, $p, 8 ) ); $p += 8;
                    list(,$weight) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                } else
                {
                    list ( $doc, $weight ) = array_values ( unpack ( "N*N*",
                        substr ( $response, $p, 8 ) ) );
                    $p += 8;

                    if ( PHP_INT_SIZE>=8 )
                    {
                        // x64 route, workaround broken unpack() in 5.2.2+
                        if ( $doc<0 ) $doc += (1<<32);
                    } else
                    {
                        // x32 route, workaround php signed/unsigned braindamage
                        $doc = sprintf ( "%u", $doc );
                    }
                }
                $weight = sprintf ( "%u", $weight );

                // create match entry
                if ( $this->_arrayresult )
                    $result["matches"][$idx] = array ( "id"=>$doc, "weight"=>$weight );
                else
                    $result["matches"][$doc]["weight"] = $weight;

                // parse and create attributes
                $attrvals = array ();
                foreach ( $attrs as $attr=>$type )
                {
                    // handle floats
                    if ( $type==SPH_ATTR_FLOAT )
                    {
                        list(,$uval) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                        list(,$fval) = unpack ( "f*", pack ( "L", $uval ) );
                        $attrvals[$attr] = $fval;
                        continue;
                    }

                    // handle everything else as unsigned ints
                    list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                    if ( $type & SPH_ATTR_MULTI )
                    {
                        $attrvals[$attr] = array ();
                        $nvalues = $val;
                        while ( $nvalues-->0 && $p<$max )
                        {
                            list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                            $attrvals[$attr][] = sprintf ( "%u", $val );
                        }
                    } else
                    {
                        $attrvals[$attr] = sprintf ( "%u", $val );
                    }
                }

                if ( $this->_arrayresult )
                    $result["matches"][$idx]["attrs"] = $attrvals;
                else
                    $result["matches"][$doc]["attrs"] = $attrvals;
            }

            list ( $total, $total_found, $msecs, $words ) =
                array_values ( unpack ( "N*N*N*N*", substr ( $response, $p, 16 ) ) );
            $result["total"] = sprintf ( "%u", $total );
            $result["total_found"] = sprintf ( "%u", $total_found );
            $result["time"] = sprintf ( "%.3f", $msecs/1000 );
            $p += 16;

            while ( $words-->0 && $p<$max )
            {
                list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                $word = substr ( $response, $p, $len ); $p += $len;
                list ( $docs, $hits ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8;
                $result["words"][$word] = array (
                    "docs"=>sprintf ( "%u", $docs ),
                    "hits"=>sprintf ( "%u", $hits ) );
            }
        }

        $this->_MBPop ();
        return $results;
    }

    /////////////////////////////////////////////////////////////////////////////
    // excerpts generation
    /////////////////////////////////////////////////////////////////////////////

    /// connect to searchd server, and generate exceprts (snippets)
    /// of given documents for given query. returns false on failure,
    /// an array of snippets on success
    function BuildExcerpts ( $docs, $index, $words, $opts=array() )
    {
        assert ( is_array($docs) );
        assert ( is_string($index) );
        assert ( is_string($words) );
        assert ( is_array($opts) );

        $this->_MBPush ();

        if (!( $fp = $this->_Connect() ))
        {
            $this->_MBPop();
            return false;
        }

        /////////////////
        // fixup options
        /////////////////

        if ( !isset($opts["before_match"]) )         $opts["before_match"] = "<b>";
        if ( !isset($opts["after_match"]) )             $opts["after_match"] = "</b>";
        if ( !isset($opts["chunk_separator"]) )         $opts["chunk_separator"] = " ... ";
        if ( !isset($opts["limit"]) )                 $opts["limit"] = 256;
        if ( !isset($opts["around"]) )                 $opts["around"] = 5;
        if ( !isset($opts["exact_phrase"]) )         $opts["exact_phrase"] = false;
        if ( !isset($opts["single_passage"]) )         $opts["single_passage"] = false;
        if ( !isset($opts["use_boundaries"]) )         $opts["use_boundaries"] = false;
        if ( !isset($opts["weight_order"]) )         $opts["weight_order"] = false;

        /////////////////
        // build request
        /////////////////

        // v.1.0 req
        $flags = 1; // remove spaces
        if ( $opts["exact_phrase"] )     $flags |= 2;
        if ( $opts["single_passage"] )     $flags |= 4;
        if ( $opts["use_boundaries"] )     $flags |= 8;
        if ( $opts["weight_order"] )     $flags |= 16;
        $req = pack ( "NN", 0, $flags ); // mode=0, flags=$flags
        $req .= pack ( "N", strlen($index) ) . $index; // req index
        $req .= pack ( "N", strlen($words) ) . $words; // req words

        // options
        $req .= pack ( "N", strlen($opts["before_match"]) ) . $opts["before_match"];
        $req .= pack ( "N", strlen($opts["after_match"]) ) . $opts["after_match"];
        $req .= pack ( "N", strlen($opts["chunk_separator"]) ) . $opts["chunk_separator"];
        $req .= pack ( "N", (int)$opts["limit"] );
        $req .= pack ( "N", (int)$opts["around"] );

        // documents
        $req .= pack ( "N", count($docs) );
        foreach ( $docs as $doc )
        {
            assert ( is_string($doc) );
            $req .= pack ( "N", strlen($doc) ) . $doc;
        }

        ////////////////////////////
        // send query, get response
        ////////////////////////////

        $len = strlen($req);
        $req = pack ( "nnN", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $len ) . $req; // add header
        $wrote = fwrite ( $fp, $req, $len+8 );
        if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_EXCERPT ) ))
        {
            $this->_MBPop ();
            return false;
        }

        //////////////////
        // parse response
        //////////////////

        $pos = 0;
        $res = array ();
        $rlen = strlen($response);
        for ( $i=0; $i<count($docs); $i++ )
        {
            list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) );
            $pos += 4;

            if ( $pos+$len > $rlen )
            {
                $this->_error = "incomplete reply";
                $this->_MBPop ();
                return false;
            }
            $res[] = $len ? substr ( $response, $pos, $len ) : "";
            $pos += $len;
        }

        $this->_MBPop ();
        return $res;
    }


    /////////////////////////////////////////////////////////////////////////////
    // keyword generation
    /////////////////////////////////////////////////////////////////////////////

    /// connect to searchd server, and generate keyword list for a given query
    /// returns false on failure,
    /// an array of words on success
    function BuildKeywords ( $query, $index, $hits )
    {
        assert ( is_string($query) );
        assert ( is_string($index) );
        assert ( is_bool($hits) );

        $this->_MBPush ();

        if (!( $fp = $this->_Connect() ))
        {
            $this->_MBPop();
            return false;
        }

        /////////////////
        // build request
        /////////////////

        // v.1.0 req
        $req = pack ( "N", strlen($query) ) . $query; // req query
        $req .= pack ( "N", strlen($index) ) . $index; // req index
        $req .= pack ( "N", (int)$hits );

        ////////////////////////////
        // send query, get response
        ////////////////////////////

        $len = strlen($req);
        $req = pack ( "nnN", SEARCHD_COMMAND_KEYWORDS, VER_COMMAND_KEYWORDS, $len ) . $req; // add header
        $wrote = fwrite ( $fp, $req, $len+8 );
        if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_KEYWORDS ) ))
        {
            $this->_MBPop ();
            return false;
        }

        //////////////////
        // parse response
        //////////////////

        $pos = 0;
        $res = array ();
        $rlen = strlen($response);
        list(,$nwords) = unpack ( "N*", substr ( $response, $pos, 4 ) );
        $pos += 4;
        for ( $i=0; $i<$nwords; $i++ )
        {
            list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) );     $pos += 4;
            $tokenized = $len ? substr ( $response, $pos, $len ) : "";
            $pos += $len;

            list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) );     $pos += 4;
            $normalized = $len ? substr ( $response, $pos, $len ) : "";
            $pos += $len;

            $res[] = array ( "tokenized"=>$tokenized, "normalized"=>$normalized );

            if ( $hits )
            {
                list($ndocs,$nhits) = array_values ( unpack ( "N*N*", substr ( $response, $pos, 8 ) ) );
                $pos += 8;
                $res [$i]["docs"] = $ndocs;
                $res [$i]["hits"] = $nhits;
            }

            if ( $pos > $rlen )
            {
                $this->_error = "incomplete reply";
                $this->_MBPop ();
                return false;
            }
        }

        $this->_MBPop ();
        return $res;
    }

    function EscapeString ( $string )
    {
        $from = array ( '(',')','|','-','!','@','~','"','&', '/' );
        $to = array ( '\(','\)','\|','\-','\!','\@','\~','\"', '\&', '\/' );

        return str_replace ( $from, $to, $string );
    }

    /////////////////////////////////////////////////////////////////////////////
    // attribute updates
    /////////////////////////////////////////////////////////////////////////////

    /// update given attribute values on given documents in given indexes
    /// returns amount of updated documents (0 or more) on success, or -1 on failure
    function UpdateAttributes ( $index, $attrs, $values )
    {
        // verify everything
        assert ( is_string($index) );

        assert ( is_array($attrs) );
        foreach ( $attrs as $attr )
            assert ( is_string($attr) );

        assert ( is_array($values) );
        foreach ( $values as $id=>$entry )
        {
            assert ( is_numeric($id) );
            assert ( is_array($entry) );
            assert ( count($entry)==count($attrs) );
            foreach ( $entry as $v )
                assert ( is_int($v) );
        }

        // build request
        $req = pack ( "N", strlen($index) ) . $index;

        $req .= pack ( "N", count($attrs) );
        foreach ( $attrs as $attr )
            $req .= pack ( "N", strlen($attr) ) . $attr;

        $req .= pack ( "N", count($values) );
        foreach ( $values as $id=>$entry )
        {
            $req .= sphPack64 ( $id );
            foreach ( $entry as $v )
                $req .= pack ( "N", $v );
        }

        // mbstring workaround
        $this->_MBPush ();

        // connect, send query, get response
        if (!( $fp = $this->_Connect() ))
        {
            $this->_MBPop ();
            return -1;
        }

        $len = strlen($req);
        $req = pack ( "nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len ) . $req; // add header
        fwrite ( $fp, $req, $len+8 );

        if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_UPDATE ) ))
        {
            $this->_MBPop ();
            return -1;
        }

        // parse response
        list(,$updated) = unpack ( "N*", substr ( $response, 0, 4 ) );
        $this->_MBPop ();
        return $updated;
    }
}

//
// $Id: sphinxapi.php 1418 2008-08-28 15:30:05Z shodan $
//

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/563

Posted by 프로그래머

2009/01/20 08:50 2009/01/20 08:50
, , , , , , , , ,
Response
No Trackback , No Comment
RSS :
http://hompy.info/rss/response/563

아래 소개된 소스는 웹 기반의 WYSIWYG 에디터 중에서 많이 언급되고 있는 FCKeditor를 간단하게 웹게시판의 입력폼으로 구성한 예제 소스 코드입니다. FCKeditor는 스킨을 손쉽게 교체할 수 있도록 설계 되어 있으며 예제에서는 MS오피스20003 스타일로 스킨을 바꿔서 사용하고 있습니다. 이런 류의 웹에디터는 국내에서도 네이버가 스마트 에디터를 얼마 전부터 오픈 소스로 공개하고 있다고 하니 참고하세요.

[샘플 소스 실행 화면]

[editor/demo.php]
<?php
include("fckeditor/fckeditor.php");
$editor_path = "/fckeditor/";
$editor = new FCKeditor('my_content');
$editor->BasePath     = $editor_path;
$editor->Config['SkinPath']     = $editor_path . "editor/skins/office2003/";
//$editor->ToolbarSet = "Basic";
$editor->Value         = $_POST[my_content];
$editor->Width         = 580;
$editor->Height         = 300;
?>
<HTML>
<HEAD>
<TITLE>FCKeditor Demo</TITLE>
<STYLE>TD,INPUT {font-size:12px;}</STYLE>
</HEAD>
<BODY>
<FORM method="POST" action="?" name="my_form" >
<INPUT type="HIDDEN" name="my_seq" value="<?=$_POST[my_seq];?>" />
<TABLE cellpadding=0 cellspacing=1 border=0>
<TR>
    <TD width=40>제목</TD>
    <TD>
        <INPUT type="TEXT" name="my_title" size="80" value="<?=$_POST[my_title];?>" class="" />
        <INPUT type="SUBMIT" value="문서저장">
    </TD>
</TR>
<TR><TD colspan=2><? $editor->Create(); ?></TD></TR>
</TABLE>
</FORM>
</BODY>
</HTML>

[FCKeditor 데모 실행]
http://www.fckeditor.net/demo/

[editor/fckeditor/fckeditor_php5.php]
<?php
/*
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
*/

class FCKeditor
{
    /**
    * Name of the FCKeditor instance.
    *
    * @access protected
    * @var string
    */
    public $InstanceName ;
    /**
    * Path to FCKeditor relative to the document root.
    *
    * @var string
    */
    public $BasePath ;
    /**
    * Width of the FCKeditor.
    * Examples: 100%, 600
    *
    * @var mixed
    */
    public $Width ;
    /**
    * Height of the FCKeditor.
    * Examples: 400, 50%
    *
    * @var mixed
    */
    public $Height ;
    /**
    * Name of the toolbar to load.
    *
    * @var string
    */
    public $ToolbarSet ;
    /**
    * Initial value.
    *
    * @var string
    */
    public $Value ;
    /**
    * This is where additional configuration can be passed.
    * Example:
    * $oFCKeditor->Config['EnterMode'] = 'br';
    *
    * @var array
    */
    public $Config ;

    /**
    * Main Constructor.
    * Refer to the _samples/php directory for examples.
    *
    * @param string $instanceName
    */
    public function __construct( $instanceName )
    {
        $this->InstanceName     = $instanceName ;
        $this->BasePath         = '/fckeditor/' ;
        $this->Width         = '100%' ;
        $this->Height         = '200' ;
        $this->ToolbarSet     = 'Default' ;
        $this->Value         = '' ;

        $this->Config         = array() ;
    }

    /**
    * Display FCKeditor.
    *
    */
    public function Create()
    {
        echo $this->CreateHtml() ;
    }

    /**
    * Return the HTML code required to run FCKeditor.
    *
    * @return string
    */
    public function CreateHtml()
    {
        $HtmlValue = htmlspecialchars( $this->Value ) ;

        $Html = '' ;

        if ( $this->IsCompatible() )
        {
            if ( isset( $_GET['fcksource'] ) && $_GET['fcksource'] == "true" )
                $File = 'fckeditor.original.html' ;
            else
                $File = 'fckeditor.html' ;

            $Link = "{$this->BasePath}editor/{$File}?InstanceName={$this->InstanceName}" ;

            if ( $this->ToolbarSet != '' )
                $Link .= "&amp;Toolbar={$this->ToolbarSet}" ;

            // Render the linked hidden field.
            $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}\" name=\"{$this->InstanceName}\" value=\"{$HtmlValue}\" style=\"display:none\" />" ;

            // Render the configurations hidden field.
            $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}___Config\" value=\"" . $this->GetConfigFieldString() . "\" style=\"display:none\" />" ;

            // Render the editor IFRAME.
            $Html .= "<iframe id=\"{$this->InstanceName}___Frame\" src=\"{$Link}\" width=\"{$this->Width}\" height=\"{$this->Height}\" frameborder=\"0\" scrolling=\"no\"></iframe>" ;
        }
        else
        {
            if ( strpos( $this->Width, '%' ) === false )
                $WidthCSS = $this->Width . 'px' ;
            else
                $WidthCSS = $this->Width ;

            if ( strpos( $this->Height, '%' ) === false )
                $HeightCSS = $this->Height . 'px' ;
            else
                $HeightCSS = $this->Height ;

            $Html .= "<textarea name=\"{$this->InstanceName}\" rows=\"4\" cols=\"40\" style=\"width: {$WidthCSS}; height: {$HeightCSS}\">{$HtmlValue}</textarea>" ;
        }

        return $Html ;
    }

    /**
    * Returns true if browser is compatible with FCKeditor.
    *
    * @return boolean
    */
    public function IsCompatible()
    {
        return FCKeditor_IsCompatibleBrowser() ;
    }

    /**
    * Get settings from Config array as a single string.
    *
    * @access protected
    * @return string
    */
    public function GetConfigFieldString()
    {
        $sParams = '' ;
        $bFirst = true ;

        foreach ( $this->Config as $sKey => $sValue )
        {
            if ( $bFirst == false )
                $sParams .= '&amp;' ;
            else
                $bFirst = false ;

            if ( $sValue === true )
                $sParams .= $this->EncodeConfig( $sKey ) . '=true' ;
            else if ( $sValue === false )
                $sParams .= $this->EncodeConfig( $sKey ) . '=false' ;
            else
                $sParams .= $this->EncodeConfig( $sKey ) . '=' . $this->EncodeConfig( $sValue ) ;
        }

        return $sParams ;
    }

    /**
    * Encode characters that may break the configuration string
    * generated by GetConfigFieldString().
    *
    * @access protected
    * @param string $valueToEncode
    * @return string
    */
    public function EncodeConfig( $valueToEncode )
    {
        $chars = array(
            '&' => '%26',
            '=' => '%3D',
            '"' => '%22' ) ;

        return strtr( $valueToEncode, $chars ) ;
    }
}

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/562

Posted by 프로그래머

2009/01/18 17:00 2009/01/18 17:00

엑셀 2003 통합 포멧 문서 파일(.xls)을 읽어올 수 있도록 공개된 오픈 소스 라이브러리를 이용해서 엑셀 문서 첫번째 Sheet 에 있는 각 Cell의 Text 데이타들을 MySQL 데이타베이스에 등록하는 소스 코드입니다. 서비스를 운영하다 보면 대량의 데이터를 일괄 등록해야 할 때가 있는데 엑셀 업로드를 응용하면 유용하므로 대량의 데이터를 다룰 때 활용하면 좋을 것입니다.
참고로 후반부에 두가지 예제는 Excel.Application 을 활용해서 엑셀 문서를 제어하는 예제입니다. 윈도우즈 환경에서 PHP 를 사용하는 경우가 드물기 때문에 잘 활용되지 않을 수 있습니다.

[excel2db.php]
<?php
$DB = array();
$DB["host"] = "192.168.10.10";
$DB["user"] = "excel";
$DB["pass"] = "password";
$DB["name"] = "excel";
$DB["conn"] = mysql_connect($DB["host"], $DB["user"], $DB["pass"]) or die("ERROR");
mysql_select_db($DB["name"], $DB["conn"]) or die("ERROR");
mysql_query('SET NAMES utf8',$DB["conn"]);
require_once "Excel/reader.php";
$data = new Spreadsheet_Excel_Reader();
$data->read("sample.xls");
$data->setOutputEncoding("UTF-8//IGNORE");
for ($i = 1; $i <= $data->sheets[0]["numRows"]; $i++){
    $my_name = $data->sheets[0]["cells"][$i][1];
    $my_email = $data->sheets[0]["cells"][$i][2];
    $query = "insert into my_user set my_name='{$my_name}', my_email='{$my_email}'";
    $DB["result"] = mysql_query($query, $DB["conn"]);
}
mysql_close($DB["conn"]);
?>

[Excel/reader.php]
http://sourceforge.net/projects/phpexcelreader
<?php

//require_once 'PEAR.php';
require_once 'Excel/oleread.inc';

//define('Spreadsheet_Excel_Reader_HAVE_ICONV', function_exists('iconv'));
//define('Spreadsheet_Excel_Reader_HAVE_MB', function_exists('mb_convert_encoding'));

define('Spreadsheet_Excel_Reader_BIFF8', 0x600);
define('Spreadsheet_Excel_Reader_BIFF7', 0x500);
define('Spreadsheet_Excel_Reader_WorkbookGlobals', 0x5);
define('Spreadsheet_Excel_Reader_Worksheet', 0x10);

define('Spreadsheet_Excel_Reader_Type_BOF', 0x809);
define('Spreadsheet_Excel_Reader_Type_EOF', 0x0a);
define('Spreadsheet_Excel_Reader_Type_BOUNDSHEET', 0x85);
define('Spreadsheet_Excel_Reader_Type_DIMENSION', 0x200);
define('Spreadsheet_Excel_Reader_Type_ROW', 0x208);
define('Spreadsheet_Excel_Reader_Type_DBCELL', 0xd7);
define('Spreadsheet_Excel_Reader_Type_FILEPASS', 0x2f);
define('Spreadsheet_Excel_Reader_Type_NOTE', 0x1c);
define('Spreadsheet_Excel_Reader_Type_TXO', 0x1b6);
define('Spreadsheet_Excel_Reader_Type_RK', 0x7e);
define('Spreadsheet_Excel_Reader_Type_RK2', 0x27e);
define('Spreadsheet_Excel_Reader_Type_MULRK', 0xbd);
define('Spreadsheet_Excel_Reader_Type_MULBLANK', 0xbe);
define('Spreadsheet_Excel_Reader_Type_INDEX', 0x20b);
define('Spreadsheet_Excel_Reader_Type_SST', 0xfc);
define('Spreadsheet_Excel_Reader_Type_EXTSST', 0xff);
define('Spreadsheet_Excel_Reader_Type_CONTINUE', 0x3c);
define('Spreadsheet_Excel_Reader_Type_LABEL', 0x204);
define('Spreadsheet_Excel_Reader_Type_LABELSST', 0xfd);
define('Spreadsheet_Excel_Reader_Type_NUMBER', 0x203);
define('Spreadsheet_Excel_Reader_Type_NAME', 0x18);
define('Spreadsheet_Excel_Reader_Type_ARRAY', 0x221);
define('Spreadsheet_Excel_Reader_Type_STRING', 0x207);
define('Spreadsheet_Excel_Reader_Type_FORMULA', 0x406);
define('Spreadsheet_Excel_Reader_Type_FORMULA2', 0x6);
define('Spreadsheet_Excel_Reader_Type_FORMAT', 0x41e);
define('Spreadsheet_Excel_Reader_Type_XF', 0xe0);
define('Spreadsheet_Excel_Reader_Type_BOOLERR', 0x205);
define('Spreadsheet_Excel_Reader_Type_UNKNOWN', 0xffff);
define('Spreadsheet_Excel_Reader_Type_NINETEENFOUR', 0x22);
define('Spreadsheet_Excel_Reader_Type_MERGEDCELLS', 0xE5);

define('Spreadsheet_Excel_Reader_utcOffsetDays' , 25569);
define('Spreadsheet_Excel_Reader_utcOffsetDays1904', 24107);
define('Spreadsheet_Excel_Reader_msInADay', 24 * 60 * 60);

//define('Spreadsheet_Excel_Reader_DEF_NUM_FORMAT', "%.2f");
define('Spreadsheet_Excel_Reader_DEF_NUM_FORMAT', "%s");

// function file_get_contents for PHP < 4.3.0
// Thanks Marian Steinbach for this function
if (!function_exists('file_get_contents')) {
    function file_get_contents($filename, $use_include_path = 0) {
        $data = '';
        $file = @fopen($filename, "rb", $use_include_path);
        if ($file) {
            while (!feof($file)) $data .= fread($file, 1024);
            fclose($file);
        } else {
            // There was a problem opening the file
            $data = FALSE;
        }
        return $data;
    }
}


//class Spreadsheet_Excel_Reader extends PEAR {
class Spreadsheet_Excel_Reader {

    var $boundsheets = array();
    var $formatRecords = array();
    var $sst = array();
    var $sheets = array();
    var $data;
    var $pos;
    var $_ole;
    var $_defaultEncoding;
    var $_defaultFormat = Spreadsheet_Excel_Reader_DEF_NUM_FORMAT;
    var $_columnsFormat = array();
    var $_rowoffset = 1;
    var $_coloffset = 1;
   
    var $dateFormats = array (
        0xe => "d/m/Y",
        0xf => "d-M-Y",
        0x10 => "d-M",
        0x11 => "M-Y",
        0x12 => "h:i a",
        0x13 => "h:i:s a",
        0x14 => "H:i",
        0x15 => "H:i:s",
        0x16 => "d/m/Y H:i",
        0x2d => "i:s",
        0x2e => "H:i:s",
        0x2f => "i:s.S");

    var $numberFormats = array(
        0x1 => "%1.0f", // "0"
        0x2 => "%1.2f", // "0.00",
        0x3 => "%1.0f", //"#,##0",
        0x4 => "%1.2f", //"#,##0.00",
        0x5 => "%1.0f", /*"$#,##0;($#,##0)",*/
        0x6 => '$%1.0f', /*"$#,##0;($#,##0)",*/
        0x7 => '$%1.2f', //"$#,##0.00;($#,##0.00)",
        0x8 => '$%1.2f', //"$#,##0.00;($#,##0.00)",
        0x9 => '%1.0f%%', // "0%"
        0xa => '%1.2f%%', // "0.00%"
        0xb => '%1.2f', // 0.00E00",
        0x25 => '%1.0f', // "#,##0;(#,##0)",
        0x26 => '%1.0f', //"#,##0;(#,##0)",
        0x27 => '%1.2f', //"#,##0.00;(#,##0.00)",
        0x28 => '%1.2f', //"#,##0.00;(#,##0.00)",
        0x29 => '%1.0f', //"#,##0;(#,##0)",
        0x2a => '$%1.0f', //"$#,##0;($#,##0)",
        0x2b => '%1.2f', //"#,##0.00;(#,##0.00)",
        0x2c => '$%1.2f', //"$#,##0.00;($#,##0.00)",
        0x30 => '%1.0f'); //"##0.0E0";

    function Spreadsheet_Excel_Reader(){
        $this->_ole =& new OLERead();
        $this->setUTFEncoder('iconv');

    }

    function setOutputEncoding($Encoding){
        $this->_defaultEncoding = $Encoding;
    }

    /**
    * $encoder = 'iconv' or 'mb'
    * set iconv if you would like use 'iconv' for encode UTF-16LE to your encoding
    * set mb if you would like use 'mb_convert_encoding' for encode UTF-16LE to your encoding
    */
    function setUTFEncoder($encoder = 'iconv'){
        $this->_encoderFunction = '';
        if ($encoder == 'iconv'){
            $this->_encoderFunction = function_exists('iconv') ? 'iconv' : '';
        }elseif ($encoder == 'mb') {
            $this->_encoderFunction = function_exists('mb_convert_encoding') ? 'mb_convert_encoding' : '';
        }
    }

    function setRowColOffset($iOffset){
        $this->_rowoffset = $iOffset;
        $this->_coloffset = $iOffset;
    }

    function setDefaultFormat($sFormat){
        $this->_defaultFormat = $sFormat;
    }

    function setColumnFormat($column, $sFormat){
        $this->_columnsFormat[$column] = $sFormat;
    }


    function read($sFileName) {
        $errlevel = error_reporting();
        error_reporting($errlevel ^ E_NOTICE);
        $res = $this->_ole->read($sFileName);
       
        // oops, something goes wrong (Darko Miljanovic)
        if($res === false) {
            // check error code
            if($this->_ole->error == 1) {
            // bad file
                die('The filename ' . $sFileName . ' is not readable');    
            }
            // check other error codes here (eg bad fileformat, etc...)
        }

        $this->data = $this->_ole->getWorkBook();

       
        /*
        $res = $this->_ole->read($sFileName);

        if ($this->isError($res)) {
//         var_dump($res);        
            return $this->raiseError($res);
        }

        $total = $this->_ole->ppsTotal();
        for ($i = 0; $i < $total; $i++) {
            if ($this->_ole->isFile($i)) {
                $type = unpack("v", $this->_ole->getData($i, 0, 2));
                if ($type[''] == 0x0809) { // check if it's a BIFF stream
                    $this->_index = $i;
                    $this->data = $this->_ole->getData($i, 0, $this->_ole->getDataLength($i));
                    break;
                }
            }
        }

        if ($this->_index === null) {
            return $this->raiseError("$file doesn't seem to be an Excel file");
        }
       
        */
       
        //var_dump($this->data);
    //echo "data =".$this->data;    
        $this->pos = 0;
        //$this->readRecords();
        $this->_parse();
        error_reporting($errlevel);

    }

    function _parse(){
        $pos = 0;

        $code = ord($this->data[$pos]) | ord($this->data[$pos+1])<<8;
        $length = ord($this->data[$pos+2]) | ord($this->data[$pos+3])<<8;

        $version = ord($this->data[$pos + 4]) | ord($this->data[$pos + 5])<<8;
        $substreamType = ord($this->data[$pos + 6]) | ord($this->data[$pos + 7])<<8;
        //echo "Start parse code=".base_convert($code,10,16)." version=".base_convert($version,10,16)." substreamType=".base_convert($substreamType,10,16).""."\n";

        if (($version != Spreadsheet_Excel_Reader_BIFF8) && ($version != Spreadsheet_Excel_Reader_BIFF7)) {
            return false;
        }

        if ($substreamType != Spreadsheet_Excel_Reader_WorkbookGlobals){
            return false;
        }

        //print_r($rec);
        $pos += $length + 4;

        $code = ord($this->data[$pos]) | ord($this->data[$pos+1])<<8;
        $length = ord($this->data[$pos+2]) | ord($this->data[$pos+3])<<8;

        while ($code != Spreadsheet_Excel_Reader_Type_EOF){
            switch ($code) {
                case Spreadsheet_Excel_Reader_Type_SST:
                    //echo "Type_SST\n";
                    $spos = $pos + 4;
                    $limitpos = $spos + $length;
                    $uniqueStrings = $this->_GetInt4d($this->data, $spos+4);
                                                $spos += 8;
                                    for ($i = 0; $i < $uniqueStrings; $i++) {
        // Read in the number of characters
                                                if ($spos == $limitpos) {
                                                $opcode = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                                                $conlength = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                                                        if ($opcode != 0x3c) {
                                                                return -1;
                                                        }
                                                $spos += 4;
                                                $limitpos = $spos + $conlength;
                                                }
                                                $numChars = @ord($this->data[$spos]) | (@ord($this->data[$spos+1]) << 8);
                                                //echo "i = $i pos = $pos numChars = $numChars ";
                                                $spos += 2;
                                                $optionFlags = @ord($this->data[$spos]);
                                                $spos++;
                                        $asciiEncoding = (($optionFlags & 0x01) == 0) ;
                                                $extendedString = ( ($optionFlags & 0x04) != 0);

                                                // See if string contains formatting information
                                                $richString = ( ($optionFlags & 0x08) != 0);

                                                if ($richString) {
                                        // Read in the crun
                                                        $formattingRuns = ord($this->data[$spos]) | (ord($this->data[$spos+1]) << 8);
                                                        $spos += 2;
                                                }

                                                if ($extendedString) {
                                                // Read in cchExtRst
                                                $extendedRunLength = $this->_GetInt4d($this->data, $spos);
                                                $spos += 4;
                                                }

                                                $len = ($asciiEncoding)? $numChars : $numChars*2;
                                                if ($spos + $len < $limitpos) {
                                                                $retstr = substr($this->data, $spos, $len);
                                                                $spos += $len;
                                                }else{
                                                        // found countinue
                                                        $retstr = substr($this->data, $spos, $limitpos - $spos);
                                                        $bytesRead = $limitpos - $spos;
                                                        $charsLeft = $numChars - (($asciiEncoding) ? $bytesRead : ($bytesRead / 2));
                                                        $spos = $limitpos;

                                                        while ($charsLeft > 0){
                                                                $opcode = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                                                                $conlength = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                                                                        if ($opcode != 0x3c) {
                                                                                return -1;
                                                                        }
                                                                $spos += 4;
                                                                $limitpos = $spos + $conlength;
                                                                $option = ord($this->data[$spos]);
                                                                $spos += 1;
                                                                if ($asciiEncoding && ($option == 0)) {
                                                                                $len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength);
                                                                    $retstr .= substr($this->data, $spos, $len);
                                                                    $charsLeft -= $len;
                                                                    $asciiEncoding = true;
                                                                }elseif (!$asciiEncoding && ($option != 0)){
                                                                                $len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength);
                                                                    $retstr .= substr($this->data, $spos, $len);
                                                                    $charsLeft -= $len/2;
                                                                    $asciiEncoding = false;
                                                                }elseif (!$asciiEncoding && ($option == 0)) {
                                                                // Bummer - the string starts off as Unicode, but after the
                                                                // continuation it is in straightforward ASCII encoding
                                                                                $len = min($charsLeft, $limitpos - $spos); // min($charsLeft, $conlength);
                                                                        for ($j = 0; $j < $len; $j++) {
                                                                $retstr .= $this->data[$spos + $j].chr(0);
                                                                }
                                                            $charsLeft -= $len;
                                                                $asciiEncoding = false;
                                                                }else{
                                                            $newstr = '';
                                                                    for ($j = 0; $j < strlen($retstr); $j++) {
                                                                    $newstr = $retstr[$j].chr(0);
                                                                    }
                                                                    $retstr = $newstr;
                                                                                $len = min($charsLeft * 2, $limitpos - $spos); // min($charsLeft, $conlength);
                                                                    $retstr .= substr($this->data, $spos, $len);
                                                                    $charsLeft -= $len/2;
                                                                    $asciiEncoding = false;
                                                                        //echo "Izavrat\n";
                                                                }
                                                        $spos += $len;

                                                        }
                                                }
                                                $retstr = ($asciiEncoding) ? $retstr : $this->_encodeUTF16($retstr);
//                                             echo "Str $i = $retstr\n";
                                        if ($richString){
                                                $spos += 4 * $formattingRuns;
                                                }

                                                // For extended strings, skip over the extended string data
                                                if ($extendedString) {
                                                $spos += $extendedRunLength;
                                                }
                                                        //if ($retstr == 'Derby'){
                                                        //     echo "bb\n";
                                                        //}
                                                $this->sst[]=$retstr;
                                    }
                    /*$continueRecords = array();
                    while ($this->getNextCode() == Type_CONTINUE) {
                        $continueRecords[] = &$this->nextRecord();
                    }
                    //echo " 1 Type_SST\n";
                    $this->shareStrings = new SSTRecord($r, $continueRecords);
                    //print_r($this->shareStrings->strings);
                    */
                    // echo 'SST read: '.($time_end-$time_start)."\n";
                    break;

                case Spreadsheet_Excel_Reader_Type_FILEPASS:
                    return false;
                    break;
                case Spreadsheet_Excel_Reader_Type_NAME:
                    //echo "Type_NAME\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_FORMAT:
                        $indexCode = ord($this->data[$pos+4]) | ord($this->data[$pos+5]) << 8;

                        if ($version == Spreadsheet_Excel_Reader_BIFF8) {
                            $numchars = ord($this->data[$pos+6]) | ord($this->data[$pos+7]) << 8;
                            if (ord($this->data[$pos+8]) == 0){
                                $formatString = substr($this->data, $pos+9, $numchars);
                            } else {
                                $formatString = substr($this->data, $pos+9, $numchars*2);
                            }
                        } else {
                            $numchars = ord($this->data[$pos+6]);
                            $formatString = substr($this->data, $pos+7, $numchars*2);
                        }

                    $this->formatRecords[$indexCode] = $formatString;
                // echo "Type.FORMAT\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_XF:
                        //global $dateFormats, $numberFormats;
                        $indexCode = ord($this->data[$pos+6]) | ord($this->data[$pos+7]) << 8;
                        //echo "\nType.XF ".count($this->formatRecords['xfrecords'])." $indexCode ";
                        if (array_key_exists($indexCode, $this->dateFormats)) {
                            //echo "isdate ".$dateFormats[$indexCode];
                            $this->formatRecords['xfrecords'][] = array(
                                    'type' => 'date',
                                    'format' => $this->dateFormats[$indexCode]
                                    );
                        }elseif (array_key_exists($indexCode, $this->numberFormats)) {
                        //echo "isnumber ".$this->numberFormats[$indexCode];
                            $this->formatRecords['xfrecords'][] = array(
                                    'type' => 'number',
                                    'format' => $this->numberFormats[$indexCode]
                                    );
                        }else{
                            $isdate = FALSE;
                            if ($indexCode > 0){
                                if (isset($this->formatRecords[$indexCode]))
                                    $formatstr = $this->formatRecords[$indexCode];
                                //echo '.other.';
                                //echo "\ndate-time=$formatstr=\n";
                                if ($formatstr)
                                if (preg_match("/[^hmsday\/\-:\s]/i", $formatstr) == 0) { // found day and time format
                                    $isdate = TRUE;
                                    $formatstr = str_replace('mm', 'i', $formatstr);
                                    $formatstr = str_replace('h', 'H', $formatstr);
                                    //echo "\ndate-time $formatstr \n";
                                }
                            }

                            if ($isdate){
                                $this->formatRecords['xfrecords'][] = array(
                                        'type' => 'date',
                                        'format' => $formatstr,
                                        );
                            }else{
                                $this->formatRecords['xfrecords'][] = array(
                                        'type' => 'other',
                                        'format' => '',
                                        'code' => $indexCode
                                        );
                            }
                        }
                        //echo "\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_NINETEENFOUR:
                    //echo "Type.NINETEENFOUR\n";
                    $this->nineteenFour = (ord($this->data[$pos+4]) == 1);
                    break;
                case Spreadsheet_Excel_Reader_Type_BOUNDSHEET:
                    //echo "Type.BOUNDSHEET\n";
                        $rec_offset = $this->_GetInt4d($this->data, $pos+4);
                        $rec_typeFlag = ord($this->data[$pos+8]);
                        $rec_visibilityFlag = ord($this->data[$pos+9]);
                        $rec_length = ord($this->data[$pos+10]);

                        if ($version == Spreadsheet_Excel_Reader_BIFF8){
                            $chartype = ord($this->data[$pos+11]);
                            if ($chartype == 0){
                                $rec_name     = substr($this->data, $pos+12, $rec_length);
                            } else {
                                $rec_name     = $this->_encodeUTF16(substr($this->data, $pos+12, $rec_length*2));
                            }
                        }elseif ($version == Spreadsheet_Excel_Reader_BIFF7){
                                $rec_name     = substr($this->data, $pos+11, $rec_length);
                        }
                    $this->boundsheets[] = array('name'=>$rec_name,
                                                'offset'=>$rec_offset);

                    break;

            }

            //echo "Code = ".base_convert($r['code'],10,16)."\n";
            $pos += $length + 4;
            $code = ord($this->data[$pos]) | ord($this->data[$pos+1])<<8;
            $length = ord($this->data[$pos+2]) | ord($this->data[$pos+3])<<8;

            //$r = &$this->nextRecord();
            //echo "1 Code = ".base_convert($r['code'],10,16)."\n";
        }

        foreach ($this->boundsheets as $key=>$val){
            $this->sn = $key;
            $this->_parsesheet($val['offset']);
        }
        return true;

    }

    function _parsesheet($spos){
        $cont = true;
        // read BOF
        $code = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
        $length = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;

        $version = ord($this->data[$spos + 4]) | ord($this->data[$spos + 5])<<8;
        $substreamType = ord($this->data[$spos + 6]) | ord($this->data[$spos + 7])<<8;

        if (($version != Spreadsheet_Excel_Reader_BIFF8) && ($version != Spreadsheet_Excel_Reader_BIFF7)) {
            return -1;
        }

        if ($substreamType != Spreadsheet_Excel_Reader_Worksheet){
            return -2;
        }
        //echo "Start parse code=".base_convert($code,10,16)." version=".base_convert($version,10,16)." substreamType=".base_convert($substreamType,10,16).""."\n";
        $spos += $length + 4;
        //var_dump($this->formatRecords);
    //echo "code $code $length";
        while($cont) {
            //echo "mem= ".memory_get_usage()."\n";
//             $r = &$this->file->nextRecord();
            $lowcode = ord($this->data[$spos]);
            if ($lowcode == Spreadsheet_Excel_Reader_Type_EOF) break;
            $code = $lowcode | ord($this->data[$spos+1])<<8;
            $length = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
            $spos += 4;
            $this->sheets[$this->sn]['maxrow'] = $this->_rowoffset - 1;
            $this->sheets[$this->sn]['maxcol'] = $this->_coloffset - 1;
            //echo "Code=".base_convert($code,10,16)." $code\n";
            unset($this->rectype);
            $this->multiplier = 1; // need for format with %
            switch ($code) {
                case Spreadsheet_Excel_Reader_Type_DIMENSION:
                    //echo 'Type_DIMENSION ';
                    if (!isset($this->numRows)) {
                        if (($length == 10) || ($version == Spreadsheet_Excel_Reader_BIFF7)){
                            $this->sheets[$this->sn]['numRows'] = ord($this->data[$spos+2]) | ord($this->data[$spos+3]) << 8;
                            $this->sheets[$this->sn]['numCols'] = ord($this->data[$spos+6]) | ord($this->data[$spos+7]) << 8;
                        } else {
                            $this->sheets[$this->sn]['numRows'] = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8;
                            $this->sheets[$this->sn]['numCols'] = ord($this->data[$spos+10]) | ord($this->data[$spos+11]) << 8;
                        }
                    }
                    //echo 'numRows '.$this->numRows.' '.$this->numCols."\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_MERGEDCELLS:
                    $cellRanges = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                    for ($i = 0; $i < $cellRanges; $i++) {
                        $fr = ord($this->data[$spos + 8*$i + 2]) | ord($this->data[$spos + 8*$i + 3])<<8;
                        $lr = ord($this->data[$spos + 8*$i + 4]) | ord($this->data[$spos + 8*$i + 5])<<8;
                        $fc = ord($this->data[$spos + 8*$i + 6]) | ord($this->data[$spos + 8*$i + 7])<<8;
                        $lc = ord($this->data[$spos + 8*$i + 8]) | ord($this->data[$spos + 8*$i + 9])<<8;
                        //$this->sheets[$this->sn]['mergedCells'][] = array($fr + 1, $fc + 1, $lr + 1, $lc + 1);
                        if ($lr - $fr > 0) {
                            $this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['rowspan'] = $lr - $fr + 1;
                        }
                        if ($lc - $fc > 0) {
                            $this->sheets[$this->sn]['cellsInfo'][$fr+1][$fc+1]['colspan'] = $lc - $fc + 1;
                        }
                    }
                    //echo "Merged Cells $cellRanges $lr $fr $lc $fc\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_RK:
                case Spreadsheet_Excel_Reader_Type_RK2:
                    //echo 'Spreadsheet_Excel_Reader_Type_RK'."\n";
                    $row = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                    $column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                    $rknum = $this->_GetInt4d($this->data, $spos + 6);
                    $numValue = $this->_GetIEEE754($rknum);
                    //echo $numValue." ";
                    if ($this->isDate($spos)) {
                        list($string, $raw) = $this->createDate($numValue);
                    }else{
                        $raw = $numValue;
                        if (isset($this->_columnsFormat[$column + 1])){
                                $this->curformat = $this->_columnsFormat[$column + 1];
                        }
                        $string = sprintf($this->curformat, $numValue * $this->multiplier);
                        //$this->addcell(RKRecord($r));
                    }
                    $this->addcell($row, $column, $string, $raw);
                    //echo "Type_RK $row $column $string $raw {$this->curformat}\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_LABELSST:
                        $row         = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                        $column     = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                        $xfindex     = ord($this->data[$spos+4]) | ord($this->data[$spos+5])<<8;
                        $index = $this->_GetInt4d($this->data, $spos + 6);
            //var_dump($this->sst);
                        $this->addcell($row, $column, $this->sst[$index]);
                        //echo "LabelSST $row $column $string\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_MULRK:
                    $row         = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                    $colFirst = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                    $colLast     = ord($this->data[$spos + $length - 2]) | ord($this->data[$spos + $length - 1])<<8;
                    $columns     = $colLast - $colFirst + 1;
                    $tmppos = $spos+4;
                    for ($i = 0; $i < $columns; $i++) {
                        $numValue = $this->_GetIEEE754($this->_GetInt4d($this->data, $tmppos + 2));
                        if ($this->isDate($tmppos-4)) {
                            list($string, $raw) = $this->createDate($numValue);
                        }else{
                            $raw = $numValue;
                            if (isset($this->_columnsFormat[$colFirst + $i + 1])){
                                        $this->curformat = $this->_columnsFormat[$colFirst + $i + 1];
                                }
                            $string = sprintf($this->curformat, $numValue * $this->multiplier);
                        }
                    //$rec['rknumbers'][$i]['xfindex'] = ord($rec['data'][$pos]) | ord($rec['data'][$pos+1]) << 8;
                    $tmppos += 6;
                    $this->addcell($row, $colFirst + $i, $string, $raw);
                    //echo "MULRK $row ".($colFirst + $i)." $string\n";
                    }
                    //MulRKRecord($r);
                    // Get the individual cell records from the multiple record
                    //$num = ;

                    break;
                case Spreadsheet_Excel_Reader_Type_NUMBER:
                    $row     = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                    $column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                    $tmp = unpack("ddouble", substr($this->data, $spos + 6, 8)); // It machine machine dependent
                    if ($this->isDate($spos)) {
                        list($string, $raw) = $this->createDate($tmp['double']);
                    // $this->addcell(DateRecord($r, 1));
                    }else{
                        //$raw = $tmp[''];
                        if (isset($this->_columnsFormat[$column + 1])){
                                $this->curformat = $this->_columnsFormat[$column + 1];
                        }
                        $raw = $this->createNumber($spos);
                        $string = sprintf($this->curformat, $raw * $this->multiplier);

                    // $this->addcell(NumberRecord($r));
                    }
                    $this->addcell($row, $column, $string, $raw);
                    //echo "Number $row $column $string\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_FORMULA:
                case Spreadsheet_Excel_Reader_Type_FORMULA2:
                    $row     = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                    $column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                    if ((ord($this->data[$spos+6])==0) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) {
                        //String formula. Result follows in a STRING record
                        //echo "FORMULA $row $column Formula with a string<br>\n";
                    } elseif ((ord($this->data[$spos+6])==1) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) {
                        //Boolean formula. Result is in +2; 0=false,1=true
                    } elseif ((ord($this->data[$spos+6])==2) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) {
                        //Error formula. Error code is in +2;
                    } elseif ((ord($this->data[$spos+6])==3) && (ord($this->data[$spos+12])==255) && (ord($this->data[$spos+13])==255)) {
                        //Formula result is a null string.
                    } else {
                        // result is a number, so first 14 bytes are just like a _NUMBER record
                        $tmp = unpack("ddouble", substr($this->data, $spos + 6, 8)); // It machine machine dependent
                        if ($this->isDate($spos)) {
                            list($string, $raw) = $this->createDate($tmp['double']);
                        // $this->addcell(DateRecord($r, 1));
                        }else{
                            //$raw = $tmp[''];
                            if (isset($this->_columnsFormat[$column + 1])){
                                    $this->curformat = $this->_columnsFormat[$column + 1];
                            }
                            $raw = $this->createNumber($spos);
                            $string = sprintf($this->curformat, $raw * $this->multiplier);
   
                        // $this->addcell(NumberRecord($r));
                        }
                        $this->addcell($row, $column, $string, $raw);
                        //echo "Number $row $column $string\n";
                    }
                    break;                    
                case Spreadsheet_Excel_Reader_Type_BOOLERR:
                    $row     = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                    $column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                    $string = ord($this->data[$spos+6]);
                    $this->addcell($row, $column, $string);
                    //echo 'Type_BOOLERR '."\n";
                    break;
                case Spreadsheet_Excel_Reader_Type_ROW:
                case Spreadsheet_Excel_Reader_Type_DBCELL:
                case Spreadsheet_Excel_Reader_Type_MULBLANK:
                    break;
                case Spreadsheet_Excel_Reader_Type_LABEL:
                    $row     = ord($this->data[$spos]) | ord($this->data[$spos+1])<<8;
                    $column = ord($this->data[$spos+2]) | ord($this->data[$spos+3])<<8;
                    $this->addcell($row, $column, substr($this->data, $spos + 8, ord($this->data[$spos + 6]) | ord($this->data[$spos + 7])<<8));

                // $this->addcell(LabelRecord($r));
                    break;

                case Spreadsheet_Excel_Reader_Type_EOF:
                    $cont = false;
                    break;
                default:
                    //echo ' unknown :'.base_convert($r['code'],10,16)."\n";
                    break;

            }
            $spos += $length;
        }

        if (!isset($this->sheets[$this->sn]['numRows']))
            $this->sheets[$this->sn]['numRows'] = $this->sheets[$this->sn]['maxrow'];
        if (!isset($this->sheets[$this->sn]['numCols']))
            $this->sheets[$this->sn]['numCols'] = $this->sheets[$this->sn]['maxcol'];

    }

    function isDate($spos){
        //$xfindex = GetInt2d(, 4);
        $xfindex = ord($this->data[$spos+4]) | ord($this->data[$spos+5]) << 8;
        //echo 'check is date '.$xfindex.' '.$this->formatRecords['xfrecords'][$xfindex]['type']."\n";
        //var_dump($this->formatRecords['xfrecords'][$xfindex]);
        if ($this->formatRecords['xfrecords'][$xfindex]['type'] == 'date') {
            $this->curformat = $this->formatRecords['xfrecords'][$xfindex]['format'];
            $this->rectype = 'date';
            return true;
        } else {
            if ($this->formatRecords['xfrecords'][$xfindex]['type'] == 'number') {
                $this->curformat = $this->formatRecords['xfrecords'][$xfindex]['format'];
                $this->rectype = 'number';
                if (($xfindex == 0x9) || ($xfindex == 0xa)){
                    $this->multiplier = 100;
                }
            }else{
                $this->curformat = $this->_defaultFormat;
                $this->rectype = 'unknown';
            }
            return false;
        }
    }

    function createDate($numValue){
        if ($numValue > 1){
            $utcDays = $numValue - ($this->nineteenFour ? Spreadsheet_Excel_Reader_utcOffsetDays1904 : Spreadsheet_Excel_Reader_utcOffsetDays);
            $utcValue = round($utcDays * Spreadsheet_Excel_Reader_msInADay);
            $string = date ($this->curformat, $utcValue);
            $raw = $utcValue;
        }else{
            $raw = $numValue;
            $hours = floor($numValue * 24);
            $mins = floor($numValue * 24 * 60) - $hours * 60;
            $secs = floor($numValue * Spreadsheet_Excel_Reader_msInADay) - $hours * 60 * 60 - $mins * 60;
            $string = date ($this->curformat, mktime($hours, $mins, $secs));
        }
        return array($string, $raw);
    }

    function createNumber($spos){
        $rknumhigh = $this->_GetInt4d($this->data, $spos + 10);
        $rknumlow = $this->_GetInt4d($this->data, $spos + 6);
        //for ($i=0; $i<8; $i++) { echo ord($this->data[$i+$spos+6]) . " "; } echo "<br>";
        $sign = ($rknumhigh & 0x80000000) >> 31;
        $exp = ($rknumhigh & 0x7ff00000) >> 20;
        $mantissa = (0x100000 | ($rknumhigh & 0x000fffff));
        $mantissalow1 = ($rknumlow & 0x80000000) >> 31;
        $mantissalow2 = ($rknumlow & 0x7fffffff);
        $value = $mantissa / pow( 2 , (20- ($exp - 1023)));
        if ($mantissalow1 != 0) $value += 1 / pow (2 , (21 - ($exp - 1023)));
        $value += $mantissalow2 / pow (2 , (52 - ($exp - 1023)));
        //echo "Sign = $sign, Exp = $exp, mantissahighx = $mantissa, mantissalow1 = $mantissalow1, mantissalow2 = $mantissalow2<br>\n";
        if ($sign) {$value = -1 * $value;}
        return $value;
    }

    function addcell($row, $col, $string, $raw = ''){
        //echo "ADD cel $row-$col $string\n";
        $this->sheets[$this->sn]['maxrow'] = max($this->sheets[$this->sn]['maxrow'], $row + $this->_rowoffset);
        $this->sheets[$this->sn]['maxcol'] = max($this->sheets[$this->sn]['maxcol'], $col + $this->_coloffset);
        $this->sheets[$this->sn]['cells'][$row + $this->_rowoffset][$col + $this->_coloffset] = $string;
        if ($raw)
            $this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['raw'] = $raw;
        if (isset($this->rectype))
            $this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['type'] = $this->rectype;

    }


    function _GetIEEE754($rknum){
        if (($rknum & 0x02) != 0) {
                $value = $rknum >> 2;
        } else {
//mmp
// first comment out the previously existing 7 lines of code here
//                 $tmp = unpack("d", pack("VV", 0, ($rknum & 0xfffffffc)));
//                 //$value = $tmp[''];
//                 if (array_key_exists(1, $tmp)) {
//                     $value = $tmp[1];
//                 } else {
//                     $value = $tmp[''];
//                 }
// I got my info on IEEE754 encoding from
// http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html
// The RK format calls for using only the most significant 30 bits of the
// 64 bit floating point value. The other 34 bits are assumed to be 0
// So, we use the upper 30 bits of $rknum as follows...
        $sign = ($rknum & 0x80000000) >> 31;
        $exp = ($rknum & 0x7ff00000) >> 20;
        $mantissa = (0x100000 | ($rknum & 0x000ffffc));
        $value = $mantissa / pow( 2 , (20- ($exp - 1023)));
        if ($sign) {$value = -1 * $value;}
//end of changes by mmp        

        }

        if (($rknum & 0x01) != 0) {
            $value /= 100;
        }
        return $value;
    }

    function _encodeUTF16($string){
        $result = $string;
        if ($this->_defaultEncoding){
            switch ($this->_encoderFunction){
                case 'iconv' :
                    //$result = iconv('UTF-16LE', 'UTF-16LE//IGNORE', $string);
                    $result = @iconv('UTF-16LE', $this->_defaultEncoding, $string);
                    break;
                case 'mb_convert_encoding' :    
                    $result = mb_convert_encoding($string, $this->_defaultEncoding, 'UTF-16LE' );
                    break;
            }
        }
        return $result;
    }

    function _GetInt4d($data, $pos) {
        return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
    }

}

?>

[Excel/oleread.inc]
<?php
define('NUM_BIG_BLOCK_DEPOT_BLOCKS_POS', 0x2c);
define('SMALL_BLOCK_DEPOT_BLOCK_POS', 0x3c);
define('ROOT_START_BLOCK_POS', 0x30);
define('BIG_BLOCK_SIZE', 0x200);
define('SMALL_BLOCK_SIZE', 0x40);
define('EXTENSION_BLOCK_POS', 0x44);
define('NUM_EXTENSION_BLOCK_POS', 0x48);
define('PROPERTY_STORAGE_BLOCK_SIZE', 0x80);
define('BIG_BLOCK_DEPOT_BLOCKS_POS', 0x4c);
define('SMALL_BLOCK_THRESHOLD', 0x1000);
// property storage offsets
define('SIZE_OF_NAME_POS', 0x40);
define('TYPE_POS', 0x42);
define('START_BLOCK_POS', 0x74);
define('SIZE_POS', 0x78);
define('IDENTIFIER_OLE', pack("CCCCCCCC",0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1));

//echo 'ROOT_START_BLOCK_POS = '.ROOT_START_BLOCK_POS."\n";

//echo bin2hex($data[ROOT_START_BLOCK_POS])."\n";
//echo "a=";
//echo $data[ROOT_START_BLOCK_POS];
//function log

function GetInt4d($data, $pos) {
        return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
}


class OLERead {
    var $data = '';
   
   
    function OLERead(){
       
       
    }
   
    function read($sFileName){
       
        // check if file exist and is readable (Darko Miljanovic)
        if(!is_readable($sFileName)) {
            $this->error = 1;
            return false;
        }
       
        $this->data = @file_get_contents($sFileName);
        if (!$this->data) {
            $this->error = 1;
            return false;
            }
            //echo IDENTIFIER_OLE;
            //echo 'start';
            if (substr($this->data, 0, 8) != IDENTIFIER_OLE) {
            $this->error = 1;
            return false;
            }
        $this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
        $this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS);
        $this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS);
        $this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS);
        $this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS);
       
    /*
        echo $this->numBigBlockDepotBlocks." ";
        echo $this->sbdStartBlock." ";
        echo $this->rootStartBlock." ";
        echo $this->extensionBlock." ";
        echo $this->numExtensionBlocks." ";
        */
        //echo "sbdStartBlock = $this->sbdStartBlock\n";
        $bigBlockDepotBlocks = array();
        $pos = BIG_BLOCK_DEPOT_BLOCKS_POS;
    // echo "pos = $pos";
    $bbdBlocks = $this->numBigBlockDepotBlocks;
       
            if ($this->numExtensionBlocks != 0) {
                $bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4;
            }
       
        for ($i = 0; $i < $bbdBlocks; $i++) {
            $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
            $pos += 4;
        }
       
       
        for ($j = 0; $j < $this->numExtensionBlocks; $j++) {
            $pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE;
            $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1);

            for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) {
                $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
                $pos += 4;
            }

            $bbdBlocks += $blocksToRead;
            if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
                $this->extensionBlock = GetInt4d($this->data, $pos);
            }
        }

    // var_dump($bigBlockDepotBlocks);
       
        // readBigBlockDepot
        $pos = 0;
        $index = 0;
        $this->bigBlockChain = array();
       
        for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) {
            $pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE;
            //echo "pos = $pos";    
            for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) {
                $this->bigBlockChain[$index] = GetInt4d($this->data, $pos);
                $pos += 4 ;
                $index++;
            }
        }

    //var_dump($this->bigBlockChain);
        //echo '=====2';
        // readSmallBlockDepot();
        $pos = 0;
        $index = 0;
        $sbdBlock = $this->sbdStartBlock;
        $this->smallBlockChain = array();
   
        while ($sbdBlock != -2) {
   
        $pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE;
   
        for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) {
            $this->smallBlockChain[$index] = GetInt4d($this->data, $pos);
            $pos += 4;
            $index++;
        }
   
        $sbdBlock = $this->bigBlockChain[$sbdBlock];
        }

       
        // readData(rootStartBlock)
        $block = $this->rootStartBlock;
        $pos = 0;
        $this->entry = $this->__readData($block);
       
        /*
        while ($block != -2) {
            $pos = ($block + 1) * BIG_BLOCK_SIZE;
            $this->entry = $this->entry.substr($this->data, $pos, BIG_BLOCK_SIZE);
            $block = $this->bigBlockChain[$block];
        }
        */
        //echo '==='.$this->entry."===";
        $this->__readPropertySets();

    }
   
    function __readData($bl) {
        $block = $bl;
        $pos = 0;
        $data = '';
       
        while ($block != -2) {
            $pos = ($block + 1) * BIG_BLOCK_SIZE;
            $data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE);
            //echo "pos = $pos data=$data\n";    
        $block = $this->bigBlockChain[$block];
        }
        return $data;
    }
       
    function __readPropertySets(){
        $offset = 0;
        //var_dump($this->entry);
        while ($offset < strlen($this->entry)) {
            $d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE);
           
            $nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8);
           
            $type = ord($d[TYPE_POS]);
            //$maxBlock = strlen($d) / BIG_BLOCK_SIZE - 1;
       
            $startBlock = GetInt4d($d, START_BLOCK_POS);
            $size = GetInt4d($d, SIZE_POS);
       
            $name = '';
            for ($i = 0; $i < $nameSize ; $i++) {
            $name .= $d[$i];
            }
           
            $name = str_replace("\x00", "", $name);
           
            $this->props[] = array (
                'name' => $name,
                'type' => $type,
                'startBlock' => $startBlock,
                'size' => $size);

            if (($name == "Workbook") || ($name == "Book")) {
                $this->wrkbook = count($this->props) - 1;
            }

            if ($name == "Root Entry") {
                $this->rootentry = count($this->props) - 1;
            }
           
            //echo "name ==$name=\n";

           
            $offset += PROPERTY_STORAGE_BLOCK_SIZE;
        }
       
    }
   
   
    function getWorkBook(){
        if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){
//         getSmallBlockStream(PropertyStorage ps)

            $rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']);
           
            $streamData = '';
            $block = $this->props[$this->wrkbook]['startBlock'];
            //$count = 0;
            $pos = 0;
            while ($block != -2) {
                $pos = $block * SMALL_BLOCK_SIZE;
                $streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE);

                $block = $this->smallBlockChain[$block];
            }
           
            return $streamData;
           

        }else{
       
            $numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE;
            if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) {
                $numBlocks++;
            }
           
            if ($numBlocks == 0) return '';
           
            //echo "numBlocks = $numBlocks\n";
        //byte[] streamData = new byte[numBlocks * BIG_BLOCK_SIZE];
            //print_r($this->wrkbook);
            $streamData = '';
            $block = $this->props[$this->wrkbook]['startBlock'];
            //$count = 0;
            $pos = 0;
            //echo "block = $block";
            while ($block != -2) {
            $pos = ($block + 1) * BIG_BLOCK_SIZE;
            $streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE);
            $block = $this->bigBlockChain[$block];
            }
            //echo 'stream'.$streamData;
            return $streamData;
        }
    }
   
}
?>

[Excel.Application.test1.php]
<?php
$excel_app = new COM("Excel.application") or Die ("Error");
$Workbook = $excel_app->Workbooks->Open("C:\Documents and Settings\Master\Excel\test.xls") or Die("Error");
$Worksheet = $Workbook->Worksheets("sheet1");
$Worksheet->activate;
$excel_cell = $Worksheet->Range("D3");
$excel_cell->activate;
echo $excel_cell->value;
$Workbook->Save();
$Workbook->Saved = true;
$Workbook->Close;
unset($Worksheet);
unset($Workbook);
$excel_app->Workbooks->Close();
$excel_app->Quit();
unset($excel_app);
?>

[Excel.Application.test2.php]
<?php
$excel = new COM("Excel.Application") or die("Error");
$excel->Visible = 0;
$excel->DisplayAlerts = 0;
$excel->Workbooks->Open("C:\Documents and Settings\Master\Excel\test.xls") or Die("Error");
$book = $excel->Workbooks(1);
$sheet = $book->Worksheets(1);
$name = "New Sheet";
$sheets2 = $book->Worksheets->add();
$sheets2->activate;
$sheets2->name = $name;
$file_name = "C:\Documents and Settings\Master\Excel\sample.xls";
if (file_exists($file_name)) unlink($file_name);
$excel->Workbooks[1]->SaveAs($file_name);
$excel->Quit();
$excel->Release();
$excel = null;
?>

웹프로그래머의 홈페이지 정보 블로그 http://hompy.info/561

Posted by 프로그래머

2009/01/17 12:14 2009/01/17 12:14

동적 HTML 객체 모델 요소의 위치와 면적 계산
Understanding Properties That Measure Element Dimension and Location

diagram of a sample page showing the DHTML Object Model properties that are related to the dimension and location of elements
diagram of a sample page showing the DHTML Object Model properties that are related to the dimension and location of elements
diagram of a sample page showing the DHTML Object Model properties that are related to the dimension and location of elements

예제 테스트 링크
http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/overview/measure.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD><TITLE>Measure for Measure</TITLE>
<SCRIPT type="text/javascript">
<!--
var lastfunc = 1;
function split() {
    switch(lastfunc) {
        case 1: one(); break;
        case 2: two(); break;
        case 3: three(); break;
        case 4: four(); break;
        default: five(); break;
    }
}
function iebody() {
    // Sense the difference between Strict and Quirks mode
    return (document.compatMode != "BackCompat"? document.documentElement : document.body);
}
function one() {
lastfunc = 1;
report.value = "The style object contains information that was set in the inline style to position the object. The following values are reported for the various position and dimension properties on the style object for the DIV above:" + "\n\n";
report.value += " mydiv.style.top (string) = " + mydiv.style.top + "\n";
report.value += " mydiv.style.left (string) = " + mydiv.style.left + "\n";
report.value += " mydiv.style.height (string) = " + mydiv.style.height + "\n";
report.value += " mydiv.style.width (string) = " + mydiv.style.width + "\n";
report.value += " mydiv.style.pixelTop = " + mydiv.style.pixelTop + "\n";
report.value += " mydiv.style.pixelLeft = " + mydiv.style.pixelLeft + "\n";
report.value += " mydiv.style.pixelHeight = " + mydiv.style.pixelHeight + "\n";
report.value += " mydiv.style.pixelWidth = " + mydiv.style.pixelWidth + "\n";
report.value += " mydiv.style.posTop = " + mydiv.style.posTop + "\n";
report.value += " mydiv.style.posLeft = " + mydiv.style.posLeft + "\n";
report.value += " mydiv.style.posHeight = " + mydiv.style.posHeight + "\n";
report.value += " mydiv.style.posWidth = " + mydiv.style.posWidth + "\n";
// Cancel the generic click event for the body
window.event.cancelBubble = true;
}
function two() {
lastfunc = 2;
report.value = "Offset properties for the DIV above: \n";
report.value += " mydiv.offsetLeft = " + mydiv.offsetLeft + "\n";
report.value += " mydiv.offsetTop = " + mydiv.offsetTop + "\n";
report.value += " mydiv.offsetHeight = " + mydiv.offsetHeight + "\n";
report.value += " mydiv.offsetWidth = " + mydiv.offsetWidth + "\n";
report.value += "Offset properties for the BODY: \n";
report.value += " offsetLeft = " + iebody().offsetLeft + "\n";
report.value += " offsetTop = " + iebody().offsetTop + "\n";
report.value += " offsetHeight = " + iebody().offsetHeight + "\n";
report.value += " offsetWidth = " + iebody().offsetWidth + "\n";
// Cancel the generic click event for the body
window.event.cancelBubble = true;
}
function three() {
lastfunc = 3;
report.value = "Scroll values for the DIV above: \n";
report.value += " mydiv.scrollLeft = " + mydiv.scrollLeft + "\n";
report.value += " mydiv.scrollTop = " + mydiv.scrollTop + "\n";
report.value += " mydiv.scrollHeight = " + mydiv.scrollHeight + "\n";
report.value += " mydiv.scrollWidth = " + mydiv.scrollWidth + "\n";
report.value += "Scroll values for the BODY: \n";
report.value += " scrollLeft = " + iebody().scrollLeft + "\n";
report.value += " scrollTop = " + iebody().scrollTop + "\n";
report.value += " scrollHeight = " + iebody().scrollHeight + "\n";
report.value += " scrollWidth = " + iebody().scrollWidth + "\n";
// Cancel the generic click event for the body
window.event.cancelBubble = true;
}
function four() {
lastfunc = 4;
report.value = "";
report.value += " clientHeight for the BODY: " + iebody().clientHeight + "\n";
report.value += " clientWidth for the BODY:" + iebody().clientWidth + "\n";
report.value += " clientTop for the BODY:" + iebody().clientTop + "\n";
report.value += " clientLeft for the BODY:" + iebody().clientLeft + "\n";
report.value += " clientHeight for this TEXTAREA:" + report.clientHeight + "\n";
report.value += " clientWidth for this TEXTAREA: " + report.clientWidth + "\n";
report.value += " clientTop for this TEXTAREA:" + report.clientTop + "\n";
report.value += " clientLeft for this TEXTAREA:" + report.clientLeft + "\n";
// Cancel the generic click event for the body
window.event.cancelBubble = true;
}
function five() {
lastfunc = 5;
report.value = "The following x and y values are passed on the event object for this mouse click event: \n";
report.value += " window.event.x = " + window.event.x + "\n";
report.value += " window.event.y = " + window.event.y + "\n";
report.value += " window.event.offsetX = " + window.event.offsetX + "\n";
report.value += " window.event.offsetY = " + window.event.offsetY + "\n";
report.value += " window.event.screenX = " + window.event.screenX + "\n";
report.value += " window.event.screenY = " + window.event.screenY + "\n";
report.value += " window.event.clientX = " + window.event.clientX + "\n";
report.value += " window.event.clientY = " + window.event.clientY + "\n";
// Cancel the generic click event for the body
window.event.cancelBubble = true;
}
-->
</script>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
<META NAME="AUTHOR" CONTENT="InetSDK">
<META NAME="MS.LOCALE" CONTENT="EN-US">
<META NAME="ROBOTS" CONTENT="noindex">

<!-- SAMPLE_STYLE_START -->
<LINK REL="stylesheet" HREF="/workshop/samples/samples.css" TYPE="text/css">
<!-- SAMPLE_STYLE_END -->
<STYLE type="text/css">
BODY {
    margin:0;
    border:10px solid #99ccff;
    padding:10px;
    font-family:arial;
    font-size:70%;
    background-color:white;
    color:black;
}
BUTTON {
    margin:2px;
}
#mydiv {
    overflow:scroll;
    margin:20px auto;
    background-color:white;
    padding:20px;
    border:10px solid #99ccff;
    font-size:150%;
}
#report {
    margin-top:25px;
    border:1px solid #cccccc;
    font-family:arial;
    width:90%;
}
</STYLE>
</HEAD>
<!--TOOLBAR_START-->
<!--TOOLBAR_EXEMPT-->
<!--TOOLBAR_END-->

<BODY onload="two()" onscroll="three()" onresize='split()' onclick="five()">
<DIV class="body">
<CENTER>

<!-- This DIV uses an inline style to test the style object above. -->
<DIV id="mydiv" onclick="one()" onscroll="three()" style="top:5px; left:5px; height:8em; width:90%;">
DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool! DHTML is so cool!
</DIV>

<button onclick=one()>Style Positions</button>
<button onclick=two()>Object Offset</button>
<button onclick=three()>Scroll Positions</button>
<button onclick=four()>Client Area</button>
<button onclick=five()>Event Object</button>

<TEXTAREA id="report" rows=12 style=""></TEXTAREA>

</CENTER>

<!-- START_PAGE_FOOTER -->
<BR><BR><BR>
<p class="viewsource">[Right-click and choose View Source from the shortcut menu.] </p>
<A class="copyright" HREF="http://www.microsoft.com/isapi/gomscom.asp?TARGET=/info/cpyright.htm">&copy; 2007 Microsoft Corporation. All rights reserved. Terms of use.</A>
<!-- END_PAGE_FOOTER -->
</DIV>
</BODY>
</HTML>

Posted by 프로그래머

2009/01/04 15:46 2009/01/04 15:46


※ 녹색은 네츠케이프, 혹은 익스플로러 전용으로만 사용되는 객체(속성,메소드)입니다

객체(Object)

속성(Property)

메소드(Method)

이벤트핸들러

(Event Handler)

Anchor

name

 

 

text

x

y

anchors array

length

 

 

Applet

 

applet's methods

 

applets array

length

 

 

Area

hash

 

onClick

host

onmouseOut

gostname

onmouseOver

href

 

pathname

 

port

 

protocol

 

search

 

target

 

Array

length

concat

 

join

pop

push

reverse

shift

slice

sort

unshjft

Button

form

blur

onClick

name

click

onmouseDown

type

focus

onmouseUp

value

 

 

Checkbox

checked

blur

onClick

defaultChecked

click

onmouseDown

form

focus

onmouseUp

name

 

 

type

 

 

value

 

 

Date

 

getDate

 

getDay

getFullYear

getHours

getMilliseconds

getMinutes

getMonth

getSeconds

getTime

getTimezoneOffset

getUTCDate

getUTCDay

getUTCFullYear

getUTCHours

getUTCMilliseconds

getUTCMinutes

getUTCMonth

getUTCSeconds

getYear

parse

setDate

setFullYear

setHours

setMilliseconds

setMinutes

setMonth

setSeconds

setTime

setUTCDate

setUTCHours

setUTCMilliseconds

setUTCMinutes

setUTCMonth

setUTCSeconds

setYear

goGMTString

toLocaleString

toString

toUTCString

UTC

valueOf

document

activeElement

clear

 

alinkColor

close

all

createElement

Anchor

createStylesheet

anchors

elementFromPoint

Applet

getSelection

applets

open

Area

write

bgColor

writeIn

body

 

charset

 

children

 

cookie

 

defaultCharset

 

domain

 

embed

 

embeds

 

expando

 

fgColor

 

Form

 

forms

 

Image

 

images

 

lastModified

 

Layer

 

layers

 

linkColor

 

Link

 

links

 

location

 

parentWindow

 

plugins

 

readyState

 

referrer

 

scripts

 

selection

 

styleSheets

 

title

 

URL

 

vlinkColor

 

FileUpload

form

blur

onBlur

name

focus

onFocus

type

select

onSelect

value

 

 

Form

action

reset