[펌글] 자바스크립트(javascript) 객체 및 함수 목록

By | 12월 31, 2009

- 출처 :  http://cafe.naver.com/tonkjsp/226 -

▶ 자바스크립트 객체

     - 구현 엔진과는 관계없이 언어에 종속에 된다. 

        즉 , 자바스크립트를 어디에서 구현하느냐와 관계없이 객체를 사용이 가능하다.

     - 각 객체는 기 본 데이터 타입과 함께 전환 함수 등의 추가적인 기능을 포함하고 있다.    

     - 자바스크립트의 모든 객체는 배열을 상속하고 있다.

     - 자바스크립트 객체는 Object라는 객체에 기초를 둔다.

     - 생성자 개념과 new 키워드를 사용해 객체 인스턴스 생성을 지원한다.     

    

      ※ 특수 용도의 객체

          - Math      

          - Date

          - RegExp

             프로그램에 있어 매우 정교한 문자열 패턴 매칭을 가능케 해준다.             

  

⑴ 자바스크립트에 객체의 종류

    ㉠ 자바스크립트 내장 객체

    ㉡ 브라우저 객체 모델(BOM) 객체

    ㉢ 문서 객체 모델(DOM) 객체

    ㉣  개발자가 만든 사용자 정의 객체

 

⑵ 내장객체와 객체 생성자  

     모든 내장객체는 객체 타입과 연관되어 있는 메소드와 프로퍼티를 갖고 있음.

     객체 인스턴스를 통해 접근할 있는 객체를 제외하고는 모두 공유객체를 통해 직접적으로 접근한다.

    

     ※  고유 프로퍼티나 메소드를 갖고 있지 않은 유일한 객체는 Boolean 객체

          [예]

          var hAnswer = new Boolean(true); 

          alert(hAnswer.toValue);  ←  접근할 수 없다.

          alert(hAnswer); ← 접근할 수 있다.

 

⑶ Number 객체

    고유 메소드(문자열로 변환 , 특정 로케일의 문자로 변환, 특정 소수점 표현식이 나 지수 표현식으로 변환)

    는 변환과 관련된 메소드가 존재한다.

   

    - toExponential(숫자) : 숫자 개수를 매개 변수로 넘겨주면 지수 표현식으로 바꾸는 메소드 

    - toPrecision(숫자) : 소수점 밑 자리수를 숫자 자리까지로 표현하는 메소드  

    - toFixed(숫자) : 지정한 숫자만큼의 소수점 이하 자리수만 남기고 나머지는 반올림하여 표시

    - toLocaleString() : 주어진 로케일에 맞추어 숫자를 표현

      예)

      var nVal = new Number("34.8896");

      alert(nVal.toExponential(3));   // 지수 값이 나옴

      alert(nVal.toPrecision(3));      // 34.9

      alert(nVal.toFixed(6));            // 34.889600

 

    4 개의 상수 프로퍼티를 갖고 있다.

    - MAX_VALUE : 숫자 상수로서 자바스크립트에서 표현할 수 있는 최대값

       Number.MAX_VALUE

    - MIN_VALUE  : 숫자 상수로서 자바스크립트에서 표현할 수 있는 최소값

       Number.MIN_VALUE

    - NEVATIVE_INFINITY : 자바스크립트의 표현할 수 있는 값을 초과하는 경우 음의 무대값 (overflow)

       Number.NATIVE_INFINITY

    - POSITIVE_INFINITY  : 자바스크립트의 표현할 수 있는 값을 초과하는 경우 양의 무대값 (overflow)

       Number.POSITIV_INFINITY     

 

⑷ String 객체

    new String 생성자를 사용함.     

    

    ㉠ valueOf()

        String 객체가 들어 있는 문자열을 반환하거나 , 객체가 가지고 있는 값을 String으로 반환한다.

         var iVal = "방가방가";

         alert(iVal.valueOf());

        

         function strTest(){

             var iVal = "방가방가";

             alert(strTest.valueOf());

         }

        

    ㉡ length

        문자열 길이를 반환하는 프로퍼티

 

        var hAnswer = new String("Happy Day");
        alert(hAnswer.length);

       

        ※ 괄호() 없이 사용한다.

   

    ㉢ anchor

        HTML 앵커(anchor)를 만든다.       

 

        var hAnswer = new String("네이버 홈");
        document.write(hAnswer.anchor("www.naver.com"));

 

    ㉣ big, blink, bold, italics, small, strike, sub, sup

        String 객체의 문자열 값을 HTML 형식으로 만들어 반환한다.

        

        var strVal = new String("This is the test string");

        var strResul = strVal.big();
             strResul += strVal.blink();
             strResul += strVal.bold();
             strResul += strVal.italics();
             strResul += strVal.small();
             strResul += strVal.strike();
             strResul += strVal.sub();
             strResul += strVal.sup(); 
             document.getElementById('innerTest').innerHTML = strResul;

 

    ㉤ charAt, charCodeAt

        위치를 정수로 나타내며 시작점은 0 부터 시작한다.

 

        - charAt

           주어진 위치의 문자열

           var strVal = new String("This is the test string");
            alert(strVal.charAt(3)); // s

 

        - charCodeAt

           주어진 위치의 문자코드를 반환

            var strVal = new String("This is the test string");
            alert(strVal.charCodeAt(3)); // 115

 

    ㉥ indexOf

        첫번째로 일치하는 부분 문자열의 시작 위치를 반환한다.

        검색할 문자열을 인자로 받는다.    

    

        var strObj = new String("This is a test string");
        alert(strObj.indexOf('t'));   //10

 

    ㉦ lastIndexOf

        마지막으로 일치하는 부분 문자열의 시작 위치를 반환한다.        

        검색할 문자열을 인자로 받는다.

       

        var strObj = new String("This is a test string");
        alert(strObj.lastIndexOf('t')); // 16

 

    ㉧ link

        링크할 HTML을 반환한다.

        href 프로퍼티에대한 url인자로 받는다.        

       

        var strObj = new String("네이버 홈");
         document.write(strObj.link("http://www.naver.com"));

       

    ㉨ concat

        문자열을 붙인다.        

        문자열에 덧붙일 문자열 인자로 받는다.

 

        var strObj = new String().concat("This is a ", " new string");

        alert(strObj);

 

        var strObj = new String();

        alert(strObj.concat("This is a ", " new string");       

 

    ㉩ split

        구분자를 기준으로 문자열을 토큰으로 분할한다.

        구분자와 최대 분할 횟수를 인자로 받는다.

 

         var strName = "fName=a1, lName=a2, state=korea, statement=happy day";
         var arrTokens = strName.split(',',4);
         var res = "";
        
         for(var i in arrTokens){
             var newTokens = arrTokens[i].split('=');
              res += newTokens[0];
              res += "=" + newTokens[1] + "\n";  
         }
        
         alert(res);

        

        ※ 자바스크립트 엔진은 문자 변수를 String 객체로 변환한 다음 , 함수 호출을 실행한다.

 

    ㉪ slice

        문자열의 일부를 반환한다.

        문자열의 시작과 끝 위치를 인자로 받는다. (0부터 시작하고 끝을 나타내는 인자 -1의 사이의 문자)

 

        var strVal = new String("This is the test string");
        alert(strVal.slice(3,6));  // s i        

 

    ㉫ substring , substr

        부분 문자열을 반환한다.  (substring : 0부터 시작하고 끝을 나타내는 인자 -1의 사이의 문자)      

                                           (substr : 시작점에서 출력될 문자열 갯수를 인자로 받는다. )

         - substring() 

        var strVal = new String("This is the test string");
        alert(strVal.substring(3,6));  // s i        

       

         -substr()

        var strVal = new String("This is the test string");
        alert(strVal.substr(3,6)); // s is t

 

    ㉬ match, replace, search

        정규표현식으로 일치, 대체, 검색한다.         

 

    ㉭ toLowerCase, toUpperCase 

        대소문자를 상호 변환한다.

        

        var strVal = new String("Mix of upper and lower");

        alert(strVal.toUpperCase());

        alert(strVal.toLowerCase());

 

    ㉮ fromCharCode

        유니코드 값을 쉽표(,)로 분할해서 반환한다.

      

 

⑸ 정규표현식과 RegExp

    패턴을 형성하는 문자들의 집합으로 문자열 내에서 검색, 대체, 추출 등을 할 때 사용

 

    - RegExp 객체를 사용하여 정규표현식을 명시적으로 사용한 경우

       var sPattern = new RegExp('+s'); // + 의미는 문자열 중에 s 문자가 1개 이상 있는지 찾는다 .

 

    - RegExp 문자열 리터럴의 사용하는 방법

      var sPattern = /+s/;  // + 의미는 문자열 중에 s 문자가 1개 이상 있는지 찾는다 .  

 

    ※ 정규표현식은 자바스크립트에만 있는 것은 아니다. 대부분의 프로그래밍 언어는 다 지원한다.   

   

     ① RegExp 객체의 test("문자열");, exec("문자열")

         ㉠  test("문자열") 메소드

              입력된 문자열이 정규 표현식을 부합하는지 판단한다.

 

              var str1 = /JavaScript rules/;
              var str2 = "JavaScript rules";
             

              alert(str1.test(str2));  

 

              var str1 = /JavaScript rules/i;   // i 의미는 문자열 중에 대소문자를 구별없게 처리하기 위한 플래그

              var str2 = "javascript rules";    
                       
              alert(str1.test(str2));             

            

              ※ 플래그

                  i  : 대소문자 구별 없도록 처리하는 플래그

                 g  : 전역 매칭 플래그

                 m : 여러줄 매칭 플래그

                 -  var sPattern = new RegExp('+s', 'g');

 

         ㉡ exec("문자열") 메소드 

             exec("문자열") : 정규패턴에 부합되는 값을 배열 형태로 반환한다. 만약 없으면 null 반환한다.

 

             var re = /JS*/ig; 

             /*

               플래그 부터 해석하면 전체 문자열 패턴에 대하여 대소문자를 구분하지 않으며 정규표현식은 J로 시작하고 그 뒤에

               S가 0개 이상의 패턴을 의미

             */

             var str = "cfdsJS *(&YJSjs 8888JSJ";
             var rArr = re.exec(str);
        
             while(rArr){
                alert(rArr[0]);   // JS JS js JS J
                rArr = re.exec(str);
             } 

 

     ② 정규식의 응용

         ㉠  RegExp 객체에 text() 메소드, exec() 메소드가 아닌 regex 메소드인 replace(대체), match(매치), search(검색)

         ㉡ \ 역슬래쉬 의미 

              - 첫번째 숫자인지 아니면 문자인지 판단한다. (생략가능)

                 \d (숫자) , \D (숫자가 아닌 문자) , \w (알파벳과 숫자로 된 문자)

                   

                   [예-1]  

                   var regExp = /(\w*)-*(\w*)/;
                   var str = "00Java--00JSP";
                   var strResult = str.replace(regExp, "$2-$1");
          
                   alert(strResult);  

              

              - 두번째 \ 역슬래쉬는 특수문자를 가르킨다.

                 \s (스페이스 공백) , \t (탭) , \f (폼 필드) , \l (라인필드) , \m (여러줄)

 

              - 세번째 \ 는 문자 자체를 의미 한다.

                

                [예-1]

                var regExp = /\s\*/g;  // 공백 문자 다음에 나오는 * 를 문자 패턴 전체에 찾는다.
                var str = "Happy Day * a Thank * you";
                var strRplc = str.replace(regExp, '-'); // * 를 - 로 바꾼다.
        
                alert(strRplc);

               

                [예-2]

                var regExp = /:\D*\s\d+\s\d+/; = var regExp = / :[^0-9]*\s[0-9]+\s[0-9]+/;

                /*

                  첫번째 시작하는 문자는 :(콜론) 으로 시작하고 \D 숫자가 아닌 문자가 0 개 이상 이면서 \s 공백을 기준으로

                  숫자가 1개 이상, \s 공백 걸처 또다시 숫자가 1개이상 패턴의 값을 반환한다.

                */
                var str = "Date : July 7 2009";
                var strResult = str.match(regExp);
         
                alert("Date " + strResult);

 

         ㉢  정규표현식에서 문자열 매칭에 편리하도록 사용하는 네 가지의 특수문자

             +  : 1회 이상 반복

             *  : 0회 이상 반복  

             ?  : 0 또는 1 개의 문자       

 

               

         ㉣  기타 표기법

             - [^0 - 9] : 숫자가 아닌 문자를 나타내는 것으로 \D와 같다.

             - [0 - 9]  : 숫자만 나타내는 것으로 \d와 같다.

             - [A-Za-z] : 알파벳 대소문자 전체를 매칭한다.

             - [가-힣] : 한글

             - [A-Za-z0-9] : 숫자나 영문자로 된 문자를 의미한다.  

 

         ㉤ 한줄의 시작/ 끝을 지칭하는 기호

             캐럿기호(^) , 달러기호($)

 

             var regExp1 = /^The/i;
             var regExp2 = /end$/;
             var str = "The end";
             var strResult1 = str.match(regExp1);
             var strResult2 = str.match(regExp2);
          
             alert(strResult1 + " " + strResult2); // The end

 

         ㉥  수직바(|) , 중괄호({})

              a | b  : a 또는 b

              {a}  : aa 두번 반복

             

⑹ Date와 Math 객체

 

    ① Date

        날짜를 생성하고 년, 월, 일, 초 등의 값에 접근할 수 있는 객체

 

        ㉠ 날짜 객체 생성하는 방법 

 

          var dtNow1 = new Date(); // 시스템 오늘 날짜
          var dtNow2 = new Date(5999000920); // 밀리초 값으로 날짜를 객체 생성
          var dtNow3 = new Date("March 12, 1980 12:20:25"); // 문자열 값으로 날짜를 객체를 생성
          var dtNow4 = new Date(1977,10,28)  // 직접 년, 월, 일 값을 입력하여 날짜 객체 생성
          var dtNow5 = new Date(1977,10,28,19,30,20,20); // 직접 년, 월, 일 , 시간 , 분, 초 모두 입력하여 날짜 객체 생성
         
          alert(dtNow1 + '\n' + dtNow2 + '\n' + dtNow3 + '\n' + dtNow4 + '\n' + dtNow5);

 

        ㉡ 날짜 객체에 접근할 수 있는 정적 메소드

            - parse

               1970년 1월 1일 12시 이후로 현재까지 경과된 시간을 미리 초단위로 반환

               var dtNow1 = Date.parse(new Date());    // 인자 값으로 variable 를 받습니다.

            - UTC

               1970년 1월 1일 자정 이후로 현재까지 경과된 시간을 밀리 초 단위로 반환

               var dtNow2 = Date.UTC(2009,04,29,09,40,20);  // 인자 값으로 int 를 받습니다.

 

            ※ 정적 메소드의 특정 중 하나는 객체 인스턴스를 통하지 않고 공유 Date 객체에 직접 접근도 가능하다.  

        ㉢ Date 객체의 메소드

            - getDay()        

               일, 결과값은 1~31 중 한개의 숫자

     

            - getDate()                    ↔ setDate()

               요일에 해당하는 수치값을 반환하거나 그 값을 재 설정하는데 사용한다.

                0 = 일요일, 1 =  월요일 , 2 = 화요일 , 3 = 수요일 , 4 = 목요일 , 5 = 금요일 , 6 = 토요일

 

            - getFullYear()              ↔ setFullYear()

               네자리 숫자의 연도, 결과 값은 1900과 같은 식으로 나타내거나 값을 재 설정하는데 사용한다.

              

            - getHours()                  ↔ setHours()

               시 , 결과값은 0~23 중 한개의 숫자값을 반환하거나 값을 재 설정하는데 사용한다.                

 

            - getMilliseconds()        ↔ setMilliseconds()

               밀리초 , 결과값은 0~999 중 한 개의 숫자 값을 반환하거나 값을 재 설정하는데 사용한다.

 

            - getMinutes()               ↔ setMinutes()

               분 , 결과값은 0~59 중 한 개의 숫자 값을 반환하거나 값을 재 설정하는데 사용한다.              

              

            - getMonth()                  ↔ setMonth() 

               월, 결과값은 0~11의 값을 반환한다.  (0은 1월 , 1은 2월 .....)

 

            - getSeconds()              ↔ setSeconds()

               초 , 결과값은 0~59 중 한 개의 숫자 값을 반환하거나 값을 재설정하는데 사용한다.             

 

            - getYear()               

               1900년 이후의 연도, 결과값, 1900~1999년도 사이의 0 ~ 99 , 그 이후는 네 자리 숫자의 년도

 

            - getTime()                    ↔ setTime()

               1970년 1월 1일 이후 시간을 1000분 1초로 나타낸값               

 

            - getTimezoneOffset()

               사용자 지역 시간과 GMT의 차이(분 단위)를 반환 , 결과값은 0 ~ 1439  중 한개의 숫자           

 

            [UTC계 날짜와 시각에 대한 값을 가져오는 메소드]

 

            - getUTCDate()               ↔ setUTCDate()

               Data 객체의 날짜를 변경하거나 날짜타입을 받아 온다.

               인자값은 숫자 타입  : setDate(숫자)               

              

            - getUTCDay()                

               getDay() 메소드 같음

 

            - getUTCFullYear()         ↔ setUTCFullYear()

               getFullYear() && setFullYear() 메소드 같음

 

            - getUTCHours()            ↔ setUTCHours()

               getHours()  && setHour() 메소드 같음

 

            - getUTCMilliseconds()  ↔ setUTCMilliseconds()

               getMilliseconds()  && setMilliseconds() 메소드 같음               

 

            - getUTCMinutes()         ↔ setUTCMinutes() 

               getMinutes()  && setMinutes() 메소드 같음               

 

            - getUTCMonth()            ↔ setUTCMonth()  

               getMonth()  && setMonth() 메소드 같음               

 

            - getUTCSeconds()        ↔  setUTCSeconds()

               getSeconds()  && setSeconds() 메소드 같음               

                             

           

    

           

       

         ㉣ 날짜 객체에서 리턴값을 문자열로 반환하는 메소드

             - toString

                로컬 시각을 문자열로 출력한다.

 

             - toGMTString

               문자열 형식을 GMT 표준으로 지정한다.

 

             - toLocaleDateString과 toLocalTimeString

                로케일을 사용해서 날짜와 시각을 출력한다.

 

             - toLocaleString

                문자열 형식을 현재 로케일로 지정한다.

 

             - toUTCString

               문자열 형식을 UTC 표준으로 정한다.

 

    ② Math  

        수학적 프로퍼티와 메소드를 제공하는 객체

        Math 객체의 프로퍼티는 여타 자바스크립트 객체와는 달리 모두 정적       

        

        ㉠ 로그

             - LN10 : 10의 자연로그 값, 즉, loge10의 값

                Math.LN10

             - LN2  : 2의 자연로그 값, 즉, loge2의 값

                Math.LN2

             - LOG2E : LN2의 역 근사값 즉, log2e의 값

             - LOG10E: LN10의 역 근사값 즉, log10e의 값

 

        ㉡ 루트            

             - SQRT1_2  루트값 , 즉 루트 1/2

             - SQRT2 루트값 ,  즉 루트 2

 

        ㉢ 삼각함수

             - Math.sin(x) : 사인값을 계산한다.

                x 는 인자값으로 각도를 라디안 값으로 입력받는다.

             - Math.cos(x) : 코사인값을 계산하다.

                x 는 인자값으로 각도를 라디안 값으로 입력받는다.

             - Math.tan(x) : 탄젠트값을 계산하다.

                x 는 인자값으로 각도를 라디안 값으로 입력받는다.

             - Math.asin(x)  : 아크 사인값을 계산한다.

                x는 인자값으로 -1과 1 사이의 숫자를 입력받는다.

             - Math.acos(x) : 아크 코사인값을 계산한다.

                x는 인자값으로 -1과 1 사이의 숫자를 입력받는다.      

             - Math.aton(x) : 아크 탄젠트값을 계산한다.

                인자로는 모든 숫자가 가능하다.

             - Math.atan2(py,px) : (x,y) 좌표의 아크 탄젠트값을 계산하다.

                인자로는 한 점의 y와 x 좌표값을 입력받는다.

 

         ㉣ 기타 함수

             - Math.ceil(x)

               x는 인자값이고 ceil 메소드는 x값에 대해 무조건 반올림하여 값을 반환한다.

               var nVal = 3.40;
               alert(Math.ceil(nVal));  //4

 

             - Math.floor(x)

               x는 인자값이고 floor 메소드는 x값에 대해 내림값으로 반환한다.

               var nVal = -3.40;
               alert(Math.floor(nVal));  // -4

 

             - Math.round(x)

                x는 인자값이고 메소드는 x값에 대해 반올림이 가능한 경우 값을 반올림하고 그 값을 반환한다.

 

             - Math.exp(x)

                자연로그의 밑인 e의 지수승(e^x) 에 해당 하는 수를 계산하여 반환한다.  

 

             - Math.pow(x)

                x는 인자로 전자 값에 후에 멱승을 계산하여 반환하다.

                var nVal = Math.pow(3,2)  // 3^2 = 9                 

 

             - Math.max(인자1, 인자2, 인자3...)

                인자 값 중에 가장 큰 값을 반환한다.

        

             - Math.min(인자1, 인자2, 인자3...)

                인자 값 중에 가장 작은 값을 반환한다.

 

             - Math.random();           

               0과 1 사이의 값을 반환한다.

 

            

 

⑺ 배열

   - 자바스크립트에서 배열은 하나의 객체로 본다.

   - 배열을 생성할 때는 Array() 생성자를 사용한다.

      var newArr = new Array('1st','2st); ↔ var newArr = new Array(5);

   - 리터럴 값을 배열에 바로 사용할 경우에는 Array() 생성자를 사용하지 않는다.

      var newArr = ['1st','2st']; // 자바스크립트에 엔진이 바로 Array 타입의 객체로 변환한다.

   - 배열의 인덱스

     배열의 각 원소는 인덱스 값에 통해 접근할 수 있다. 즉, 인덱스값은 곳 배열 원소의 위치를 가리키는 숫자다.

     배열의 인덱스는 0부터 시작해서 '배열의 총개수 -1'까지 증가한다.

   

   ① 배열에 객체에 메소드 및 프로퍼티

       ㉠ lenth

           배열의 길이를 숫자 타입으로 반환한다.

 

       ㉡ splice() 메소드

           제거된 원소를 배열값으로 반환한다.

           slice(원소의 인덱스 위치, 원소의 갯수, 추가할 문자열 값)

 

           var computerArr = new Array('CPU','Main Board', 'Graphic Card', 'RAM');
           var ChangeComputer  = computerArr.splice(2, 1, 'CD-ROM','CAM');
     
           alert(' No update : ' + computerArr + '\n New update : ' + ChangeComputer);   

           

            

           

 

       ㉢ slice() 메소드

           배열에서 지정한 범위에 해당하는 부분 배열을 반환한다.

           slice(반환할 원소의 시작 인덱스, 반환할 원소의 라스트 인덱스) 

 

          var computerArr = new Array('CPU','Main Board', 'Graphic Card', 'RAM');
          var ChangeComputer  = computerArr.slice(2, 4);
    
          alert(' No update : ' + computerArr + '\n New update : ' + ChangeComputer);  

 

            

 

       ㉣ concat() 메소드

          배열 뒤에 다른 배열을 붙인다.

          

         var computerArr1 = new Array('CPU','Main Board', 'Graphic Card', 'RAM');
         var computerArr2 = ['Dica','Notebook'];
    
         alert(' com1 : ' + computerArr1 + '\n com2 : ' + computerArr1.concat(computerArr2));

 

          

        

 

       ㉤ join() 메소드

           자바스크립트 엔진은 쉼표(,)를 구분자로 사용해 배열을 문자열로 반환하는 것이 기본이지만

           쉼표가 아닌 다른 구분자를 지정하고 싶을 경우 사용하는 메소드

 

           var computerArr = new Array('CPU','Main Board', 'Graphic Card', 'RAM');
         
            alert(computerArr.join('*'));    

 

           

            

         

       ㉥ reverse() 메소드     

          배열 안에 들어 있는 원소들의 순서를 뒤집을 경우 사용하는 메소드다.

 

         var computerArr = new Array('CPU','Main Board', 'Graphic Card', 'RAM');          
         alert('1st : ' + computerArr + '\n2st : ' + computerArr.reverse());   

                

         

 

       ※ concat와 slice는 원래의 배열을 변경하지 않고 수행결과를 배열로 반환한다.   

 

   ② 큐  

       FIFO(First In First Out : 선입선출) : 먼저 들어간 것이 먼저 나오는 데이터 구조

 

       ㉠ push()

           배열 끝에 원소를 추가하는 메소드

 

       ㉡ pop()

           배열 원소 끝에 원소를 제거하는 메소드

 

       ㉢ shift()

           첫번째 원소를 제거한는 메소드

 

       ㉣ unshift()

           배열의 시작위치에 원소를 추가하는 메소드 

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments