•  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
리캡챠에 안 시달려도 되는 좋은 VPNGATE 아이피: 211.204.195.49


1. Node.js로 더시드용 봇을 구현할 때 4.18.2에서 X-Chika의 값을 가져오기2. OTP 인증3. 터보위키에서 쓰는 역사 포크기 플러그인4. the seed용 자동 반달 복구기5. the seed 4.16.0+용 Node.js 봇 라이브러리6. 탭7. 색 선택기8. C언어 난독화9. 디스코드 API 메시지 파서10. 디스코드 메시지 추출기11. 디스코드 메시지 추출기 212. 맞춤법 수정13. 사이트들14. 할일15. 무료 데이타·파티션 복구16. Windows Longhorn 설치 시 오류 해결하기17. 틀:댓글

1. Node.js로 더시드용 봇을 구현할 때 4.18.2에서 X-Chika의 값을 가져오기[편집]

// Chika 값을 가져온다(안하면 편집, 토론 댓글달기 등이 작동하지 않음).
const thiscls = this;

http.request({
	host: hosts[thiscls.wikiname],
	path: '/RecentChanges'
}, function(res) {
	var ret = '';

	res.on('data', function(chunk) {
		ret += chunk;
	});

	res.on('end', function() {
		// main.어쩌구저쩌구.js 호출하는 부분 찾기
		var htmldata = ret;
		var mainjs   = ret.match(/<script src=\"(\/skins\/(((?!\/).)+)\/main[.]([a-z0-9]+)[.]js)\" defer><\/script>/);
		//  ^^^^^^ JS 해시 파일명
		
		http.request({
			host: hosts[thiscls.wikiname],
			path: mainjs[1]
		}, function(res) {
			var ret = '';

			res.on('data', function(chunk) {
				ret += chunk;
			});
			
			// 스크립트 내용을 다 불러왔으면
			res.on('end', function() {
				// 'X-Chika':a2_0x1234('0x123') 부분 찾기(그 함수가 문자열 배열에서 값을 가져와줌)
				const _chika = ret.match(/\'X[-]Chika\'[:](((?![,]).)+)/);
				
				// (window.webpackJsonP = window.webpackJsonP || [])의 바로 전 부분의 코드를 통째로 가져온다.
				const toe
				= ret
				  .split(ret.match(/;[(]window\[(((?!\]).)+)\]=window\[(((?!\]).)+)\][|][|]\[\][)]\[a/g)[0])[0]
				  .replace(/^var\s/, 'global.')  // 문자열 배열의 이름인 var a2_0x2331를 global.a2_0x2331로 바꾼다(안하면 ReferenceError)
				  .replace(/[)][)][;]var\sa/, '));global.a');  // 문자열 배열에서 값을 가져오는 함수 a2_0x41a4도 var에서 글로벌로 바꾼다
				
				try {  // eval로 코드를 실행하는데, 코드의 뒷부분에서 오류가 발생하기 때문에 try 블럭 사용
					eval(toe);  // 바꿨으면 코드를 실행해서 문자열 배열과 문자열 배열 함수를 만든다.
					throw 1; 
				} catch(e) {
					  chika[thiscls.wikiname]
					= thiscls.chika
					= eval(_chika[1]);  // 이제 a2_0x41a4 함수가 만들어졌으므로 아까 _chika에 저장한 'X-Chika':a2_0x41a4('0x7e9')에서 a2_0x41a4('0x7e9')를 실행해서 chika의 값을 받아오면 끝!
				}
			});
		}).end();
	});
}).end();

2. OTP 인증[편집]

const speakeasy = require('speakeasy');
const print = console.log;

// https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
function rndval(chars, length) {
	var   result           = '';
	const characters       = chars;
	const charactersLength = characters.length;
	for (i=0; i<length; i++) {
		result += characters.charAt(Math.floor(Math.random() * charactersLength));
	}
	return result;
}

const key = rndval('01234567', 4) + '-' + rndval('01234567', 4) + '-' + rndval('01234567', 4) + '-' + rndval('01234567', 4) + '-' + rndval('01234567', 4) + '-' + rndval('01234567', 4) + '-' + rndval('01234567', 4) + '-' + rndval('01234567', 4);
print('전화기에 Google OTP 애플리케이션을 설치하고 하단의 뿌리스 기호를 누를 뒤, [제공된 키 입력]에 들어가 키를 입력합니다.');
print('OTP 키는 ' + key + '입니다.\r\n');

setInterval(() => 
	print('OTP 화면에 ' + 
		speakeasy.totp({
			secret: key.replace(/[-]/g, ''),
			encoding: 'base32'
		})
	+ '가 나오면 정상 등록이 된 것입니다.')
, 10000);

3. 터보위키에서 쓰는 역사 포크기 플러그인[편집]

// 필수 코드 시작 //
const {
	render, conn, curs, ip_check, ip_pas, html, ban_check, config, getperm, 
	showError, getTime, toDate, generateTime, timeFormat, islogin, stringInFormat, 
	timeout, generateCaptcha, validateCaptcha, alertBalloon
} = require('./../../index.js');
// 필수 코드 종료 //

const theseed = require('./theseed.js');

module.exports = {
	urls: [/\/import\/(.*)/, /\/import\/(.*)/],
	codes: [
		{
			method: 'get',
			code: async function(req, res) {
				const title = req.params[0] || '';
				
				if(!getperm(req, 'import_history', ip_check(req))) {
					return res.send(await showError(req, 'insufficient_permissions'));
				}
				
				var content = `
					<form method=post>
						${alertBalloon('[경고!]', '이 위키와 동일한 라이선스의 위키의 역사만 포크하십시오. 또한 리비전 수에 따라 1분 이상 소요될 수 있습니다(오랜 시간동안 브라우저에서 로딩 표시가 나오는 것은 정상입니다). 완료되면 자동으로 역사 페이지로 이동됩니다.', 'success', 0)}
					
						<div class=form-group>
							<label>위키 엔진: <label><br />
							<select name=engine class=form-control>
								<option value="the seed">the seed (4.16.0 이상)</option>
                <option value="the seed2">the seed (4.7.0~4.12.0)</option>
                <option value="opennamu">openNAMU (3.2.0 이상)</option>
							</select>
						</div>
						
						<div class=form-group>
							<label>포크할 위키 이름: <label><br />
							<select name=wikiname class=form-control>
								<option value=a>알파위키</option>
								<option value=t>더시드위키</option>
							</select>
						</div>
						
						<div class=form-group>
							<label>문서 이름: <label><br />
							<input type=text name=title class=form-control value="${html.escape(title)}" />
						</div>
						
						<div class=form-group>
							<label>메모: <label><br />
							<input type=text name=note class=form-control />
						</div>
						
						<div class=btns>
							<button class="btn btn-danger" type=submit style="width: 100px;">포크</button>
						</div>
					</form>
				`;
				
				res.send(await render(req, '역사 포크', content));
			}
		},
		{
			method: 'post',
			code: async function(req, res) {
				if(!req.body['title']) {
					return res.send(await showError(req, 'invalid_request_body'));
				}
				
				if(!getperm(req, 'import_history', ip_check(req))) {
					return res.send(await showError(req, 'insufficient_permissions'));
				}
				
				const doctitle = req.body['title'];
				
				switch(req.body['engine']) {
					case 'the seed':
						var wiki;
				
						if(doctitle.match(/^(파일|사용자)[:]/)) {
							return res.send(await showError(req, 'invalid_namespace'));
						}
						
						try {
							wiki = theseed(req.body['wikiname']);
						} catch(e) {
							return res.send(await showError(req, 'invalid_request_body'));
						}
						
						const wikiname = ({
							'a': '알파위키',
							't': '더시드위키'
						})[req.body['wikiname']] || null;
						
						if(!wikiname) {
							return res.send(await showError(req, 'invalid_request_body'));
						}
						
						var prefix = '';
						switch(wiki.wikiname) {
							case 'alphawiki': prefix = 'A:';
							break; case 'theseedwiki': prefix = 'T:';
						}
						
						wiki.on('ready', () => {
							wiki.exportHistory(doctitle)
							.then(async history => {
								if(!history.length) {
									return res.send(await showError(req, 'document_not_found'));
								}
								
								const dbd = await curs.execute("select title from history where title = ?", [doctitle]);
								if(dbd.length) {
									return res.send(await showError(req, 'history_exists'));
								}
								
								await curs.execute("insert into history (title, content, rev, username, time, changes, log, iserq, erqnum, ismember, advance) \
												values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
									doctitle, '', '1', ip_check(req), getTime(), ('0'), '[' + wikiname + '의 ' + doctitle + ' 문서 포크] ' + (req.body['note'] || ''), '0', '-1', islogin(req) ? 'author' : 'ip', ''
								]);
								
								for(item of history) {
									const raw = await wiki.fetchRAW(doctitle, item.rev);
									var advance = '';
									
									switch(item.type) {
										case 'create':
											advance = '(새 문서)';
										break; case 'delete':
											advance = '(삭제)';
										break; case 'move':
											advance = '(이동)';
										break; case 'revert':
											advance = '(r' + item.target_rev + '로 되돌림)';
									}
									
									await curs.execute("insert into history (title, content, rev, username, time, changes, log, iserq, erqnum, ismember, advance) \
													values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
										doctitle, raw, String(Number(item.rev) + 1), (item.username.match(/^[A-Z][:]/) ? item.username : (prefix + item.username)), item.datetime, (Number(item.changes) > 0 ? '+' : '') + String(item.changes), `[리비전 ${item.rev}] ${item.log} `, '0', '-1', item.usertype, advance
									]);
								}
								
								if(await wiki.exists(doctitle)) {
									await curs.execute("insert into documents (title, content) values (?, ?)", [doctitle, await wiki.fetchRAW(doctitle)]);
								}
								
								return res.redirect('/history/' + doctitle);
							})
							.catch(async e => {
								console.log(e);
								return res.send(await showError(req, 'internal_error'));
							});
						});
					break; default:
						return res.send(await showError(req, 'invalid_request_body'));
				}
			}
		}
	],
	permissions: ['import_history'],
	permission_descriptions: {
		'import_history': '역사 가져오기'
	},
	create_table: {
	}
};

4. the seed용 자동 반달 복구기[편집]

const theseed = require('./seed');
const client = theseed('alpha');

function print(prpt) {
	process.stdout.write(prpt + '\n');
}

client.on('ready', () => {
	client.login('1', '2').then(e => print('로그인 완료.'));
});

client.on('change', item => {
	if(item.username == '116.38.**.**') {
		client.revert(item.document.fulltitle, String(Number(item.rev) - 1), '초고속! 초고속! 초고속! 즉시복구!!');
	}
});


SSD 240GB + HDD 1,000GB[고장] + HDD 320GB[2] + HDD 320GB[고장] + USB 128GB + USB 16GB = 2,024GB - 1,320GB조심히 다룰 걸 = 704GB

<1TB 하드의 죽음>
  • 컴퓨터에 프로그램을 너무 많이 깔아서 느려져서 윈도우를 재설치한다.
  • 제조사의 그래픽 드라이버를 깔기 전까지는 화면이 안 나와서 컴퓨터에서 무슨 일이 일어나는지를 몰라 강제 종료를 5번씩 했다.내가 정신이 나갔다
  • 540GB 파티션 접근이 갑자기 불가해진다.
  • 나머지 파티션에 다시 설치를 시도한다.
  • 컴퓨터가 거북이의 속도로 돌아간다.
  • 하드 디스크에서 이상한 소리가 나오기 시작한다.
  • 외장 하드로 연결 시 인식이 잘 안 되기 시작한다.
  • 겨우 하드를 노트북에 연결해서 데이타 복구 프로그램을 돌린다.
  • 잘 안 돼서 뺐다 꽂았다를 반복
  • 하드에서 또 이상한 소리가 난다.
  • 나머지 파티션 증발
  • 며칠 뒤 다시 연결 시도
  • 이상한 소리가 계속 나며 디스크 관리 프로그램에서 "디스크 초기화 안 됨" 메시지가 나오고 데이타 복구 프로그램에서는 하드가 있다는 것 자체를 모름
  • 실수로 하드 디스크의 표면을 눌렀다가 데이타가 저장된 플래터가 긁힌 것 같다.
  • 지금은 모터만 약하게 돌아가고 시시식 하는 소리가 나오는 것 외에는 아무 일도 일어나지 않는다.

5. the seed 4.16.0+용 Node.js 봇 라이브러리[편집]

옥텟트 스트림 미지원 / Windows XP에서 실행 가능
"use strict";

const http = require('https');

require('tls').DEFAULT_MIN_VERSION = 'TLSv1';

const chika = {
    // 실행 시마다 자동으로 가져오는 방식으로 변경됨
    // 아래 값은 무효
    namuwiki:    '9fe579274e586b950',
    alphawiki:   '903e1a140dbcd2df8',
    theseedwiki: '9ba957530204bbf25'
};

const hosts = {
    namuwiki:    'namu.wiki',
    alphawiki:   'awiki.theseed.io',
    theseedwiki: 'theseed.io'
};

if(typeof(Array.prototype.includes) !== 'function') {
    Array.prototype.includes = function(val) {
        for(var item of this) {
            if(item === val) return true;
        }
        
        return false;
    };
}

var onReadyCallback = null;

var userAgent = "Mozilla/5.0 (Windows NT 5.1; rv:68.9) Gecko/20100101 Goanna/4.6 Firefox/68.9 Mypal/28.12.0";
var pinPrompt = 'PIN: ';

function theseedRequest(wikiname, host, path, cookie, noInternal) {
    return new Promise((resolve, reject) => {
        http.request({
            host: host,
            path: (noInternal ? path : ('/internal' + path)),
            headers: {
                "X-Chika": chika[wikiname],
                "Cookie": cookie,
                "User-Agent": userAgent
            }
        }, function(res) {
            try {
                var ret = '';

                res.on('data', function(chunk) {
                    ret += chunk;
                });

                res.on('end', function() {
                    if(res.statusCode != 200) {
                        reject({
                            status: res.statusCode,
                            json: ret
                        });
                    } else {
                        resolve(JSON.parse(ret));
                    }
                });
            } catch(e) {
                reject(e);
            }
        }).end();
    });
}

function theseedPost(wikiname, host, path, jdata, cookie, returnRes, noInternal) {
    return new Promise((resolve, reject) => {
        const data = JSON.stringify(jdata);
        
        var req = http.request({
            host: host,
            path: (noInternal ? path : ('/internal' + path)),
            headers: {
                'X-Chika': chika[wikiname],
                'Cookie': cookie,
                'Content-Type': 'application/json',
                "User-Agent": "Mozilla/5.0 (Windows NT 5.1; rv:68.9) Gecko/20100101 Goanna/4.6 Firefox/68.9 Mypal/28.12.0"
            },
            method: 'POST'
        }, function(res) {
            try {
                var ret = '';

                res.on('data', function(chunk) {
                    ret += chunk;
                });

                res.on('end', function() {
                    if(returnRes) 
                        resolve({
                            json: JSON.parse(ret),
                            res: res
                        });
                    else {
                        if(res.statusCode != 200) {
                            reject({
                                status: res.statusCode,
                                json: ret
                            });
                        } else {
                            resolve(JSON.parse(ret));
                        }
                    }
                });
            } catch(e) {
                reject(e);
            }
        });
        req.write(data);
        req.end();
    });
}

class Document {
    constructor(title, namespace, forceShowNamespace) {
        this.title = title;
        this.namespace = namespace;
        this.forceShowNamespace = forceShowNamespace;
        
        var fulltitle;
        
        if((this.namespace == '문서' && this.forceShowNamespace) || this.namespace != '문서') {
            fulltitle = namespace + ':' + title;
        } else {
            fulltitle = title;
        }
        
        this.fulltitle = fulltitle;
    }
    
    toString() {
        return fulltitle;
    }
}

var jsnCheckedRecent  = {};
var jsnCheckedComment = {};

class Thread {
    constructor(obj, seed) {
        const items = ['document', 'status', 'topic', 'commentCount', 'slug'];
        for(var li in items) {
            const item = items[li];
            this[item] = obj[item];
        }
        
        this.theseed = seed;
    }
    
    comment(text) {
        const thiscls = this;
        const theseed = this.theseed;
        
        return new Promise((resolve, reject) => {
            theseedPost(theseed.wikiname, hosts[theseed.wikiname], '/thread/' + thiscls.slug, {
                text: String(text),
                identifier: theseed.identifier
            }, theseed.cookie).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
}

class ThreadComment {
    constructor(obj) {
        const items = ['id', 'username', 'usertype', 'datetime', 'hidden', 'type', 'admin', 'html'];
        for(var li in items) {
            const item = items[li];
            this[item] = obj[item];
        }
    }
}

var doLog = false;

function log(t) {
    if(doLog) console.log(t);
}

class Theseed {
    constructor(wikiname, pinprpt, ua) {
        if(typeof wikiname == 'string')
            wikiname = wikiname.toLowerCase();
        
        if(ua) userAgent = ua;
        if(pinprpt) pinPrompt = pinprpt;
        
        if([1, 'n', 'namu'].includes(wikiname)) wikiname = 'namuwiki';
        if([2, 'a', 'alpha'].includes(wikiname)) wikiname = 'alphawiki';
        if([3, 't', 'theseed'].includes(wikiname)) wikiname = 'theseedwiki';
        
        if(!wikiname) {
            throw Error('위키 이름을 지정하시오.');
            return;
        }
        
        this.wikiname = wikiname;
        this.cookie = '';
        this.ready = false;
        
        const thiscls = this;
        
        this.commentCount = {};
        
        this.host = hosts[thiscls.wikiname];
        if(!this.host) {
            throw Error('틀린 위키입니다.');
            return;
        }
        
        // Chika 값을 가져온다(안하면 편집, 토론 댓글달기 등이 작동하지 않음).
        http.request({
            host: hosts[thiscls.wikiname],
            path: '/RecentChanges'
        }, function(res) {
            var ret = '';
            
            res.on('data', function(chunk) {
                ret += chunk;
            });
            
            res.on('end', function() {
                // main.어쩌구저쩌구.js 호출하는 부분 찾기
                var htmldata = ret;
                var mainjs   = ret.match(/<script src=\"(\/skins\/(((?!\/).)+)\/main[.]([a-z0-9]+)[.]js)\" defer><\/script>/);
                //  ^^^^^^ JS 해시 파일명
                
                http.request({
                    host: hosts[thiscls.wikiname],
                    path: mainjs[1]
                }, function(res) {
                    var ret = '';
                    
                    res.on('data', function(chunk) {
                        ret += chunk;
                    });
                    
                    res.on('end', function() {
                        const _chika = ret.match(/\'X[-]Chika\'[:](((?![,]).)+)/);
                        const toe
                        = ret
                          .split(ret.match(/;[(]window\[(((?!\]).)+)\]=window\[(((?!\]).)+)\][|][|]\[\][)]\[/g)[0])[0]
                          .replace(/^var\s/, 'global.')
                          .replace(/[)][)][;]var\sa/, '));global.a');
                        
                        try {
                            eval(toe);
                            throw 1;
                        } catch(e) {
                              chika[thiscls.wikiname]
                            = thiscls.chika
                            = eval(_chika[1]);
                            
                            theseedRequest(thiscls.wikiname, hosts[thiscls.wikiname], '/RecentChanges', thiscls.cookie).then(data => {
                                thiscls.identifier = data.session.identifier;
                                thiscls.ready = true;
                                
                                if(onReadyCallback !== null) onReadyCallback();
                            }).catch(err => {
                                throw Error('CSRF 식별자 획득에 실패했읍니다. POST 기능이 작동하지 않습니다.');
                            });
                        }
                    });
                }).end();
            });
        }).end();
        
        // 봇이 꺼지지 않게...
        setInterval(() => {
            for(var i=0; i<10; i++);
        }, 2147483647);  // 24,855일동안 실행 가능
    }
    
    recentChanges(flag) {
        flag = flag || 'all';
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/RecentChanges?logtype=' + flag, this.cookie).then(data => {
                var recentData = data.data.recent;
                
                var retval = [];
                
                for(var ri=0; ri<recentData.length; ri++) {
                    const item = recentData[ri];
                    
                    retval.push({
                        datetime: Number(item.date) * 1000,
                        rev: Number(item.rev),
                        username: item.ip ? item.ip : item.author,
                        usertype: item.ip ? 'ip' : 'author',
                        log: item.log,
                        changes: Number(item.count),
                        type: item.logtype,
                        'document': new Document(item.doc.title, item.doc.namespace, item.doc.forceShowNamespace)
                    });
                }
                
                resolve(retval);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    recentDiscuss(flag) {
        flag = flag || 'normal_thread';
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/RecentDiscuss?logtype=' + flag, this.cookie).then(data => {
                var recentData = data.data.recent;
                
                var retval = [];
                
                for(var ri in recentData) {
                    const item = recentData[ri];
                    
                    retval.push({
                        datetime: Number(item.updated_date) * 1000,
                        topic: item.type == 'discuss' ? item.topic : null,
                        slug: item.slug,
                        type: item.type,
                        'document': new Document(item.doc.title, item.doc.namespace, item.doc.forceShowNamespace),
                    });
                }
                
                resolve(retval);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    discussFetch(slug, id) {
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        if(!id) {
            throw Error('댓글 번호를 명시하시오.'); return;
        }
        
        const thiscls = this;
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/thread/' + slug + '/' + id, this.cookie).then(data => {
                const comments = data.data.comments;
                var retval = [];
                
                for(var ci in comments) {
                    const res = comments[ci];
                    
                    retval.push(new ThreadComment({
                        id: res.id,
                        username: res.ip ? res.ip : res.author,
                        usertype: res.ip ? 'ip' : 'author',
                        datetime: Number(res.date) * 1000,
                        hidden: res.hide_author,
                        type: res.type,
                        admin: res.admin,
                        html: res.text
                    }));
                }
                
                resolve(retval);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    comment(slug, text) {
        const thiscls = this;
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/thread/' + slug, {
                text: String(text),
                identifier: thiscls.identifier
            }, thiscls.cookie).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    fetchDiscuss(slug) {
        const thiscls = this;
        
        if(!slug) {
            throw Error('토론 ID가 없습니다.');
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/thread/' + slug, this.cookie).then(data => {
                const item = data.data;
                
                resolve(new Thread({
                    document: new Document(item.document.title, item.document.namespace, item.document.forceShowNamespace),
                    status: item.status,
                    topic: item.topic,
                    commentCount: item.comments.length,
                    slug: slug
                }, thiscls));
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    createThread(title, topic, text) {
        const thiscls = this;
        if(!title) {
            throw Error('제목을 명시하시오.'); return;
        }
        if(!topic) {
            throw Error('주제를 명시하시오.'); return;
        }
        if(!text) {
            throw Error('내용을 쓰세요.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/discuss/' + title, {
                topic: topic,
                text: text,
                identifier: thiscls.identifier
            }, thiscls.cookie).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    hideRes(slug, id) {
        const thiscls = this;
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        if(!id) {
            throw Error('댓글 번호를 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/admin/thread/' + slug + '/' + id + '/hide', {
                id: String(id),
                slug: slug,
                identifier: thiscls.identifier
            }, thiscls.cookie, undefined, 1).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    showRes(slug, id) {
        const thiscls = this;
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        if(!id) {
            throw Error('댓글 번호를 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/admin/thread/' + slug + '/' + id + '/show', {
                id: String(id),
                slug: slug,
                identifier: thiscls.identifier
            }, thiscls.cookie, undefined, 1).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    updateThreadStatus(slug, status) {
        const thiscls = this;
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        if(!status) {
            throw Error('상태를 [close, normal, pause]중 하나로 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/admin/thread/' + slug + '/status', {
                status: status,
                slug: slug,
                identifier: thiscls.identifier
            }, thiscls.cookie, undefined, 1).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    updateThreadDocument(slug, title) {
        const thiscls = this;
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        if(!title) {
            throw Error('문서 이름을 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/admin/thread/' + slug + '/document', {
                document: title,
                slug: slug,
                identifier: thiscls.identifier
            }, thiscls.cookie, undefined, 1).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    updateThreadTopic(slug, topic) {
        const thiscls = this;
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        if(!topic) {
            throw Error('주제를 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/admin/thread/' + slug + '/topic', {
                topic: topic,
                slug: slug,
                identifier: thiscls.identifier
            }, thiscls.cookie, undefined, 1).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    lastEditedTime(title) {
        
    }
    
    on(evt, cb, a, b, c, d, e, f) {
        const thisClass = this;
        
        evt = evt.toLowerCase();
        var cbnf = false;
        
        if(['comment'].includes(evt)) {
            cbnf = (typeof a != 'function');
        } else {
            cbnf = (typeof cb != 'function');
        }
        
        if(cbnf) {
            throw Error('콜백이 함수가 아닙니다.'); return;
        }
        
        switch(evt) {
            case 'change':
                thisClass.changeWatcher = setInterval(function() {
                    if(thisClass.ready) {
                        thisClass.recentChanges().then(data => {
                            var firstItem = data[0];
                            
                            if(typeof thisClass.lastChangedTime === 'undefined') {
                                thisClass.lastChangedTime = 0;
                            } else {
                                if(!jsnCheckedRecent[firstItem.title + firstItem.rev]) {
                                    jsnCheckedRecent[firstItem.title + firstItem.rev] = 1;
                                } else {
                                    if(firstItem && firstItem.datetime > thisClass.lastChangedTime) {
                                        thisClass.lastChangedTime = firstItem.datetime;
                                        thisClass.fetchRAW(firstItem.document.fulltitle).then(raw => {
                                            firstItem['content'] = raw;
                                            cb(firstItem);
                                        });
                                    }
                                }
                            }
                        });
                    }
                }, 1000);
            break; case 'ready':
                onReadyCallback = cb;
            break; case 'comment':
                thisClass.commentWatcher = setInterval(function() {
                    const slug = cb;
                    var commentCount = thisClass.commentCount[slug];
                    
                    if(thisClass.ready) {
                        if(!commentCount) {
                            thisClass.fetchDiscuss(slug).then(data => {
                                thisClass.commentCount[slug] = data.commentCount;
                            });
                        } else {
                            thisClass.fetchDiscuss(slug).then(data => {
                                if(data.commentCount > commentCount) {
                                    commentCount = thisClass.commentCount[slug] = data.commentCount;
                                    
                                    thisClass.discussFetch(slug, commentCount).then(d => {
                                        a(d[1]);
                                    });
                                }
                            });
                        }
                    }
                }, 1100);
        }
    }
    
    destroyEvent(evt) {
        switch(evt) {
            case 'comment':
                clearInterval(this.commentWatcher);
            break; case 'change':
                clearInterval(this.changeWatcher);
            break; case 'ready':
                onReadyCallback = null;
        }
    }
    
    fetchHTML(title, rev) {
        if(!title) {
            throw Error('제목이 없습니다.');
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/w/' + encodeURIComponent(title) + (rev ? '?rev=' + rev : ''), this.cookie).then(data => {
                resolve(data.data.content);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    fetchRAW(title, rev) {
        if(!title) {
            throw Error('제목이 없습니다.');
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/raw/' + encodeURIComponent(title) + (rev ? '?rev=' + rev : ''), this.cookie).then(data => {
                resolve(data.data.text);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    exists(title) {
        if(!title) {
            throw Error('제목이 없습니다.');
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/w/' + encodeURIComponent(title), this.cookie).then(data => {
                resolve(data.status == 200);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    discussOngoing(title) {
        if(!title) {
            throw Error('제목이 없습니다.');
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/w/' + encodeURIComponent(title), this.cookie).then(data => {
                resolve(data.data.discuss_progress);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    edit(title, text, log, section) {
        const thiscls = this;
        
        var token, baserev;
        
        if(!title) {
            throw Error('문서 제목을 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/edit/' + encodeURIComponent(title) + (section ? '?section=' + section : ''), this.cookie).then(data => {
                thiscls.token = token = data.data.token;
                baserev = data.data.body.baserev;
                
                theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/edit/' + encodeURIComponent(title) + (section ? '?section=' + section : ''), {
                    text: String(text),
                    token: token,
                    identifier: thiscls.identifier,
                    baserev: baserev,
                    agree: 'Y',
                    log: log ? log : ''
                }, thiscls.cookie).then(resolve).catch(err => {
                    reject(err);
                });
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    revert(title, rev, log) {
        const thiscls = this;
        
        if(!title) {
            throw Error('문서 제목을 명시하시오.'); return;
        }
        
        if(!rev) {
            throw Error('리비전을 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/revert/' + encodeURIComponent(title) + '?rev=' + rev, {
                identifier: thiscls.identifier,
                rev: String(rev),
                log: log ? log : ''
            }, thiscls.cookie).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    delete(title, note) {
        const thiscls = this;
        
        const params = {
            log: note ? note : '     ',
            agree: 'Y'
        };
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/delete/' + encodeURIComponent(title), params, thiscls.cookie).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    move(title, newtitle, note, swap) {
        const thiscls = this;
        
        const params = {
            log: note ? note : '     ',
            title: newtitle,
            mode: swap ? swap :  undefined
        };
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/move/' + encodeURIComponent(title), params, thiscls.cookie).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
    
    random() {
        const thiscls = this;
        
        return new Promise((resolve, reject) => {
            theseedRequest(thiscls.wikiname, hosts[thiscls.wikiname], '/random', thiscls.cookie).then(data => {
                resolve(decodeURIComponent(data.url.replace(/^\/w\//, '')));
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    putToGroup(groupname, usertype, username, note, duration) {
        const thiscls = this;
        
        usertype = usertype.toLowerCase().replace('author', 'username').replace('member', 'username');
        
        var params = {
            mode: usertype,
            ip: usertype == 'ip' ? username : undefined,
            username: usertype == 'username' ? username : undefined,
            expire: String(duration),
            group: groupname,
            note: note
        };
        
        theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/aclgroup', params, thiscls.cookie).then(resolve).catch(err => {
            reject(err);
        });
    }
    
    deleteFromGroup(groupname, id, note) {
        const thiscls = this;
        
        usertype = usertype.toLowerCase().replace('author', 'username').replace('member', 'username');
        
        var params = {
            note: note,
            id: String(id),
            group: groupname.replace(/\s/g, '+')
        };
        
        theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/aclgroup/remove', params, thiscls.cookie).then(resolve).catch(err => {
            reject(err);
        });
    }
    
    getacl(title, action, isns) {
        const thiscls = this;
        
        if(!title) {
            throw Error('문서 제목을 명시하시오.'); return;
        }
        
        if(!action) {
            throw Error('작업 ID(read, edit, move, delete, create_thread, write_thread_comment, acl중 하나)를 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/acl/' + encodeURIComponent(title), this.cookie).then(data => {
                if(data.status != 200) {
                    reject(data.data.content)
                    return;
                }
                
                if(isns) resolve(data.data.nsACL.acls[action]);
                else resolve(data.data.docACL.acls[action]);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    setacl(title, mode, type, condition, action, expiration, isns, ID, afterID) {
        const thiscls = this;
        
        // 예제
        //   namu.setacl('제목', 'insert', 'edit', 'perm:admin', 'allow', 0) => 편집 ACL에 관리자 허용 ACL 추가
        //   namu.setacl('제목', 'delete', 'edit', undefined, undefined, 0, 1) => 편집 ACL 1번 삭제
        //   namu.setacl('제목', 'move', 'edit', undefined, undefined, 0, 1, 3) => 편집 ACL의 1번을 3번으로 옮김
        
        if(!title) {
            throw Error('문서 제목을 명시하시오.'); return;
        }
        
        if(!type) {
            throw Error('작업 ID(read, edit, move, delete, create_thread, write_thread_comment, acl중 하나)를 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(this.wikiname, hosts[this.wikiname], '/acl/' + encodeURIComponent(title), {
                mode: mode,
                type: type,
                isNS: isns ? 'Y' : undefined,
                condition: condition,
                action: action,
                expire: String(expiration),
                id: String(ID),
                after_id: String(afterID)
            }, this.cookie).then(data => {
                if(data.status >= 400) {
                    reject(data)
                    return;
                }
                
                resolve(data);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    history(title, options) {
        // options에는 until이나 from
        
        options = options || {};
        
        var from = options.from;
        var until = options.until;
        
        var flag = '';
        
        if(until) flag = '?until=' + until;
        if(from) flag = '?from=' + from;
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/history/' + encodeURIComponent(title) + flag, this.cookie).then(data => {
                var historyData = data.data.history;
                
                var retval = [];
                
                for(var ri in historyData) {
                    const item = historyData[ri];
                    
                    retval.push({
                        datetime: Number(item.date) * 1000,
                        rev: Number(item.rev),
                        username: item.ip ? item.ip : item.author,
                        usertype: item.ip ? 'ip' : 'author',
                        log: item.log,
                        changes: Number(item.count),
                        type: item.logtype,
                        target_rev: item.target_rev
                    });
                }
                
                resolve(retval);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    login(username, password) {
        const thiscls = this;
        
        return new Promise((resolve, reject) => {
            theseedPost(this.wikiname, hosts[this.wikiname], '/member/login', {
                username: username,
                password: password
            }, this.cookie, 1).then(data => {
                const cookies = data.res.headers['set-cookie'];
                const json = data.json;
                
                for(var ci=0; ci<cookies.length; ci++) {
                    const cookie = cookies[ci];
                    thiscls.cookie += cookie.split(';')[0] + ';';
                }
                
                if(!thiscls.cookie) {
                    reject(-1);
                } else {
                    if(json.viewName == 'login_pin') {
                        var pin;
                        
                        const readline = require('readline');
                        const rl = readline.createInterface({
                            input: process.stdin,
                            output: process.stdout
                        });
                        
                        function rlCallback(pin) {
                            try {
                                rl.close();
                            } catch(e) {}
                            
                            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/member/login/pin', {
                                pin: (pin ? String(pin) : '111111'),
                                trust: 'on'
                            }, thiscls.cookie, 1).then(resp => {
                                const cookies = resp.res.headers['set-cookie'];
                                const jsn = resp.json;
                                
                                for(var ci=0; ci<cookies.length; ci++) {
                                    const cookie = cookies[ci];
                                    if(thiscls.cookie.includes(cookie.split(';')[0].split('=')[0])) continue;
                                    thiscls.cookie += cookie.split(';')[0] + ';';
                                }
                                
                                theseedRequest(thiscls.wikiname, hosts[thiscls.wikiname], '/RecentChanges', thiscls.cookie).then(data2 => {
                                    thiscls.identifier = data2.session.identifier;
                                    resolve(1);
                                }).catch(err => {
                                    reject(err);
                                });
                            }).catch(err => {
                                reject(err);
                            });
                        }
                        
                        if(json.data.mode != 'disable') {
                            rl.question(pinPrompt, rlCallback);
                        } else {
                            rlCallback(111111);
                        }
                    } else {
                        theseedRequest(thiscls.wikiname, hosts[thiscls.wikiname], '/RecentChanges', thiscls.cookie).then(data => {
                            thiscls.identifier = data.session.identifier;
                            resolve(1);
                        }).catch(err => {
                            reject(err);
                        });
                    }
                }
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    logout() {
        const thiscls = this;
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/member/logout', this.cookie).then(data => {
                theseedRequest(thiscls.wikiname, hosts[thiscls.wikiname], '/RecentChanges', thiscls.cookie).then(data2 => {
                    thiscls.identifier = data2.session.identifier;
                    resolve(1);
                }).catch(err => {
                    reject(err);
                });
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    star(title) {
        const thiscls = this;
        
        if(!title) {
            throw Error('문서명이 없습니다.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/member/star/' + encodeURIComponent(title), this.cookie, 1).then(data => {
                resolve(data);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    unstar(title) {
        const thiscls = this;
        
        if(!title) {
            throw Error('문서명이 없습니다.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], '/member/unstar/' + encodeURIComponent(title), this.cookie, 1).then(data => {
                resolve(data);
            }).catch(err => {
                reject(err);
            });
        });
    }
    
    test(url) {
        return new Promise((resolve, reject) => {
            theseedRequest(this.wikiname, hosts[this.wikiname], url ? url : '/RecentChanges', this.cookie).then(data => {
                resolve(data);
            });
        });
    }
    
    render(content) {
        // /internal/preview
    }
    
    exportHistory(title, jsonpath) {
        const thiscls = this;
        var ret = [];
        
        return new Promise((resolve, reject) => {
            thiscls.history(title).then(data => {
                if(!data.length) return resolve([]);
                const historysize = Number(data[0]['rev']);
                
                function recursive(until) {
                    thiscls.history(title, { until: until }).then(d => {
                        ret = ret.concat(d);
                        if(historysize < until) {
                            ret.sort(function(l, r) {
                                return l['rev'] - r['rev'];
                            });
                            
                            if(jsonpath) {
                                require('fs').writeFile(jsonpath, JSON.stringify(ret), () => resolve(ret));
                            } else {
                                resolve(ret);
                            }
                        } else {
                            setTimeout(() => recursive(until + 30), 300);
                        }
                    }).catch(reject);
                }
                
                setTimeout(() => recursive(1), 300);
            }).catch(reject);
        });
    }
    
    // --------------------------------------
    
    // 아래는 deprecated 함수(보수안함)
    
    /**
     * @deprecated 쓰지 마세요. <Theseed>.comment()를 대신 사용하십시오.
     */
    postComment(slug, text) {
        const thiscls = this;
        if(!slug) {
            throw Error('토론 ID를 명시하시오.'); return;
        }
        
        return new Promise((resolve, reject) => {
            theseedPost(thiscls.wikiname, hosts[thiscls.wikiname], '/thread/' + slug, {
                text: String(text),
                identifier: thiscls.identifier
            }, thiscls.cookie).then(resolve).catch(err => {
                reject(err);
            });
        });
    }
}

module.exports = function(a, b, c) {
    return new Theseed(a || 1, b, c);
};

6. [편집]

<meta charset=utf-8 />

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

<script>
	$(function() {
		var bindTabClick;
		
		(bindTabClick = function() {
			$('tabbar tab:not([newtab]):not([disabled])').click(function() {
				$(this).parent().find('> tab').removeAttr('active');
				$(this).attr('active', '');
				
				var pageid = $(this).parent().attr('id');
				var to     = $(this).attr('page');
				
				$('tabcontent[tab="' + pageid + '"] page').removeAttr('active');
				$('tabcontent[tab="' + pageid + '"] page#' + to).attr('active', '');
			});
			
			$('tabbar tab:not([disabled]) close').click(function() {
				var pageid = $(this).parent().parent().attr('page');
				var tabid  = $(this).parent().parent().parent().attr('id');
				var page   = $('tabcontent[tab="' + tabid + '"] page#' + pageid);
				
				$(this).parent().parent().remove();
				if(page.attr('active') !== undefined) {
					$('tabcontent[tab="' + tabid + '"] page').removeAttr('active');
					$('tabcontent[tab="' + tabid + '"] page:first-child').attr('active', '');
					
					$('tabbar#' + tabid + ' tab[active]').removeAttr('active');
					$('tabbar#' + tabid + ' tab:first-of-type').attr('active', '');
				}
				page.remove();
			});
		})();
	
		$('tabbar tab[newtab]').click(function() {
			var pageid = 'newtab-page-' + Math.floor(Math.random() * 1e8);
			var newtab = $('<tab page="' + pageid + '"><t>새 탭 <close>×</close></t></tab>');
			
			$(this).before(newtab);
			$('tabcontent[tab="' + $(this).parent().attr('id') + '"]').append('<page id="' + pageid + '"></page>');
			bindTabClick();
			
			newtab.click();
		});
	});
</script>

<style>
	input.address-box {
		width: 100%;
		border: 1px solid #777;
		padding: 3px;
	}

	tabpage {
		/* 좌우로 채우려면 100%로 하지 말고 display를 block로 한다 */
		
		width: 800px;
		display: inline-block;
	}

	tabpage titlebar {
		background-image: linear-gradient(rgb(226, 226, 226) 0%, rgb(205, 204, 204) 41%, rgb(186, 185, 185) 40%, rgb(186, 185, 185) 100%);
		padding: 5px 8px 5px 8px;
		border: 1px solid #000;
		border-radius: 5px 5px 0 0;
		border-bottom: none;
		display: block;
		text-align: center;
	}
	
	tabpage toolbar {
		background-color: rgb(186, 185, 185);
		padding: 5px 8px 5px 8px;
		border: 1px solid #000;
		border-width: 0 1px 0 1px;
		display: block;
	}
	
	tabpage tabframe {
		border: 1px solid #000;
		padding: 6px;
		background-color: rgb(186, 185, 185);
		display: block;
		border-top: none;
		border-radius: 0 0 5px 5px;
	}

	tabpage tabbar {
		background-image: linear-gradient(rgb(246, 246, 246) 0%, rgb(246, 245, 245) 26%, rgb(235, 233, 233) 25%, rgb(225, 220, 220) 100%);
		display: block;
		padding: 4px 0 0 0;
		table-layout: fixed;
		width: 100%;
	}
	
	tabpage tabbar > a {
		text-decoration: none;
		color: currentcolor;
		padding: 0px 10px 0px 10px;
		font-size: 14pt;
		border: 1px solid transparent;
		display: table-cell;
	}
	
	tabpage tabbar > a:hover {
		border: 1px solid #ccc;
		border-radius: 4px;
		background-color: rgba(255, 255, 255, .9);
	}
	
	tabpage tabbar tab {
		display: table-cell;
		width: 190px;
		text-overflow: ellipsis;
	}

	tabpage tabbar tab t {
		padding: 5px 10px 7px 10px;
		border: 1px solid rgb(97, 108, 140);
		border-radius: 6px 6px 0 0;
		border-bottom: none;
		display: block;
		width: auto;
		position: relative;
		margin: 0 2px 0 2px;
		cursor: default;
		text-overflow: ellipsis;
		background-image: linear-gradient(rgb(244, 241, 241) 0%, rgb(233, 231, 231) 36%, rgb(212, 209, 209) 35%, rgb(212, 209, 209) 100%);
	}
	
	tabpage tabbar tab[disabled] t {
		background: #aaa;
		color: #555;
	}
	
	tabpage tabbar tab t close {
		float: right;
		color: rgb(128, 16, 16);
		font-weight: bold;
	}
	
	tabpage tabbar tab:not([disabled]):not([active]):hover t {
		background-image: linear-gradient(rgb(244, 241, 241) 0%, rgb(237, 235, 235) 36%, rgb(217, 213, 213) 35%, rgb(232, 231, 231) 100%);
	}
	
	tabpage tabbar tab[newtab] {
		width: 10px;
	}
	
	tabpage tabbar tab[newtab] t {
		font-weight: bolder;
	}

	tabpage tabbar tab[active] t {
		background-image: linear-gradient(rgb(242, 246, 254) 0%, rgb(227, 236, 253) 36%, rgb(205, 220, 248) 35%, rgb(240, 246, 255) 100%);
		margin: 0 2px 0 2px;
		border-bottom: 1px solid rgb(240, 246, 255);
		padding: 8px 10px 7px 10px;
		z-index: 2;
		font-weight: bold;
	}
	
	tabpage tabbar:after {
		border: none;
		background-color: rgb(240, 246, 255);
		border-top: 1px solid rgb(97, 108, 140);
		height: 7px;
		margin: -1px 0 0 0;
		content: "";
		z-index: 1;
		display: block;
		width: 100%;
		position: relative;
	}
	
	tabpage tabbar tab[active] t:before, tabbar tab[active] t:after {
		position: absolute;
		width: 5px;
		height: 5px;
		content: " ";
		border: 1px solid rgb(97, 108, 140);
	}
	
	tabpage tabbar tab[active] t:after {
		border-radius: 0 0 0 6px;
		border-width: 0 0 1px 1px;
		box-shadow: -2px 2px 0 rgb(240, 246, 255);
		top: 28px;
		right: -6px;
	}
	
	tabpage tabbar tab[active] t:before {
		border-radius: 0 0 6px 0;
		border-width: 0 1px 1px 0;
		box-shadow: 2px 2px 0 rgb(240, 246, 255);
		top: 28px;
		left: -6px;
	}
	
	tabpage tabcontent {
		border: 2px inset gray;
		padding: 8px;
		display: none;
		background: white;
		height: 400px;
		overflow-y: scroll;
		overflow-x: auto;
		display: block;
	}
	
	tabpage tabcontent page {
		display: none;
	}
	
	tabpage tabcontent page[active] {
		display: block;
	}
</style>

<tabpage>
	<titlebar>탭 예제</titlebar>

	<tabframe>
		<tabbar id=test>
			<a href>+</a
			><tab active page=1><t>탭 1 <close>×</close></t></tab
			><tab page=2><t>탭 2 <close>×</close></t></tab
			><tab page=3 disabled><t>탭 3 <close>×</close></t></tab
			><tab newtab><t>+</t></tab
		></tabbar>

		<tabcontent tab=test>
			<page id=1 active>탭 1의 내용.</page>
			<page id=2>탭 2의 내용.</page>
			<page id=3>탭 3의 내용.</page>
		</tabcontent>
	</tabframe>
</tabpage>


실제 적용 예시[4]

바나나 엔진 편집 창에 적용할 때는... theseed.js[5]나 NamuFix[6]가 감지되면 (기존처럼) 더시드 호환 탭을 표시하고 아니면 이 탭을 표시.

7. 색 선택기[편집]

<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<meta charset=utf-8 />

<style>
	.color-frame {
		line-height: 1;
		border-radius: 12345678px;
		padding: 12px;
		position: relative;
		color: transparent;
		border: 2px outset gray;
		box-shadow: 3px 3px 2px #ccc;
		display: inline-block;
	}

	.color-frame:before {
		background: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.4));
		position: absolute;
		width: 100%;
		height: 50%;
		content: "";
		left: 0px;
		top: 0px;
		border-top-left-radius: 2463px 2159px;
		border-top-right-radius: 2463px 2159px;
		border-bottom-left-radius: 2500px 258px;
		border-bottom-right-radius: 2500px 258px;
		line-height: 1;
	}
	
	.color-gradient {
		border-radius: 1234px;
		border: 2px outset gray;
		line-height: 1;
	}
</style>

<script>
	$(function() {
		/*
		 * micro-js / hsl-to-rgb ( https://github.com/micro-js/hsl-to-rgb )
		 * Committer(기여자): ashaffer
		 * License(라이선스): MIT
		 */
		function hslToRgb(h, s, l) {
			/* CSS 호환 */
			s /= 100, l /= 100;
		
			if(s == 0) return [l, l, l];
			h /= 360;

			var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
			var p = 2 * l - q;

			return [
				Math.round(hueToRgb(p, q, h + 1/3) * 255),
				Math.round(hueToRgb(p, q, h) * 255),
				Math.round(hueToRgb(p, q, h - 1/3) * 255)
			];
		}

		function hueToRgb(p, q, t) {
			if(t < 0) t += 1;
			if(t > 1) t -= 1;
			if(t < 1/6) return p + (q - p) * 6 * t;
			if(t < 1/2) return q;
			if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;

			return p;
		}
		/* ---------------------------------- */
		
		function randint(s, e) {
			return Math.floor(Math.random() * (e + 1 - s) + s);
		}
		
		$('#random-h').click(function() {
			$('#hue').val(randint(0, 360)).change();
		});
		
		$('#random-s').click(function() {
			$('#sat').val(randint(1, 100)).change();
		});
		
		$('#random-l').click(function() {
			$('#bri').val(randint(0, 100)).change();
		});
		
		$('#random-all').click(function() {
			$('#random-h').click();
			$('#random-s').click();
			$('#random-l').click();
		});
	
		$('#hue, #sat, #bri').on('input change', function() {
			$('#picked-color').css('background-color', 'hsl(' + $('#hue').val() + ', ' + $('#sat').val() + '%, ' + $('#bri').val() + '%)');
			$('#picked-color-h').css('background-color', 'hsl(' + $('#hue').val() + ', 100%, 50%)');
			$('#picked-color-s').css('background-color', 'hsl(240, ' + $('#sat').val() + '%, 50%)');
			$('#picked-color-l').css('background-color', 'hsl(240, 100%, ' + $('#bri').val() + '%)');
		
			$('#h').val(Math.floor(Number($('#hue').val()) * (240 / 360)));
			$('#s').val(Math.floor(Number($('#sat').val()) * (240 / 100)));
			$('#l').val(Math.floor(Number($('#bri').val()) * (240 / 100)));
			
			var rgb = hslToRgb(Number($('#hue').val()), Number($('#sat').val()), Number($('#bri').val()));
			
			$('#r').val(rgb[0]);
			$('#g').val(rgb[1]);
			$('#b').val(rgb[2]);
			
			var a, b, c;
			
			$('#html').val((((a = rgb[0].toString(16)) < 10 ? '0' + a : a) + ((b = rgb[1].toString(16)) < 10 ? '0' + b : b) + ((c = rgb[2].toString(16)) < 10 ? '0' + c : c)).toUpperCase());
		});
		
		$('#hue').on('input change', function() {
			$('#bri').prev().css('background-image', 'linear-gradient(to right, #000, hsl(' + $(this).val() + ', ' + $('#sat').val() + '%, 50%), #fff)');
			$('#sat').prev().css('background-image', 'linear-gradient(to right, #888, hsl(' + $(this).val() + ', 100%, 50%))');
		});
		
		$('#sat').on('input change', function() {
			$('#bri').prev().css('background-image', 'linear-gradient(to right, #000, hsl(' + $('#hue').val() + ', ' + $(this).val() + '%, 50%), #fff)');
		});
		
		$('#picked-color').click(function() {
			$('#saved-colors div').prepend($('<table style="display: table-cell;"><tr><td style="text-align: center;"><span class=color-frame style="background-color: ' + $(this).css('background-color') + '; padding: 6px;">__</span></td></tr><tr><td style="font-size: 9pt;">#' + $('#html').val() + '</td></tr></table>'));
		});
		
		$('#hue').change();
	});
</script>

<table>
	<tr>
		<td rowspan=3 style="vertical-align: top; padding: 18px 8px 0 0; text-align: center;">
			<span class=color-frame id=picked-color style="background-color: red; cursor: cell;" title="고른 색">__</span>
			<br /><br />
			<span class=color-frame id=picked-color-h style="background-color: red;  padding: 4px; margin-bottom: 10px;" title="색상">__</span><br />
			<span class=color-frame id=picked-color-s style="background-color: blue; padding: 4px; margin-bottom: 10px;" title="채도">__</span><br />
			<span class=color-frame id=picked-color-l style="background-color: blue; padding: 4px; margin-bottom: 10px;" title="명도">__</span><br />
		</td>
		
		<td style="padding: 0 0 20px 0;">
			<div class=color-gradient style="height: 10px; width: 100%; background-image: linear-gradient(to right, red, yellow, yellow, #0f0, #0ff, blue, purple, hotpink, red);"></div>
			<input type=range max=360 min=0 value=0 id=hue style="width: 100%; margin: 0;" />
			
			<span style="float: left; width:15%">빨강</span>
			<span style="float: left; width:20%">노랑</span>
			<span style="float: left; width:20%">초록</span>
			<span style="float: left; width:20%">파랑</span>
			<span style="float: left; width:15%">보라</span>
			<span style="float: right;">분홍</span>
		</td>
		
		<td style="vertical-align: middle;"><button id=random-h title="무작위 생성">*</button></td>
	</tr>
	
	<tr>
		<td style="padding: 0 0 20px 0;">
			<div class=color-gradient style="height: 10px; width: 100%; background-image: linear-gradient(to right, #888, red);"></div>
			<input type=range max=100 min=1 value=100 id=sat style="width: 100%; margin: 0;" />
			
			<span style="float: left; width:25%">무색</span>
			<span style="float: left; width:25%">25%</span>
			<span style="float: left; width:20%">50%</span>
			<span style="float: left; width:15%">75%</span>
			<span style="float: right">선명</span>
		</td>
		
		<td style="vertical-align: middle;"><button id=random-s title="무작위 생성">*</button></td>
	</tr>
	
	<tr>
		<td style="padding: 0 0 20px 0;">
			<div class=color-gradient style="height: 10px; width: 100%; background-image: linear-gradient(to right, #000, red, #fff);"></div>
			<input type=range max=100 min=0 value=50 id=bri style="width: 100%; margin: 0;" />
			
			<span style="float: left; width:25%">검정</span>
			<span style="float: left; width:25%">어둡게</span>
			<span style="float: left; width:20%">보통</span>
			<span style="float: left; width:15%">밝게</span>
			<span style="float: right">흰색</span>
		</td>
		
		<td style="vertical-align: middle;"><button id=random-l title="무작위 생성">*</button></td>
	</tr>
	
	<tr>
		<td colspan=3>
			R<input type=number readonly id=r style="width: 60px;" />
			G<input type=number readonly id=g style="width: 60px;" />
			B<input type=number readonly id=b style="width: 60px;" />
			
			H<input type=number readonly id=h style="width: 60px;" />
			S<input type=number readonly id=s style="width: 60px;" />
			L<input type=number readonly id=l style="width: 60px;" />
			
			#<input type=text readonly id=html style="width: 70px;" />
			
			<button id=random-all title="무작위 생성">*</button>
		</td>
	</tr>
	
	<tr>
		<td colspan=3 id=saved-colors style="max-width: 0px;">
			<div style="overflow: auto;"></div>
		</td>
	</tr>
</table>

8. C언어 난독화[편집]

GCC에서만 가능. 그리고 C++ 말고 C로만 가능. 안 그러면 콤파일 오류.
const int a5_ff4a[] = {0x7E3, 0x3ADE68B1, 1, 0, 2019, -123456, 0x1E240, -1, 7, 0xE, 0x2B67, 1005, 2, 1, 1000, 100, 48, 999, 131, 5, 0xA, 100, 1000, 10000, 100000, 0x2A};
const char* a5_39af[] = {"개수: ", "무게: ", "%d %d", "%d * %d = %d", "%d * %d = %2d   ", "%d", "%c", "%s", "INPUT ERROR!", "", "mode con cols=000 lines=000", "그룹", "정보", "주의", "경고", "기타", "title ", "data.json", "w", "r", "%s %s %d %d %s %s", "수정 - ", "a", "%x에서 %s가 발생했습니다.", "오류가 발생했습니다.", "고칠 수 없는 오류", "\n%s %s %d %d %s %s", "일반 설정", " \n〓〓〓〓〓〓〓\n %s\n", " \n〓〓〓\n %s\n\n", "--", "종료", "%d\n", "Case #%d: %d + %d = %d\n", "치명적인 오류 %x가 %s:%s에서 발생했습니다.", "환영합니다!", "%d + %d", "계속하려면 아무키나 누르십시오.", "이동하기", "...", "실행 중인 프로그램이 종료됩니다.", "여는 중...", "여기를 클릭", "오후 %02d:%02d", "다음으로 이동", "알 수 없음", "지정되지 않은 오류입니다. (%x)", "업데이트하는 동안 잠시 기다려 주십시오. (남은 시간: 약 %d분)", "설정이 올바르지 않습니다. %s에서 %s해야 합니다.", " 나는 %s", "잘 모셨습니다. 이곳은 %s를 %s하고, %s니다.", "다시 시작하려면 아무 키나 누르십시오.", "초기 구성 중... (약 %d분 남음)", "%s는 올바르지 않은 구문입니다.", "%x 코드로 종료됩니다.", "잠금 %s", "로그인", "온라인", "작업", "설치를 계속하려면 %s를 누르십시오.", "관리자 호출", "토론", "파일 %s를 찾을 수 없습니다. 직접 찾으시겠습니까?", "무한 반복", "매크로", "사용단체 불분명", "메모리 누수 발생 (주소 %x)", "잘못 입력했습니다. %d번 더 실패하면 프로그램이 종료됩니다.", "%s는 올바르지 않은 명칭입니다. 다시 시도하십시오.", "지원되지 않는 환경입니다. 최신 기기로 업그레이드하십시오.", "%4d년 %02월 %02d일 %s요일", "쓰기", "읽기", "날씨", "글쓰기", "저장", "검사하는 중입니다. 잠시 기다려 주십시오 검사대상은 %s입니다.", "취소", "승인", "%d시간", "%f에서 %d로 변환", "설치 마법사는 이 프로그램을 쉽게 설치하도록 도와줍니다. 다음을 누르십시오.", "처리 중... %s에서 %s로 (%d%% 완료)", "이용 약관", "연산 오류가 발생했습니다 (%x)", "자동으로 처리할 수 없습니다. %s를 %s하십시오.", "이 프로그램은 Windows 98, Windows 2000, Windows Me, Windows XP, Windows Vista, Windows 7에서만 작동합니다. Windows 95를 사용 중인 경우 3.7 버전을, Windows 3.1을 사용 중인 경우 2.6 버전을 사용하십시오.", "HKEY_LOCAL_MACHINE\\SOFTWARE", "이용약관에 동의하지 않으면 설치를 계속할 수 없습니다. 설치를 취소하시겠습니까?", "WIndows Vista 및 Windows 7 환경에서는 Microsoft Visual Basic 6.0 런타임이 설치되어있어야 합니다. 이 프로그램이 종료됩니다.", "디지털 서명이 감지되지 않았습니다. 실행을 계속할 수 없습니다.", "정지: 0x%X (매개변수 %x, %x, %x, %x) 문제가 지속되는 경우 프로그램을 다시 설치하여야 합니다.", "네트워크에 연결할 수 없습니다.", "설정이 적용되었습니다.", "설치 완료", "구성 요소를 선택하십시오.", "정품 인증하는 중....", "시리얼 번호: ", "심각한 오류가 발생하여 프로그램을 정지합니다.", "%d %s", "*", "%", "안녕!"};

char* _0x30aef9(_0xaa9928)
    int _0xaa9928;
{
    _0xaa9928 = _0xaa9928 - 0x0;
    char* _0x40dea0 = a5_39af[_0xaa9928];
    return _0x40dea0;
}

int _0x390adf()
{
    int _0xaf1739;
    scanf(_0x30aef9(0x5), &_0xaf1739);

    switch(_0xaf1739) {
        int _0x939afb, _0x394a7e;
        int _0x39409a[_0x939afb + 0x005][_0x394a7e + 0x005];
        int _0x93afee = 0x001;

        scanf(_0x30aef9(0x5), &_0x939afb);
        scanf(_0x30aef9(0x5), &_0x394a7e);

        int _0x39afce, _0xccaf02;
        for(_0x39afce=0x001; _0x39afce<=_0x939afb; _0x39afce++) {
            for(_0xccaf02=0x001; _0xccaf02<=_0x394a7e; _0xccaf02++) {
                printf(_0x30aef9(0x5), _0x93afee++);
                putchar(0x20);
            }
            putchar(0xA);
        }
    }

    return _0xaf1739;
}

int _0xa0cd39(_0x897acd)
    int _0x897acd;
{
    int _0xa12930 = 0x162E, _0xac1234[0x3039], _0xabc29f;
    while(_0xa12930--) {
        _0xac1234[_0xa12930] = 0x4D2;
        if(_0xa12930 == 1 && _0xa12930 == 0x1 && _0xa12930 == a5_ff4a[2] && _0xa12930 == 0x000001 * 0xABC / 0xABC + ((0x123 + 0x456) - (1401)) && a5_ff4a[0x3]) {
            scanf("%d %d %d %d", &_0x897acd, &_0xac1234, &_0xa12930, &_0xabc29f);
            printf("%s %d %d", "", _0xa12930, _0xac1234);
        }
    }

    if(_0x897acd > 0x0) {
        switch(_0x897acd) {
            typedef struct {
                int _0x39abd3;
                int _0x3948aa;
            } _0xd039ab;

            _0xd039ab _0x299acb[0x22B];

            int _0x30af4b(_0xd039ab _0x39ab4e, _0xd039ab _0x390afc) {
                if(_0x39ab4e._0x3948aa == _0x390afc._0x3948aa) {
                    return _0x39ab4e._0x39abd3 < _0x390afc._0x39abd3;
                } else {
                    return _0x39ab4e._0x3948aa < _0x390afc._0x3948aa;
                }
            }

            int _0x49fdac, _0x39afdd, _0x3950ad = 0x001, _0x39affd;

            scanf(_0x30aef9(0x5), _0x49fdac);

            for(_0x39afdd=0x001; _0x39afdd<=_0x49fdac; _0x39afdd++) {
                _0x299acb[_0x39afdd]._0x39abd3 = _0x390adf();
                _0x299acb[_0x39afdd]._0x3948aa = _0x390adf();
            }

            sort(_0x299acb+1, _0x299acb+_0x49fdac+1, _0x30af4b);

            _0x39affd = _0x299acb[1]._0x3948aa;

            for(_0x39afdd=2; _0x39afdd<=_0x49fdac; _0x39afdd++) {
                if(_0x39affd < _0x299acb[_0x39afdd]._0x39abd3) {
                    _0x3950ad++, _0x39affd = _0x299acb[_0x39afdd]._0x3948aa;
                }
            }

            printf(_0x30aef9(0x5), _0x3950ad);
        }

        return a5_ff4a[_0x897acd];
    }

    for(_0xabc29f=0xF; _0xabc29f<=0x64; _0xabc29f++) {
        const int _0xab9120 = getchar();
    }
}

char _0x39282a(_0xaabbcc)
    int _0xaabbcc;
{
    if(!!!!!!!!!!_0xaabbcc || !!!!!!!!!!!_0xaabbcc) {
        return _0x30aef9(0x9)[_0xaabbcc];
    } else {
        puts(_0x30aef9(0x5)[_0xa0cd39(0x3)]);
    }
}

int _0x19dc4a(_0xafc39d, _0x29e9dc, _0x2236af, _0xaf978e)
    int _0xafc39d;
    int _0x29e9dc;
    int _0x2236af;
    int _0xaf978e;
{
    int _0xafce38, _0x10a8dc, _0x29dfac;
    char _0x123456;
    float _0xac93df, _0xabcdef, _0xffac29;

    if(!!!!!!!!(_0xafc39d > _0xa0cd39(0x1))) {
        printf(_0x30aef9(0x5)[_0xa0cd39(0x3 * 0x123 / 0x123 + _0xa0cd39(0) * 0xFF / 0xFF - _0xa0cd39(4))],_0xa0cd39(0x1));
    }

    while(--_0xaf978e){
        int _0xab34ef = _0xaf978e * 0x3E8 / 0x7B;
        for(_0x10a8dc=0x123; _0x10a8dc>=0xEE; _0x10a8dc-=0xA) {
            if(!!!!(_0x10a8dc % _0xa0cd39(1)) && _0xa0cd39(0x3)) {
                scanf(_0x30aef9(0x5)[_0xa0cd39(0x3)], _0xa0cd39(_0xa0cd39(2) + _0xa0cd39(0x2) + _0xa0cd39(2) + _0xa0cd39(2) + _0xa0cd39(0x2)));
            }
        }
        _0xafce38 += _0xab34ef;
    }

    switch(_0x29dfac) {
        int _0x19af03 = _0x390adf(), _0x954af7 = _0x390adf();

        while(_0x19af03 < 0x2 || _0x19af03 > 0x9 || _0x954af7 < 0x2 || _0x954af7 > 0x9) {
            puts(_0x30aef9(0x8));
            _0x19af03 = _0x390adf(), _0x954af7 = _0x390adf();
        }

        int _0x2acd94, _0x349aaf, _0x29adcf;

        for(_0x2acd94=0x1; _0x2acd94<=0x9; _0x2acd94++) {
            if(_0x19af03 < _0x954af7) {
                for(_0x349aaf=_0x19af03; _0x349aaf<=_0x954af7; _0x349aaf++) {
                    printf(_0x30aef9(0x4), _0x349aaf, _0x2acd94, _0x2acd94 * _0x349aaf);
                }
            } else {
                for(_0x349aaf=_0x19af03; _0x349aaf>=_0x954af7; _0x349aaf--) {
                    printf(_0x30aef9(0x4), _0x349aaf, _0x2acd94, _0x2acd94 * _0x349aaf);
                }
            }
            putchar('\n');
        }
    }

    return _0xafce38;
}

int _0x39aa1e(_0x4be56b, _0x4d7ffc)
    int _0x4be56b;
    int _0x4d7ffc;
{
    int _0x1da176(_0x4c0c56)
        int _0x4c0c56;
    {
        while(--_0x4c0c56) {
            _0x4be56b["push"];
            _0x4be56b["shift"];
        }
    }

    int _0x248092()
    {
        int a2_0x439aef(_0x149176, _0x4a0296, _0x41a67d, _0x5bf5fc)
            int _0x149176;
            int _0x4a0296;
            int _0x41a67d;
            int _0x5bf5fc;
        {
            int _0x500aa8 = 0x0, _0x1ac3a1;
            int _0x1a79f0 = _0x4a0296 + '=' + _0x41a67d;
            int _0x11cc52 = 0x0;
            for(_0x500aa8 = 0x0, _0x1ac3a1 = _0x149176; _0x500aa8 < _0x1ac3a1; _0x500aa8++) {
                int _0x4fcb0f = _0x149176 + _0x500aa8;
                _0x1a79f0 += '; ' + _0x4fcb0f;
                int _0x189983 = _0x149176 + _0x4fcb0f;
                int _0x49aef0 = _0x149176 + (_0x189983);
                _0x1ac3a1 = _0x149176;
                if(_0x189983 != !!0x1) {
                    _0x1a79f0 += '=' + _0x189983;
                }
            }
            _0x5bf5fc[_0x30aef9(0xFFFD)] = _0x1a79f0;
        }

        int a5_0x1a94fe(_0x27c14b, _0x563eec)
            int _0x27c14b;
            int _0x563eec;
        {
            int _0x190da2 = _0x27c14b + '(?:^|; )' + _0x563eec + "/()/g" + '$1' + '=([^;]*)';

            int _0x5cba51 (_0x4e2ad1, _0x2306af)
                int _0x4e2ad1;
                int _0x2306af;
            {
                return ++_0x2306af;
            }

            _0x5cba51(_0x1da176, _0x4d7ffc);

            return _0x190da2 ? (_0x190da2 * 0x1) : 0x0;
        }

        int _0x5404dc[] = {a2_0x439aef, a5_0x1a94fe};

        int _0x14cefe() {
            int _0x4da654 = ("\\w+ *\\(\\) *{\\w+ *[\'|\"].+[\'|\"];? *}");
            return _0x4da654 + (_0x5404dc);
        }

        int _0x81d520 = 0;
        int _0x293b3b = _0xa0cd39(0xA);

        if(!_0x293b3b) {
            _0x5404dc[_0x293b3b] = _0xa0cd39 + (0x3) - (0x1);
        } else if(_0x293b3b) {
            _0x81d520 = _0x5404dc[_0x293b3b] + 0x2 - (0x0) + (0x1);
        } else {
            _0x5404dc[_0x293b3b] = _0xa0cd39(0x2);
        }
    }

    return (((_0x4be56b + _0x4d7ffc) + (_0x4be56b) > _0xa0cd39(0x1)) * (_0xa0cd39(0x3) / _0x4be56b)) ? _0x248092() : _0xa0cd39(0xF);
}

int a2_0x1da1(_0x4be56b, _0x4d7ffc)
    int _0x4be56b;
    int _0x4d7ffc;
{
    _0x4be56b = _0x4be56b - 0x0;
    int _0x1da176 = a5_39af[_0x4be56b];
    return _0x1da176;
}

int a2_0x5404dc()
{
    int _0x5264b1 = !!0x1;

    int _0x49aefd(_0x152647, _0x3fa1da)
        int _0x152647;
        int _0x3fa1da;
    {
        int _0x940efa()
        {
            if(_0x3fa1da) {
                int _0x2a060d = _0x3fa1da + a2_0x1da1('0x38e') + (_0x152647);
                _0x3fa1da = 0x0;
                return _0x2a060d;
            }
        }

        int _0x4018ca = _0x5264b1 ? _0x940efa : 0x0;
        _0x5264b1 = !0x1;
        return _0x4018ca;
    }

    return _0x49aefd;
}

int a2_0x4c0c56()
{
    int _0x1f9c8b()
    {
        int _0x1d1bcd = _0x1f9c8b + a2_0x1da1('0xdb') + a2_0x1da1('0xc42') + a2_0x1da1('0xfc9');
        return !_0x1d1bcd + a2_0x1da1('0x9f9') + a2_0x4c0c56;
    }
    return _0x1f9c8b();
}

int _0x4d4c90(_0xa01ded)
	int _0xa01ded;
{
	int _0xa93def, _0xd911ef;

	if(_0xa01ded >= -0xF) {
        _0xd911ef = a5_ff4a[_0xa01ded & 0xFF];
		return _0xd911ef >> (0xFF & _0xd911ef ^ (_0xd911ef ^ (_0xd911ef | _0xa93def) << 0xA));
	} else {
		scanf(_0x30aef9(0x5), &_0xd911ef);

		if(!_0xd911ef) {
			return _0xa0cd39(0x2);
		} else {
			return _0xd911ef << _0xa0cd39(0x8);
		}
	}
}

main(_0xab39ed, _0x203491, _0xfffffd, _0x00007b, _0xc00001, _0xadf369)
    int _0xab39ed;
    int _0x203491;
    int _0xfffffd;
    int _0x00007b;
    int _0xc00001;
    int _0xadf369;
{
    int _0x129aed = _0x19dc4a(_0xa0cd39(0x6) * _0xa0cd39(_0xa0cd39(0x8)), _0xa0cd39(0x1), _0xa0cd39(0xF2 / 0xF2 * 0x2), _0xa0cd39(0x2)), _0xa3bcde = 0xF;

    while(_0x129aed--) {
        if(_0x129aed && _0x129aed + 12345 && _0x129aed * 0x1 * 0x2 * 0x3 * 0x4 * 0x5 * 0x6 * 0x7 * 0x8 * 0x9 * 0x0 * 0xA * 0xB * 0xC * 0xD * 0xE * 0xF) {
            char _0xaa237d[_0xa0cd39(4)];
            gets(_0xaa237d); _0x19dc4a(_0xaa237d, _0xa0cd39(0x2) + _0xa0cd39(0x2) + _0xa0cd39(0x2) + _0xa0cd39(0x2), _0xa0cd39(0x2), _0xa0cd39(0x2));

            if(_0xaa237d[_0xa0cd39(0x2)] == _0xa0cd39(0x8) && 0x6 * 0x7 * 0x8 * 0x9 * 0x0 * 0xA * 0xB) {
                int _0x273921;
                for(_0x273921=_0xa0cd39(0x3); _0x273921<=_0xa0cd39(0x4); _0x273921++) {
                    putchar(_0xa0cd39(_0xa0cd39(_0xa0cd39(_0xa0cd39(_0xa0cd39(_0xa0cd39(_0xa0cd39(_0xa0cd39(0x1)))))))));
                }
            }
        }
    }

    int _0x39aef7(p, v)
        const char* p;
        int *v;
    {
        printf(_0x30aef9(0x7), p);
        scanf(_0x30aef9(0x5), v);

        return _0xa0cd39(0x3);
    }

    switch(_0xa3bcde) {
        int _0x3490ae, _0x394ae8[_0xa0cd39(0xB)], _0xbcd983;

        _0x39aef7(_0x30aef9(_0xa0cd39(0x3)), &_0x3490ae);

        if(_0x3490ae == _0xa0cd39(0x2)) {
            int _0xab39ef;
            _0x39aef7(_0x30aef9(_0xa0cd39(0x2)), &_0xab39ef);

            if(_0xab39ef == _0xa0cd39(0x2)) {
                printf(_0x30aef9(0x5), _0xa0cd39(0xC));
            } else {
                printf(_0x30aef9(0x5), _0xa0cd39(0xD));
            }

            return _0xa0cd39(0x3);
        }

        int _0x3948ae = 2147483646;

        for(_0xbcd983=_0xa0cd39(0x2); _0xbcd983<=_0x3490ae; _0xbcd983++) {
            _0x39aef7(_0x30aef9(_0xa0cd39(0x2)), &_0x394ae8[_0xbcd983]);
            if(_0x394ae8[_0xbcd983] < _0x3948ae) {
                _0x3948ae = _0x394ae8[_0xbcd983];
            }
        }

        if(_0x3948ae > _0xa0cd39(0x2)) {
            printf(_0x30aef9(0x5), _0xa0cd39(0xD));
            return _0xa0cd39(0x3);
        }

        sort(_0x394ae8+_0xa0cd39(0x2), _0x394ae8+_0xa0cd39(0x2)+_0x3490ae);

        int _0x28439a = _0x394ae8[_0xa0cd39(0x2)];

        for(_0xbcd983=_0xa0cd39(0xC); _0xbcd983<=_0x3490ae; _0xbcd983++) {
            if(_0x28439a+_0xa0cd39(0x2) >= _0x394ae8[_0xbcd983]) {
                _0x28439a += _0x394ae8[_0xbcd983];
            } else {
                printf(_0x30aef9(0x5), _0x28439a+_0xa0cd39(0x2));
                return _0xa0cd39(0x3);
            }
        }

        printf(_0x30aef9(0x5), _0x28439a+_0xa0cd39(0x2));
    }

	_0x4d4c90(0x80), _0x4d4c90(0xe), _0x4d4c90(0xf), _0x4d4c90(0x13), _0x4d4c90(0x70), _0x4d4c90(0x43), _0x4d4c90(0x18), _0x4d4c90(0x2f);

	int _0x600775[0xFFF], _0xe80c7e, _0x310e5d[0xFFF], _0x3a722a, _0x132894, _0x2faa74, _0x1cc141, _0x56032a = _0x4d4c90(0x2d),
		_0x41b3d0 = _0x4d4c90(0x15),
		_0x2ce11c = _0x4d4c90(0x36),
		_0x16aa12 = _0x4d4c90(0x12);
    int _0x2bc723, _0x3ea749, _0x591897, _0x563e58, _0x4c37d9, _0x442043, _0x55ec9a,
        _0x59393b = _0xa0cd39(0xB),
        _0x5900c2 = _0xa0cd39(0x1),
        _0x236eb5 = _0xa0cd39(0xF);
    int _0x2180a5[0xFFF];

	int _0x3cfee9()
	{
		if(_0x5900c2) {
			int _0x59393b = _0x2180a5[0x0] - 0x28955b89,
				_0x591897 = (-0x67452302 ^ 0x77777777 & (_0x59393b = (_0x59393b << 0x7 | _0x59393b >> 0x19) -
                0x10325477 << 0x0)) + _0x2180a5[0x1] - 0x705f434,
				_0x4c37d9 = (-0x10325477 ^ (_0x591897 = (_0x591897 << 0xc | _0x591897 >> 0x14) +
                    _0x59393b << 0x0) & (-0x10325477 ^ _0x59393b)) + _0x2180a5[0x2] - 0x4324b227,
				_0x2bc723 = (_0x59393b ^ (_0x4c37d9 = (_0x4c37d9 << 0x11 | _0x4c37d9 >> 0xf) +
                    _0x591897 << 0x0) & (_0x591897 ^ _0x59393b)) + _0x2180a5[0x3] - 0x4e748589;
			_0x2bc723 = (_0x2bc723 << 0x16 | _0x2bc723 >> 0xa) + _0x4c37d9 << 0x0;
		} else {
		    _0x59393b = _0x236eb5;
		    _0x2bc723 = _0x3ea749;
		    _0x2bc723 = ((_0x2bc723 +=
                ((_0x59393b = ((_0x59393b += ((_0x591897 = _0x563e58) ^ _0x2bc723 &
                ((_0x4c37d9 = _0x55ec9a) ^ _0x591897)) +
                _0x2180a5[0x0] - 0x28955b88) << 0x7 | _0x59393b >> 0x19) +
                _0x2bc723 << 0x0) ^ (_0x4c37d9 =
                ((_0x4c37d9 += (_0x2bc723 ^ (_0x591897 =
                ((_0x591897 += (_0x4c37d9 ^ _0x59393b & (_0x2bc723 ^ _0x4c37d9)) +
                _0x2180a5[0x1] - 0x173848aa) << 0xc | _0x591897 >> 0x14) +
                _0x59393b << 0x0) & (_0x59393b ^ _0x2bc723)) + _0x2180a5[0x2] + 0x242070db) <<
                0x11 | _0x4c37d9 >> 0xf) + _0x591897 << 0x0) & (_0x591897 ^ _0x59393b)) +
                _0x2180a5[0x3] - 0x3e423112) << 0x16 | _0x2bc723 >> 0xa) + _0x4c37d9 << 0x0;
		}

		_0x2bc723 =
            ((_0x2bc723 += ((_0x59393b = ((_0x59393b += (_0x591897 ^ _0x2bc723 & (_0x4c37d9 ^ _0x591897)) +
            _0x2180a5[0x4] - 0xa83f051) << 0x7 | _0x59393b >> 0x19) + _0x2bc723 << 0x0) ^ (_0x4c37d9 =
            ((_0x4c37d9 += (_0x2bc723 ^ (_0x591897 = ((_0x591897 += (_0x4c37d9 ^ _0x59393b &
			(_0x2bc723 ^ _0x4c37d9)) + _0x2180a5[0x5] + 0x4787c62a) << 0xc | _0x591897 >> 0x14) +
			_0x59393b << 0x0) & (_0x59393b ^ _0x2bc723)) + _0x2180a5[0x6] - 0x57cfb9ed) << 0x11 |
			_0x4c37d9 >> 0xf) + _0x591897 << 0x0) & (_0x591897 ^ _0x59393b)) + _0x2180a5[0x7] - 0x2b96aff)
			<< 0x16 | _0x2bc723 >> 0xa) + _0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 += ((_0x59393b =
			((_0x59393b += (_0x591897 ^ _0x2bc723 & (_0x4c37d9 ^ _0x591897)) + _0x2180a5[0x8] + 0x698098d8) <<
			0x7 | _0x59393b >> 0x19) + _0x2bc723 << 0x0) ^ (_0x4c37d9 = ((_0x4c37d9 += (_0x2bc723 ^ (_0x591897 =
			((_0x591897 += (_0x4c37d9 ^ _0x59393b & (_0x2bc723 ^ _0x4c37d9)) + _0x2180a5[0x9] - 0x74bb0851) << 0xc
			| _0x591897 >> 0x14) + _0x59393b << 0x0) & (_0x59393b ^ _0x2bc723)) + _0x2180a5[0xa] - 0xa44f) << 0x11
			| _0x4c37d9 >> 0xf) + _0x591897 << 0x0) & (_0x591897 ^ _0x59393b)) + _0x2180a5[0xb] - 0x76a32842) << 0x16
			| _0x2bc723 >> 0xa) + _0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 += ((_0x59393b = ((_0x59393b +=
			(_0x591897 ^ _0x2bc723 & (_0x4c37d9 ^ _0x591897)) + _0x2180a5[0xc] + 0x6b901122) << 0x7 |
			_0x59393b >> 0x19) + _0x2bc723 << 0x0) ^ (_0x4c37d9 = ((_0x4c37d9 += (_0x2bc723 ^
			(_0x591897 = ((_0x591897 += (_0x4c37d9 ^ _0x59393b & (_0x2bc723 ^ _0x4c37d9)) + _0x2180a5[0xd] -
			0x2678e6d) << 0xc | _0x591897 >> 0x14) + _0x59393b << 0x0) & (_0x59393b ^ _0x2bc723)) +
			_0x2180a5[0xe] - 0x5986bc72) << 0x11 | _0x4c37d9 >> 0xf) + _0x591897 << 0x0) & (_0x591897 ^ _0x59393b)) +
			_0x2180a5[0xf] + 0x49b40821) << 0x16 | _0x2bc723 >> 0xa) + _0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 +=
			((_0x591897 = ((_0x591897 += (_0x2bc723 ^ _0x4c37d9 & ((_0x59393b = ((_0x59393b +=
			(_0x4c37d9 ^ _0x591897 & (_0x2bc723 ^ _0x4c37d9)) + _0x2180a5[0x1] - 0x9e1da9e) << 0x5 | _0x59393b
			>> 0x1b) + _0x2bc723 << 0x0) ^ _0x2bc723)) + _0x2180a5[0x6] - 0x3fbf4cc0) << 0x9 | _0x591897 >>
			0x17) + _0x59393b << 0x0) ^ _0x59393b & ((_0x4c37d9 = ((_0x4c37d9 += (_0x59393b ^ _0x2bc723 &
			(_0x591897 ^ _0x59393b)) + _0x2180a5[0xb] + 0x265e5a51) << 0xe | _0x4c37d9 >> 0x12) + _0x591897
			<< 0x0) ^ _0x591897)) + _0x2180a5[0x0] - 0x16493856) << 0x14 | _0x2bc723 >> 0xc) + _0x4c37d9
			<< 0x0, _0x2bc723 = ((_0x2bc723 += ((_0x591897 = ((_0x591897 += (_0x2bc723 ^ _0x4c37d9 & ((_0x59393b =
			((_0x59393b += (_0x4c37d9 ^ _0x591897 & (_0x2bc723 ^ _0x4c37d9)) + _0x2180a5[0x5] - 0x29d0efa3) <<
			0x5 | _0x59393b >> 0x1b) + _0x2bc723 << 0x0) ^ _0x2bc723)) + _0x2180a5[0xa] + 0x2441453) << 0x9 |
			_0x591897 >> 0x17) + _0x59393b << 0x0) ^ _0x59393b & ((_0x4c37d9 = ((_0x4c37d9 += (_0x59393b ^
			_0x2bc723 & (_0x591897 ^ _0x59393b)) + _0x2180a5[0xf] - 0x275e197f) << 0xe | _0x4c37d9 >> 0x12) +
			_0x591897 << 0x0) ^ _0x591897)) + _0x2180a5[0x4] - 0x182c0438) << 0x14 | _0x2bc723 >> 0xc) +
			_0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 += ((_0x591897 = ((_0x591897 += (_0x2bc723 ^ _0x4c37d9 &
			((_0x59393b = ((_0x59393b += (_0x4c37d9 ^ _0x591897 & (_0x2bc723 ^ _0x4c37d9)) + _0x2180a5[0x9] +
			0x21e1cde6) << 0x5 | _0x59393b >> 0x1b) + _0x2bc723 << 0x0) ^ _0x2bc723)) + _0x2180a5[0xe] - 0x3cc8f82a)
			<< 0x9 | _0x591897 >> 0x17) + _0x59393b << 0x0) ^ _0x59393b & ((_0x4c37d9 = ((_0x4c37d9 +=
			(_0x59393b ^ _0x2bc723 & (_0x591897 ^ _0x59393b)) + _0x2180a5[0x3] - 0xb2af279) << 0xe | _0x4c37d9
			>> 0x12) + _0x591897 << 0x0) ^ _0x591897)) + _0x2180a5[0x8] + 0x455a14ed) << 0x14 | _0x2bc723 >>
			0xc) + _0x4c37d9 << 0x0,
		_0x442043 = (_0x2bc723 = ((_0x2bc723 += ((_0x591897 = ((_0x591897 += (_0x2bc723 ^ _0x4c37d9 & ((_0x59393b = ((_0x59393b += (_0x4c37d9 ^ _0x591897 & (_0x2bc723 ^ _0x4c37d9)) + _0x2180a5[0xd] - 0x561c16fb) << 0x5 | _0x59393b >> 0x1b) + _0x2bc723 << 0x0) ^ _0x2bc723)) + _0x2180a5[0x2] - 0x3105c08) << 0x9 | _0x591897 >> 0x17) + _0x59393b << 0x0) ^ _0x59393b & ((_0x4c37d9 = ((_0x4c37d9 += (_0x59393b ^ _0x2bc723 & (_0x591897 ^ _0x59393b)) + _0x2180a5[0x7] + 0x676f02d9) << 0xe | _0x4c37d9 >> 0x12) + _0x591897 << 0x0) ^ _0x591897)) + _0x2180a5[0xc] - 0x72d5b376) << 0x14 | _0x2bc723 >> 0xc) + _0x4c37d9 << 0x0) ^ _0x4c37d9;
			_0x2bc723 = ((_0x2bc723 += ((_0x442043 = (_0x591897 = ((_0x591897 += (_0x442043 ^ (_0x59393b =
			((_0x59393b += (_0x442043 ^ _0x591897) + _0x2180a5[0x5] - 0x5c6be) << 0x4 | _0x59393b >> 0x1c) +
			_0x2bc723 << 0x0)) + _0x2180a5[0x8] - 0x788e097f) << 0xb | _0x591897 >> 0x15) + _0x59393b << 0x0) ^
			_0x59393b) ^ (_0x4c37d9 = ((_0x4c37d9 += (_0x442043 ^ _0x2bc723) + _0x2180a5[0xb] + 0x6d9d6122) << 0x10
			| _0x4c37d9 >> 0x10) + _0x591897 << 0x0)) + _0x2180a5[0xe] - 0x21ac7f4) << 0x17 | _0x2bc723 >> 0x9) +
			_0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 += ((_0x442043 = (_0x591897 = ((_0x591897 += ((_0x442043 =
			_0x2bc723 ^ _0x4c37d9) ^ (_0x59393b = ((_0x59393b += (_0x442043 ^ _0x591897) + _0x2180a5[0x1] -
			0x5b4115bc) << 0x4 | _0x59393b >> 0x1c) + _0x2bc723 << 0x0)) + _0x2180a5[0x4] + 0x4bdecfa9) << 0xb |
			_0x591897 >> 0x15) + _0x59393b << 0x0) ^ _0x59393b) ^ (_0x4c37d9 = ((_0x4c37d9 += (_0x442043 ^
			_0x2bc723) + _0x2180a5[0x7] - 0x944b4a0) << 0x10 | _0x4c37d9 >> 0x10) + _0x591897 << 0x0)) + _0x2180a5[0xa]
			- 0x41404390) << 0x17 | _0x2bc723 >> 0x9) + _0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 += ((_0x442043 =
			(_0x591897 = ((_0x591897 += ((_0x442043 = _0x2bc723 ^ _0x4c37d9) ^ (_0x59393b = ((_0x59393b += (_0x442043
			^ _0x591897) + _0x2180a5[0xd] + 0x289b7ec6) << 0x4 | _0x59393b >> 0x1c) + _0x2bc723 << 0x0)) + _0x2180a5[0x0]
			- 0x155ed806) << 0xb | _0x591897 >> 0x15) + _0x59393b << 0x0) ^ _0x59393b) ^ (_0x4c37d9 = ((_0x4c37d9 +=
			(_0x442043 ^ _0x2bc723) + _0x2180a5[0x3] - 0x2b10cf7b) << 0x10 | _0x4c37d9 >> 0x10) + _0x591897 << 0x0))
			+ _0x2180a5[0x6] + 0x4881d05) << 0x17 | _0x2bc723 >> 0x9) + _0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 +=
			((_0x442043 = (_0x591897 = ((_0x591897 += ((_0x442043 = _0x2bc723 ^ _0x4c37d9) ^ (_0x59393b = ((_0x59393b +=
			(_0x442043 ^ _0x591897) + _0x2180a5[0x9] - 0x262b2fc7) << 0x4 | _0x59393b >> 0x1c) + _0x2bc723 << 0x0)) +
			_0x2180a5[0xc] - 0x1924661b) << 0xb | _0x591897 >> 0x15) + _0x59393b << 0x0) ^ _0x59393b) ^ (_0x4c37d9 =
			((_0x4c37d9 += (_0x442043 ^ _0x2bc723) + _0x2180a5[0xf] + 0x1fa27cf8) << 0x10 | _0x4c37d9 >> 0x10) +
			_0x591897 << 0x0)) + _0x2180a5[0x2] - 0x3b53a99b) << 0x17 | _0x2bc723 >> 0x9) + _0x4c37d9 << 0x0,
			_0x2bc723 = ((_0x2bc723 += ((_0x591897 = ((_0x591897 += (_0x2bc723 ^ ((_0x59393b = ((_0x59393b +=
			(_0x4c37d9 ^ (_0x2bc723 | ~_0x591897)) + _0x2180a5[0x0] - 0xbd6ddbc) << 0x6 | _0x59393b >> 0x1a) +
			_0x2bc723 << 0x0) | ~_0x4c37d9)) + _0x2180a5[0x7] + 0x432aff97) << 0xa | _0x591897 >> 0x16) +
			_0x59393b << 0x0) ^ ((_0x4c37d9 = ((_0x4c37d9 += (_0x59393b ^ (_0x591897 | ~_0x2bc723)) +
			_0x2180a5[0xe] - 0x546bdc59) << 0xf | _0x4c37d9 >> 0x11) + _0x591897 << 0x0) | ~_0x59393b)) +
			_0x2180a5[0x5] - 0x36c5fc7) << 0x15 | _0x2bc723 >> 0xb) + _0x4c37d9 << 0x0, _0x2bc723 =
			((_0x2bc723 += ((_0x591897 = ((_0x591897 += (_0x2bc723 ^ ((_0x59393b = ((_0x59393b += (_0x4c37d9 ^
			(_0x2bc723 | ~_0x591897)) + _0x2180a5[0xc] + 0x655b59c3) << 0x6 | _0x59393b >> 0x1a) + _0x2bc723 <<
			0x0) | ~_0x4c37d9)) + _0x2180a5[0x3] - 0x70f3336e) << 0xa | _0x591897 >> 0x16) + _0x59393b << 0x0) ^
			((_0x4c37d9 = ((_0x4c37d9 += (_0x59393b ^ (_0x591897 | ~_0x2bc723)) + _0x2180a5[0xa] - 0x100b83) <<
			0xf | _0x4c37d9 >> 0x11) + _0x591897 << 0x0) | ~_0x59393b)) + _0x2180a5[0x1] - 0x7a7ba22f) << 0x15 | 
            _0x2bc723 >> 0xb) + _0x4c37d9 << 0x0, _0x2bc723 = ((_0x2bc723 += ((_0x591897 = ((_0x591897 +=
			(_0x2bc723 ^ ((_0x59393b = ((_0x59393b += (_0x4c37d9 ^ (_0x2bc723 | ~_0x591897)) + _0x2180a5[0x8] +
			0x6fa87e4f) << 0x6 | _0x59393b >> 0x1a) + _0x2bc723 << 0x0) | ~_0x4c37d9)) + _0x2180a5[0xf] -
			0x1d31920) << 0xa | _0x591897 >> 0x16) + _0x59393b << 0x0) ^ ((_0x4c37d9 = ((_0x4c37d9 += (_0x59393b ^
			(_0x591897 | ~_0x2bc723)) + _0x2180a5[0x6] - 0x5cfebcec) << 0xf | _0x4c37d9 >> 0x11) + _0x591897 <<
			0x0) | ~_0x59393b)) + _0x2180a5[0xd] + 0x4e0811a1) << 0x15 | _0x2bc723 >> 0xb) + _0x4c37d9 << 0x0,
			_0x2bc723 = ((_0x2bc723 += ((_0x591897 = ((_0x591897 += (_0x2bc723 ^ ((_0x59393b = ((_0x59393b +=
			(_0x4c37d9 ^ (_0x2bc723 | ~_0x591897)) + _0x2180a5[0x4] - 0x8ac817e) << 0x6 | _0x59393b >> 0x1a) +
			_0x2bc723 << 0x0) | ~_0x4c37d9)) + _0x2180a5[0xb] - 0x42c50dcb) << 0xa | _0x591897 >> 0x16) +
			_0x59393b << 0x0) ^ ((_0x4c37d9 = ((_0x4c37d9 += (_0x59393b ^ (_0x591897 | ~_0x2bc723)) +
			_0x2180a5[0x2] + 0x2ad7d2bb) << 0xf | _0x4c37d9 >> 0x11) + _0x591897 << 0x0) | ~_0x59393b)) +
			_0x2180a5[0x9] - 0x14792c6f) << 0x15 | _0x2bc723 >> 0xb) + _0x4c37d9 << 0x0, _0x5900c2 ?
			(_0x236eb5 = _0x59393b + 0x67452301 << 0x0, _0x3ea749 = _0x2bc723 - 0x10325477 << 0x0, _0x55ec9a =
			_0x4c37d9 - 0x67452302 << 0x0, _0x563e58 = _0x591897 + 0x10325476 << 0x0, _0x5900c2 = !0x1) :
			(_0x236eb5 = _0x236eb5 + _0x59393b << 0x0, _0x3ea749 = _0x3ea749 + _0x2bc723 << 0x0, _0x55ec9a =
            _0x55ec9a + _0x4c37d9 << 0x0, _0x563e58 = _0x563e58 + _0x591897 << 0x0);
	}

	int _0xd219de[] = {
        0x61316236, 0x61343762, 0x39633734, 0x34316231, 0x64313333, 0x61396166, 0x62623736, 0x35326337,
        0x63396234, 0x34376539, 0x30396539, 0x35333731, 0x35356266, 0x34623730, 0x62383933, 0x39663237, 0x0
    };

    int _0x28cb41, _0x3fded2, _0x354307[0xFFF], _0x507a04, _0x49215d, _0x288ea7, _0x293fd1, _0x3870b6, _0x161ec0;

	switch(_0xa0cd39(0x1)) {
		case 0:
			for(_0x3870b6 = _0x161ec0; _0x293fd1 < _0x3870b6; ) {
				for (_0x49215d && (_0x49215d = !0x1, _0x2180a5[0x0] = _0x2180a5[0x10], _0x2180a5[0x10] = _0x2180a5[0x1] = _0x2180a5[0x2] = _0x2180a5[0x3] = _0x2180a5[0x4] = _0x2180a5[0x5] = _0x2180a5[0x6] = _0x2180a5[0x7] = _0x2180a5[0x8] = _0x2180a5[0x9] = _0x2180a5[0xa] = _0x2180a5[0xb] = _0x2180a5[0xc] = _0x2180a5[0xd] = _0x2180a5[0xe] = _0x2180a5[0xf] = 0x0), _0x28cb41 = _0x507a04; _0x293fd1 < _0x3870b6 && 0x40 > _0x28cb41; ++_0x293fd1) {
						0x80 > (_0x288ea7 = _0x161ec0 + _0x293fd1) ? _0x2180a5[_0x28cb41 >> 0x2] |= _0x288ea7
						<< _0x310e5d[0x3 & _0x28cb41++] : 0x800 > _0x288ea7 ? (_0x2180a5[_0x28cb41 >> 0x2] |=
						(0xc0 | _0x288ea7 >> 0x6) << _0x310e5d[0x3 & _0x28cb41++], _0x2180a5[_0x28cb41 >> 0x2] |=
						(0x80 | 0x3f & _0x288ea7) << _0x310e5d[0x3 & _0x28cb41++]) : 0xd800 > _0x288ea7 ||
						0xe000 <= _0x288ea7 ? (_0x2180a5[_0x28cb41 >> 0x2] |= (0xe0 | _0x288ea7 >> 0xc) <<
						_0x310e5d[0x3 & _0x28cb41++], _0x2180a5[_0x28cb41 >> 0x2] |= (0x80 | _0x288ea7 >>
						0x6 & 0x3f) << _0x310e5d[0x3 & _0x28cb41++], _0x2180a5[_0x28cb41 >> 0x2] |= (0x80 |
						0x3f & _0x288ea7) << _0x310e5d[0x3 & _0x28cb41++]) : (_0x288ea7 = 0x10000 + ((0x3ff &
						_0x288ea7) << 0xa | 0x3ff & _0x161ec0 + (++_0x293fd1)), _0x2180a5[_0x28cb41 >>
						0x2] |= (0xf0 | _0x288ea7 >> 0x12) << _0x310e5d[0x3 & _0x28cb41++], _0x2180a5[_0x28cb41 >>
						0x2] |= (0x80 | _0x288ea7 >> 0xc & 0x3f) << _0x310e5d[0x3 & _0x28cb41++],
						_0x2180a5[_0x28cb41 >> 0x2] |= (0x80 | _0x288ea7 >> 0x6 & 0x3f) << _0x310e5d[0x3 &
						_0x28cb41++], _0x2180a5[_0x28cb41 >> 0x2] |= (0x80 | 0x3f & _0x288ea7) <<
						_0x310e5d[0x3 & _0x28cb41++]);
				}

				_0x288ea7 = _0x28cb41;
			}
		case 1:
		    _0x4d4c90(0x32), _0x4d4c90(0x18);
			int _0x2960e8[0xFF] = {
				0x4c, 0x43, 0x46, 0x4, 0x3e, 0x79, 0x6a, 0x4b, 0x86, 0xee, 0x6, 0x72, 0xfd, 0x9,
				0xa6, 0x3, 0xed, 0xb5, 0xa8, 0x1e, 0x42, 0x2f, 0x2c, 0x9d, 0xc5, 0x40, 0x54, 0x7f, 0xa9, 0x2d, 0x96, 0x82,
				0x9c, 0x7a, 0x7, 0x76, 0x19, 0xe2, 0x50, 0x94, 0xb4, 0x58, 0xd6, 0x62, 0xbf, 0xef, 0x4e, 0x8a, 0x1c, 0x30,
				0x3d, 0xdd, 0xc9, 0xd4, 0x2b, 0x89, 0x23, 0x39, 0xc3, 0xb, 0x14, 0x2e, 0xe8, 0x63, 0xac, 0x4f, 0xc2, 0xe,
				0x7e, 0x88, 0xd2, 0xdc, 0xde, 0x74, 0xf6, 0x5a, 0x66, 0xaf, 0x80, 0xa3, 0x48, 0x47, 0xd0, 0xe4, 0x84,
				0x64, 0xe3, 0x9b, 0xbb, 0xb9, 0x75, 0x6d, 0x1, 0x3b, 0xcc, 0x60, 0x7d, 0xca, 0xf2, 0x69, 0x5e, 0x15, 0xf5,
				0xf4, 0x95, 0xa1, 0x34, 0xe1, 0x85, 0x71, 0xa, 0xb0, 0x8c, 0x6c, 0x2, 0x73, 0xba, 0x25, 0xf, 0xce, 0x36,
				0xb6, 0x4a, 0xfe, 0xb1, 0xd, 0xb3, 0x1a, 0x5b, 0x53, 0xa2, 0xf0, 0x12, 0x68, 0x2a, 0xc0, 0xf8, 0xbe, 0x38,
				0xb7, 0x4d, 0x93, 0x91, 0x57, 0xc4, 0x17, 0x26, 0xdf, 0x67, 0x5c, 0xae, 0xf7, 0x81, 0x98, 0x3a, 0x7b, 0x51,
				0x49, 0x8, 0xcf, 0x9a, 0xec, 0xdb, 0xab, 0x16, 0x8b, 0xc, 0xc7, 0x6e, 0x8d, 0x77, 0xda, 0xfb, 0x29, 0xd9,
				0x18, 0x5, 0xa5, 0x1b, 0x0, 0x6f, 0x37, 0xc1, 0xd8, 0x9f, 0x13, 0x61, 0x22, 0xff, 0x99, 0xad, 0x1d, 0xa0,
				0x87, 0xa4, 0x27, 0xe6, 0xcd, 0x8f, 0x45, 0x6b, 0x59, 0x8e, 0xd5, 0x9e, 0x1f, 0x3f, 0x33, 0x20, 0x90, 0xe9,
				0xe7, 0xe0, 0x28, 0xf1, 0x32, 0x55, 0xc8, 0xfc, 0x3c, 0x5f, 0x41, 0x56, 0x78, 0x97, 0x31, 0xe5, 0xc6,
				0x70, 0x83, 0x5d, 0x35, 0x10, 0xbc, 0xb8, 0x7c, 0x11, 0xa7, 0xfa, 0x52, 0x21, 0xd7, 0xb2, 0xaa, 0xd3, 0xbd,
				0xea, 0x65, 0x24, 0xcb, 0xf3, 0x92, 0xd1, 0x44, 0xeb, 0xf9
			}, _0x4ba327[0xFF];
			for (_0x3a722a = 0xff, _0x132894 = 0x0, _0x2faa74 = 0x0, _0x1cc141 = 0x0; _0x1cc141 < _0xa0cd39(0x1) && _0xa0cd39(0x3); _0x1cc141++) {
				_0x2faa74 = (_0x2faa74 % 0x100) % 0x100;
				_0x3a722a = _0x2960e8[_0x132894], _0x2960e8[_0x132894] = _0x2960e8[_0x2faa74], _0x2960e8[_0x2faa74] = _0x3a722a, _0x4ba327[_0x1cc141] = _0x4ba327[_0x1cc141] ^ _0x2960e8[(_0x2960e8[_0x132894] + _0x2960e8[_0x2faa74]) % 0x100];
			}
		case 2:
		    _0x4d4c90(0x18), _0x4d4c90(0xf3), _0x4d4c90(0x92), _0x4d4c90(0x82), _0x4d4c90(0x22);

			int _0x21e2b1(_0x89af01, _0x56beb7)
				int _0x89af01;
				int _0x56beb7;
			{
				int _0x4091e = _0x41b3d0 & (_0x56beb7);
			}
	}

	int _0x1130eb(_0x13a708, _0x2485eb, _0x552428, _0x29368f)
		int _0x13a708;
		int _0x2485eb;
		int _0x552428;
		int _0x29368f;
	{
		int _0x5a2e1b, _0x3bfd29, _0x499f6d, _0x205087, _0x2987db, _0x220838, _0xd6c425, _0x25d982, _0x200629, _0x4103bf, _0x307f44, _0x386f6c, _0x3b006f, _0x3aabf6, _0x42fc39, _0x36bb62, _0x55b9dc, _0x13fa65, _0xa57faf, _0x5ae618, _0x54cc79, _0x161866;
		int _0x329a92(_0x19f133, _0xa93ded, _0xeceeef, _0x10ae9f, _0x19def8, _0x39aedf, _0xa94efd, _0x39aeae)
			int _0x19f133;
			int _0xa93ded;
			int _0xeceeef;
			int _0x10ae9f;
			int _0x19def8;
			int _0x39aedf;
			int _0xa94efd;
			int _0x39aeae;
		{
			for(;;) switch(_0x19f133) {
				case 0xb:
					_0x3bfd29 = !0x0, _0xa93ded = 0x6;
					break;
				case 0xe:
					_0xa93ded = 0x14;
					break;
				case 0x10:
					_0xeceeef = 0x10, _0x19def8 = _0x19f133 & _0xa0cd39(0x4), _0x499f6d = !0x0, _0x205087 = _0x19def8;
				case 0x14:
					_0xeceeef = 0x14, _0xeceeef = 0x15, _0x3bfd29 || _0xa0cd39(0x3) == _0x2987db || _0x2987db;
				case 0x17:
					if (_0xeceeef = 0x17, !_0x499f6d) {
						_0xa93ded = 0x1a;
						break;
					}
				case 0x1a:
					return _0x10ae9f & (0x17);
				case 0x1b:
					return _0x10ae9f & (0x14);
				case 0x23:
					_0xeceeef = 0x23, _0x39aedf = _0x19f133 & _0xa0cd39(0x1f), _0x200629 = !0x0, _0x4103bf = _0x39aedf;
				case 0x27:
					_0xeceeef = 0x27, _0xeceeef = 0x28, _0x25d982 || _0xa0cd39(0x3) == _0x307f44 || _0x307f44;
				case 0x2a:
					if (_0xeceeef = 0x2a, !_0x200629) {
						_0xa93ded = 0x2d;
						break;
					}
				case 0x2d:
					return _0x10ae9f & (0x2a);
				case 0x2e:
					return _0x10ae9f & (0x27);
				case 0x36:
					_0xeceeef = 0x36, _0xa94efd = _0x19f133 & _0xa0cd39(0x32), _0x42fc39 = !0x0, _0x36bb62 = _0xa94efd;
				case 0x3a:
					_0xeceeef = 0x3a, _0xeceeef = 0x3b, _0x3aabf6 || _0xa0cd39(0x3) == _0x55b9dc || _0x55b9dc;
				case 0x3d:
					if (_0xeceeef = 0x3d, !_0x42fc39) {
						_0xa93ded = 0x40;
						break;
					}
				case 0x40:
					return _0x10ae9f & (0x3d);
				case 0x41:
					return _0x10ae9f & (0x3a);
			}
		}
	}

	int _0x4b8368(_0x47078e, _0x2915b8)
        int _0x47078e;
        int _0x2915b8;
	{
		int _0x39efda(_0x3b1b03)
            int _0x3b1b03;
		{
			for(;;) switch(_0x3b1b03) {
				case 0x0:
					if (_0x47078e = 0x9c5d029b) {
						_0x3b1b03 = 0x7;
						break;
					}
				case 0x4:
					_0x47078e = 0x86b6557;
					break;
				case 0x7:
					_0x47078e = 0xe72bd385;
				case 0x8:
					_0x47078e = 0x5866e9c7;
			}
		};
	}

    int _0x39adef = _0xa0cd39(0x9);

    switch(_0x129aed + _0xa3bcde) {
        int _0xaabbcd, _0xdefabc;
        scanf(_0x30aef9(0x5), &_0xaabbcd);

        for(_0xdefabc=0x1; _0xdefabc<=_0xaabbcd; _0xdefabc++) {
            printf(_0x30aef9(0x5), _0xdefabc);
        }

        int _0xac2102 = _0xa0cd39(0x1);
        while(_0xac2102++) {
            printf(_0x30aef9(0x5), 0x3dfa9a, 0xa78294, 0x29acde, 0x29adca);
            printf(_0x30aef9(0x5), 0x1 * 0x2 * 0x3 * 0x4 * 0x5 * 0x6 * 0x7 * 0x8 * 0x9 * 0x0);
            printf(_0x30aef9(0x5), 0x1 * _0xa0cd39(0x1) * _0xa0cd39(_0xa0cd39(0x1)), _0xa0cd39(_0xa0cd39(_0xa0cd39(0x1))));
            scanf(_0x30aef9(0x5), 0x10293a);
        }

        1; 2; 3; _0x39ddfd: printf(_0x30aef9(0x5), pow(_0xa0cd39(0x1), 12345678));
        scanf(_0x30aef9(0x5), _0xa0cd39(0x1), _0xa0cd39(0x1), _0xa0cd39(0x2), _0xa0cd39(0x3));
        int _0x1838af = _0xa0cd39(0x1);
        while(_0x1838af--) {
            if(_0x1838af && 0x1 * 0x2 * 0x3 * 0x4 * 0x5 * 0x6 * 0x7 * 0x8 * 0x9 * 0x0) {
                while(1) {
                    printf(_0x30aef9(0x5), _0xa0cd39(0x1));
                }
            }
            else {
                while(0x5 * 0x6 * 0x7 * 0x8 * 0x9 * 0x0 * 0x1 * 0x2 * 0x3 * 0x4) {
                    int _0xaaaaaa, _0xbbbbbb;
                    for(_0xaaaaaa=1; _0xaaaaaa<20; _0xaaaaaa++) {
                        for(_0xbbbbbb=1; _0xbbbbbb<_0xaaaaaa; _0xbbbbbb++) {
                            printf(_0x30aef9(0x6), '*');
                        }
                        printf(_0x30aef9(0x6), '\n');
                    }
                }
            }
        }

        if(_0x1838af && !_0x1838af + _0xa0cd39(0x3)) {
            goto _0x39ddfd;
        }

        while(_0xa0cd39(0x3) + _0xa0cd39(0x2) + _0xa0cd39(0x1) + _0xa0cd39(0x1)) {
            double _0x39dfab = _0xa0cd39(0x7);
            printf(_0xa0cd39, _0xac2102);
            for(_0x39dfab=0x0; _0x39dfab<=0xA; _0x39dfab++) {
                if(_0xa0cd39(0x1) && _0xa0cd39(0x1) && _0xa0cd39(0x2) && _0xa0cd39(0x3)) {
                    printf(_0x30aef9(0x6), _0xa0cd39);
                    printf(_0x30aef9(0x6), _0xac2102);
                    break;
                }

                do scanf(_0x30aef9(0x6), &_0x39dfab);
                while(_0xa0cd39(0x2) == _0xac2102);
            }
        }

        _0xa0cd39; printf; _0xa3bcde; _0x1838af; case 0xE: _0x129aed = 0xABCDEF; printf(_0x30aef9(0x7), "");
        while(_0x129aed--) {
            if(0x2 * 0x4 * 0x6 * 0x8 * 0x0 * 0xB * 0xD * 0xF && 0x6 * 0x7 * 0x8 * 0x9 * 0x0 * 0xA * 0xB) {
                int _0x273921;
                for(_0x273921=_0xa0cd39(0x3); _0x273921<=_0xa0cd39(0x4); _0x273921++) {
                    scanf(_0x273921, _0xa0cd39, main, _0x30aef9(0x5), _0x273921);
                }
            }
        }

        int _0x10ae94, _0xa04fe9, _0xae9d3f, _0x1aeff7;

        if(!_0x129aed) {
            int _0x49aef3;
            for(_0x49aef3=_0xa0cd39(0x3); _0xa0cd39(0x2); _0x49aef3++) {
                scanf(_0x49aef3, &_0x129aed);
                if(_0x129aed > _0xa0cd39(0x7)) {
                    printf(_0xa0cd39(0x5));
                    break;
                }
            }

            while(_0xa0cd39(0x2)) {
                scanf(_0x49aef3, &_0xa0cd39);

                if(!_0xa0cd39) {
                    printf(_0xa0cd39);
                    return 0x0;
                }
            }
        } else if(_0xa0cd39(0x2) + _0xa0cd39(0xF) && _0xa0cd39(0x3)) {
            _0x129aed =  _0xa0cd39(0xF) / 0x0;
            return 0x0;
        } else {
            int _0x29aee2 = _0xa0cd39(0x3);

            if(_0x29aee2) {
                _0xae9d3f = _0x10ae94 - _0xa04fe9;
                return 0x0;
            } else {
                _0x10ae94 = _0x29aee2 / _0xa0cd39(0x2);
            }

            _0xae9d3f = _0xa0cd39(0x1);
        }

        int _0x29aed2 = _0xa0cd39(_0xa0cd39(0x2) + _0xa0cd39(0x2)) & 0xFF;

        switch(_0xa0cd39(0x8)) {
            case 0x1:;
                int _0x3013e9, _0x2ae9fe, _0x349ae1;

                for(_0x349ae1 = _0xa0cd39(0x3); _0xa0cd39(0x2); ++_0x349ae1) {
                    scanf(_0x30aef9(0x2), &_0x3013e9, &_0x2ae9fe);

                    if(_0x3013e9 == _0xa0cd39(0x3) && _0x2ae9fe == _0xa0cd39(0x3)) break;
                    printf(_0x30aef9(0x20), _0x3013e9 + _0xa0cd39(0x3) + _0x2ae9fe, _0x349ae1, _0xa0cd39, _0x30aef9);
                }
            case 0x2:;
                putchar(_0x39282a(0x3)); putchar(_0x39282a(0x5)); putchar(_0x39282a(0x4));
                putchar(_0x39282a(0x4)); putchar(_0x39282a(0x1)); putchar(_0x39282a(0x2));
                putchar(_0x39282a(0x6)); putchar(_0x39282a(0x1)); putchar(_0x39282a(0x9));
                putchar(_0x39282a(0x8)); putchar(_0x39282a(0x7)); putchar(_0x39282a(0x0));

                break;
            case 0x3:;
                int _0x29eac9, _0x39aefd;
                scanf(_0x30aef9(0x5), &_0x29eac9);

                for(_0x39aefd=0; _0x39aefd<_0x29eac9; _0x39aefd++) {
                    int _0x4934ae, _0xa93ef8;
                    scanf( _0x30aef9(0x2), &_0x4934ae, &_0xa93ef8);

                    printf(_0x30aef9(32), _0x4934ae + _0xa93ef8);
                }
            case 0x4:;
                int _0x29aeec(_0x39ad92)
					int _0x39ad92;
				{
                    if(_0x39ad92 < _0xa0cd39(0x3)) return -_0x39ad92;
                    return _0x39ad92;
                }

                int _0x4aef92(_0x39aaea, _0x34ae26)
					int _0x39aaea;
					int _0x34ae26;
				{
                    if(_0x34ae26 == 0) return _0x39aaea;
                    _0x4aef92(_0x34ae26, _0x39aaea % _0x34ae26);
                }

				int _0xeed92a, _0x992942, _0x1ae23f, _0x35e9f8, _0x8a30fe = 0xFFFFFFFF / (_0xa0cd39(0x2) * (_0xa0cd39(0x2) * 0x2));
				scanf(_0x30aef9(0x2), &_0x1ae23f, &_0x35e9f8);

				for(_0xeed92a=1; _0xeed92a * _0xeed92a <= _0x35e9f8 / _0x1ae23f; _0xeed92a++) {
					if((_0x35e9f8 / _0x1ae23f % _0xeed92a) == _0xa0cd39(0x3)) {
						int _0x94efe8 = _0x35e9f8 / _0x1ae23f / _0xeed92a;
						if(_0x4aef92(_0xeed92a, _0x94efe8) != 1) continue;
						if(_0x8a30fe > _0x29aeec(_0xeed92a - _0x94efe8)) _0x992942 = _0xeed92a;
					}
				}

				printf(_0x30aef9(0x2), _0x1ae23f * _0x992942, _0x35e9f8 / _0x992942);
            case 0x5:;
                int _0x39efae, _0x32a7ff;
                for(_0x39efae=_0xa0cd39(0x2); ; _0x39efae++) {
                    scanf(_0x30aef9(0x7), &_0x32a7ff);
                    printf("%d\n", _0x32a7ff);
                    if(_0x32a7ff == _0xa0cd39(0x3)) break;
                }
            case 0x6:;
                int _0x4399cf, _0x49ae83, _0x39ae38;
                scanf(_0x30aef9(0x2), &_0x49ae83, &_0x39ae38);
                for(_0x4399cf=_0x49ae83; _0x4399cf<=_0x39ae38; _0x4399cf++)
                    if(_0x4399cf % 0x2 == _0xa0cd39(0x2))
                        printf("%d ", _0x4399cf);
            case 0x7:;
                puts(_0x30aef9(0x66));

                if(_0x29aed2 | _0xa0cd39(0x2)) {
                    break;
                }
            case 0x8:;
                int _0x923e87, _0x1183e7, _0x349afe = _0xa0cd39(0x2);
                scanf(_0x30aef9(0x7), &_0x923e87);

                for(_0x1183e7=1; _0x1183e7<=_0x923e87; _0x1183e7++)
                    _0x349afe *= _0x1183e7;
                printf(_0x30aef9(0x7), _0x349afe);
        }

        while(_0x1aeff7 * _0xa0cd39(0x3)) {
            printf(_0x30aef9(0x7), _0x30aef9(0x9));
        }

        float _0x3013e9, _0x2ae9fe, _0x349ae1;

        for(_0x349ae1 = _0xa0cd39(0x2); _0xa0cd39(0x3); ++_0x349ae1) {
            scanf(_0x30aef9(0x2), &_0x3013e9, &_0x2ae9fe);

            if(_0x3013e9 == _0xa0cd39(0x3) && _0x2ae9fe == _0xa0cd39(0x3)) break;
            printf(_0x30aef9(0x20), _0x3013e9 + _0xa0cd39(0x3) + _0x2ae9fe, _0x349ae1, _0xa0cd39, _0x30aef9);
        }

        0x0012BB * _0x39282a(0x3); _0x39282a(0x5) + 0xAABBCC;
        if(0x1 && 0x2 && 0x5 && 0x8 && 0xA && 0x0 && 0xC) {
             while(_0x39282a(0x8)) {
                int _0x135790;
                printf(_0x135790, _0x135790, _0x135790, _0x135790, _0x30aef9(0x5));
                for(_0x135790=0x0; _0x135790<0xF; _0x135790+=0x1) {
                    scanf(_0x135790, _0x30aef9(0x5));
                }
            }
        } else {
            if(_0x129aed) return _0xa0cd39(0x3);
        }
    }

    int _0x29482a, _0xab29dc, _0x39a938, _0x987654;

    for(_0x29482a=0x2; _0x29482a<=0x9; _0x29482a++) {
        for(_0xab29dc=_0xa0cd39(0x2); _0xab29dc<=0x9; _0xab29dc++) {
            printf(_0x30aef9(0x3), _0x29482a, _0xab29dc, _0x29482a * _0xab29dc);
            printf(_0x30aef9(0x6), _0x39282a(0x8));
        }
        printf(_0x30aef9(0x6), _0x39282a(0x8));
    }

    if(_0xab29dc && _0x987654 && _0xa0cd39(0x3) && _0xa0cd39(0x4) && _0xa0cd39(0x5)) {
        int _0x49afef, _0x39afed[0x14], _0x349daa[0x28], _0x123aae[0x28], _0x49adfe = _0xa0cd39(0x3);

        int _0x595ade(_0x39540a)
            int _0x39540a;
        {
            int _0xaf30dd, j;
            if(_0x39540a == _0x49afef+_0xa0cd39(0x2)) {
                _0x49adfe++;
                return;
            }


            for(_0xaf30dd=_0xa0cd39(0x2); _0xaf30dd <= _0x49afef; _0xaf30dd++) {
                if(!_0x39afed[_0xaf30dd] && !_0x349daa[_0x39540a - _0xaf30dd + _0x49afef] && !_0x123aae[_0x39540a + _0xaf30dd]) {
                    _0x39afed[_0xaf30dd] = _0x349daa[_0x39540a - _0xaf30dd + _0x49afef] = _0x123aae[_0x39540a+_0xaf30dd] = _0xa0cd39(0x2);
                    _0x595ade(_0x39540a + _0xa0cd39(0x2));
                    printf(_0x30aef9(0x7), "", "", "", "");
                    putchar(_0xa0cd39(0x3)); putchar(_0xa0cd39(0x3));
                    _0x39afed[_0xaf30dd] = _0x349daa[_0x39540a - _0xaf30dd + _0x49afef] = _0x123aae[_0x39540a + _0xaf30dd] = _0xa0cd39(0x3);
                }
            }
        }

        scanf(_0x30aef9(0x5), &_0x49afef);
        _0x595ade(_0xa0cd39(0x2));

        printf(_0x30aef9(0x5), _0x49adfe);
    }

    switch(_0x39a938 = _0x30aef9(0x3)) {
        int _0x30fde3 = _0xa0cd39(0x2);

        int *_0x495fe9, *_0xff03e7;

        typedef struct {
            char _0x439ed5[8];
            char _0x123459[4];
            int _0x987654;
            int _0x1a2b3c;
            char _0x49dea9[131];
            char _0x192837[131];
        } _0x349eef;

        int _0xad937f, _0x33efc7;
        int _0x4930ff = _0xa0cd39(0x2);
        int _0x3939ff = _0xa0cd39(0x3);

        _0x349eef _0xac8de4[2000];
        int _0x1928a5[_0xa0cd39(19)];

        char _0x399aef[6][105] = {_0x30aef9(0xB), _0x30aef9(0xC), _0x30aef9(0xD), _0x30aef9(0xE), _0x30aef9(0xF)};

        int _0x49340f = _0xa0cd39(0x3), _0xaed28f;
        int _0x9939a7;
        char _0x39aee7[_0xa0cd39(0xE)];

        void _0xa9ff3d(_0x4954e1, _0x991e3d)
			int _0x4954e1;
			int _0x991e3d;
        {
            if(_0x4954e1 > _0xa0cd39(17) || _0x991e3d > _0xa0cd39(17))
                return;
            char _0x369cd4[34];
            strcpy(_0x369cd4, _0x30aef9(0xA));
            _0x369cd4[14] = (_0x4954e1 / _0xa0cd39(0xF)) + _0xa0cd39(16);
            _0x369cd4[15] = ((_0x4954e1 % _0xa0cd39(0xF)) / 10) + _0xa0cd39(16);
            _0x369cd4[16] = (_0x4954e1 % 10) + _0xa0cd39(16);

            _0x369cd4[24] = (_0x991e3d / _0xa0cd39(0xF)) + _0xa0cd39(16);
            _0x369cd4[25] = ((_0x991e3d % _0xa0cd39(0xF)) / 10) + _0xa0cd39(16);
            _0x369cd4[36] = (_0x991e3d % 10) + _0xa0cd39(16);

            system(_0x369cd4);
        }

        void _0x49dea9(_0x549fed)
			const char* _0x549fed;
        {
            char _0x369cd4[151];
            strcpy(_0x369cd4, _0x30aef9(16));
            strcat(_0x369cd4, _0x549fed);
            system(_0x369cd4);
        }

        void _0x49430d(_0x4954e1, _0x991e3d)
			int _0x4954e1;
			int _0x991e3d;
        {
            struct {
                int X;
                int Y;
            } _0x49fedf;
            _0x49fedf.X = _0x4954e1;
            _0x49fedf.Y = _0x991e3d;

        }

        int _0x93afd6(_0x4954e1, _0x991e3d)
			unsigned short _0x4954e1;
			unsigned short _0x991e3d;
        {
            return _0x4954e1 | (_0x991e3d << 4);
        }

        struct {
            int X;
            int Y;
        } _0xc0ef83;

        void _0x4930ef(_0x9430fe)
			const char* _0x9430fe;
        {
            _0x49430d(_0xa0cd39(0x3), 16);
            printf(_0x9430fe);
            getch();
            _0x4930ff = _0xa0cd39(0x2);
            _0x471ed8();
            _0x3939ff = _0xa0cd39(0x3);
        }

        void _0x471ed8()
        {
            system(_0x30aef9(0xA));
            _0xa9ff3d(120, 30);
            _0x49430d(_0xa0cd39(0x3), 29);

            _0x93afd6(_0xa0cd39(0x3), 7);

            for(_0xaed28f=_0xa0cd39(0x2); _0xaed28f<=_0xa0cd39(0x2);_0xaed28f++){printf(" ");}
            printf("%3d %3d", _0x30fde3, (_0x49340f - _0xa0cd39(0x2)) / 21 + _0xa0cd39(0x2));
            _0x93afd6(7, _0xa0cd39(0x3));
            _0x49430d(_0xa0cd39(0x3), _0xa0cd39(0x3));
            for(_0xaed28f = _0xad937f; _0xaed28f <= _0x33efc7; _0xaed28f++) {
                if(_0xaed28f >= _0x49340f)
                    break;
                if( strcmp(_0xac8de4[_0xaed28f]._0x439ed5, "") == _0xa0cd39(0x3) )
                    continue;
                if(strlen(_0xac8de4[_0xaed28f]._0x192837) > 28)
                    printf("%4d %c%c%c%c.%c%c.%c%c. %c%c:%c%c %2d %8s %14s %29s",
                           _0xaed28f + _0xa0cd39(0x2), _0xac8de4[_0xaed28f]._0x439ed5[_0xa0cd39(0x3)],
                           _0xac8de4[_0xaed28f]._0x439ed5[_0xa0cd39(0x2)], _0xac8de4[_0xaed28f]._0x439ed5[2],
                           _0xac8de4[_0xaed28f]._0x439ed5[3], _0xac8de4[_0xaed28f]._0x439ed5[4],
                           _0xac8de4[_0xaed28f]._0x439ed5[_0xa0cd39(19)], _0xac8de4[_0xaed28f]._0x439ed5[6],
                           _0xac8de4[_0xaed28f]._0x439ed5[7], _0xac8de4[_0xaed28f]._0x123459[_0xa0cd39(0x3)],
                           _0xac8de4[_0xaed28f]._0x123459[_0xa0cd39(0x2)], _0xac8de4[_0xaed28f]._0x123459[2],
                           _0xac8de4[_0xaed28f]._0x123459[3], _0xac8de4[_0xaed28f]._0x987654,
                           _0x399aef[_0xac8de4[_0xaed28f]._0x1a2b3c], _0xac8de4[_0xaed28f]._0x49dea9, "");
                else
                    printf("%4d %c%c%c%c.%c%c.%c%c. %c%c:%c%c %2d %8s %14s %29s",
                           _0xaed28f + _0xa0cd39(0x2),
                           _0xac8de4[_0xaed28f]._0x439ed5[_0xa0cd39(0x3)], _0xac8de4[_0xaed28f]._0x439ed5[_0xa0cd39(0x2)],
                           _0xac8de4[_0xaed28f]._0x439ed5[2], _0xac8de4[_0xaed28f]._0x439ed5[3], _0xac8de4[_0xaed28f]._0x439ed5[4],
                           _0xac8de4[_0xaed28f]._0x439ed5[_0xa0cd39(19)], _0xac8de4[_0xaed28f]._0x439ed5[6],
                           _0xac8de4[_0xaed28f]._0x439ed5[7], _0xac8de4[_0xaed28f]._0x123459[_0xa0cd39(0x3)],
                           _0xac8de4[_0xaed28f]._0x123459[_0xa0cd39(0x2)], _0xac8de4[_0xaed28f]._0x123459[2],
                           _0xac8de4[_0xaed28f]._0x123459[3], _0xac8de4[_0xaed28f]._0x987654,
                           _0x399aef[_0xac8de4[_0xaed28f]._0x1a2b3c], _0xac8de4[_0xaed28f]._0x49dea9,
                           _0xac8de4[_0xaed28f]._0x192837);
            }

            _0x49430d(3, 3);
            _0xc0ef83.X = 3, _0xc0ef83.Y = 3;
            _0x4930ff = _0xa0cd39(0x2);
            printf(_0x30aef9(30));
            _0x49430d(6, 3);
        }

        void _0x4399ed()
        {
            system(_0x30aef9(0xA));
            _0x49dea9(_0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x49dea9);
            _0xa9ff3d(80, 20);
            _0x49430d(_0xa0cd39(0x3), 19);
            _0x93afd6(_0xa0cd39(0x3), 7);
            for(_0xaed28f=_0xa0cd39(0x2); _0xaed28f<=59;_0xaed28f++){printf(" ");}
            _0x93afd6(7, _0xa0cd39(0x3));
            _0x49430d(_0xa0cd39(0x3), _0xa0cd39(0x3));
            printf("%s", _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x49dea9);
            _0x49430d(76, _0xa0cd39(0x2));
            printf("%c%c%c%c.%c%c.%c%c. %c%c:%c%c", _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[_0xa0cd39(0x3)],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[_0xa0cd39(0x2)],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[2],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[3],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[4],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[_0xa0cd39(19)],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[6],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[7],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x123459[_0xa0cd39(0x3)],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x123459[_0xa0cd39(0x2)],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x123459[2],
                    _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x123459[3]);
            printf("%d / 10", _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x987654);;
            printf("%s", _0x399aef[_0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x1a2b3c]);
            printf(_0x30aef9(29), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x49dea9);
            printf(_0x30aef9(28), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x192837);
        }

        void _0x349def()
        {
            system(_0x30aef9(0xA));
            _0xa9ff3d(80, 20);
            _0x49430d(13, 3);
            scanf(_0x30aef9(0x7), _0xac8de4[_0x49340f]._0x439ed5);
            if(strlen(_0xac8de4[_0x49340f]._0x439ed5) != 8)
                return 0;
            else {
                _0x49430d(13, 4);
                scanf(_0x30aef9(0x7), _0xac8de4[_0x49340f]._0x123459);
                if(strlen(_0xac8de4[_0x49340f]._0x123459) != 4)
                    _0x4930ef(_0x30aef9(23));
                else {
                    _0x49430d(13, _0xa0cd39(19));
                    scanf("%d", &_0xac8de4[_0x49340f]._0x987654);
                    if(_0xac8de4[_0x49340f]._0x987654 > 10 || _0xac8de4[_0x49340f]._0x987654 < _0xa0cd39(0x2))
                        _0x4930ef(_0x30aef9(24));
                    else {
                        _0x49430d(13, 6);
                        scanf("%d", &_0xac8de4[_0x49340f]._0x1a2b3c);
                        if(_0xac8de4[_0x49340f]._0x1a2b3c > 4 || _0xac8de4[_0x49340f]._0x1a2b3c < _0xa0cd39(0x3))
                            _0x4930ef(_0x30aef9(25));
                        else {
                            _0x49430d(13, 7);
                            scanf(_0x30aef9(0x7), _0xac8de4[_0x49340f]._0x49dea9);
                            _0x49430d(13, 8);
                            scanf(_0x30aef9(0x7), _0xac8de4[_0x49340f]._0x192837);
                            _0x49340f++;
                            _0xff03e7 = fopen(_0x30aef9(17), _0x30aef9(22));

                            fprintf(_0xff03e7, _0x30aef9(26), _0xac8de4[_0x49340f - _0xa0cd39(0x2)]._0x439ed5, _0xac8de4[_0x49340f - _0xa0cd39(0x2)]._0x123459, _0xac8de4[_0x49340f - _0xa0cd39(0x2)]._0x987654, _0xac8de4[_0x49340f - _0xa0cd39(0x2)]._0x1a2b3c, _0xac8de4[_0x49340f - _0xa0cd39(0x2)]._0x49dea9, _0xac8de4[_0x49340f - _0xa0cd39(0x2)]._0x192837);
                            fclose(_0xff03e7);
                            _0x4930ff = _0xa0cd39(0x2);
                            _0x471ed8();
                            _0x3939ff = _0xa0cd39(0x3);
                        }
                    }
                }
            }
        }

        void _0x3494ff()
        {
            system(_0x30aef9(0xA));
            char _0x43937a[9];
            strcpy(_0x43937a, _0x30aef9(21));
            _0x49dea9( strcat(_0x43937a, _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x49dea9) );
            int _0xaed28f;
            _0xa9ff3d(80, 20);
            _0x49430d(13, 3);

            for(_0xaed28f = _0xa0cd39(0x3); _0xaed28f < 8; _0xaed28f++)
                printf(_0x30aef9(0x6), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5[_0xaed28f]);
            printf(" => ");
            scanf(_0x30aef9(0x7), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x439ed5);
            _0x49430d(13, 4);
            printf("X");
            for(_0xaed28f = _0xa0cd39(0x2); _0xaed28f < 4; _0xaed28f++)
                printf(_0x30aef9(0x6), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x123459[_0xaed28f]);
            printf(" => ");
            scanf(_0x30aef9(0x7), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x123459);
            _0x49430d(13, _0xa0cd39(19));
            printf("%d => ", _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x987654);
            scanf("%d", &_0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x987654);
            _0x49430d(13, 6);
            printf("%d => ", _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x1a2b3c);
            scanf("%d", &_0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x1a2b3c);
            _0x49430d(13, 7);
            printf("%s => ", _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x49dea9);
            scanf(_0x30aef9(0x7), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x49dea9);
            _0x49430d(13, 8);
            printf("%s => ", _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x192837);
            scanf(_0x30aef9(0x7), _0xac8de4[_0x4930ff - _0xa0cd39(0x2) + _0xad937f]._0x192837);
            _0xff03e7 = fopen(_0x30aef9(17), _0x30aef9(18));

            for(_0xaed28f=_0xa0cd39(0x3); _0xaed28f<=_0x49340f-_0xa0cd39(0x2); _0xaed28f++) {
                fprintf(_0xff03e7, _0x30aef9(26), _0xac8de4[_0xaed28f]._0x439ed5, _0xac8de4[_0xaed28f]._0x123459, _0xac8de4[_0xaed28f]._0x987654, _0xac8de4[_0xaed28f]._0x1a2b3c, _0xac8de4[_0xaed28f]._0x49dea9, _0xac8de4[_0xaed28f]._0x192837);
            }
            fclose(_0xff03e7);
            _0x4930ff = _0xa0cd39(0x2);
            _0x471ed8();
            _0x3939ff = _0xa0cd39(0x3);
        }

        void _0x394e9f() {
            _0x49430d(_0xa0cd39(0x3), 26);
            int _0x01af9e = getch();
            if(_0x01af9e != 'y') {
                _0x49430d(_0xa0cd39(0x3), 26);
                printf(_0x30aef9(27));
                printf(_0x30aef9(27));
                printf(_0x30aef9(27));
                return;
            }

            int _0xaed28f;
            for(_0xaed28f=_0x4930ff - _0xa0cd39(0x3) + _0xad937f; _0xaed28f<=_0x49340f - _0xa0cd39(0x2); _0xaed28f++) {
                strcpy(_0xac8de4[_0xaed28f - _0xa0cd39(0x2)]._0x439ed5, _0xac8de4[_0xaed28f]._0x439ed5);
                strcpy(_0xac8de4[_0xaed28f - _0xa0cd39(0x2)]._0x123459, _0xac8de4[_0xaed28f]._0x123459);
                _0xac8de4[_0xaed28f - _0xa0cd39(0x2)]._0x987654 = _0xac8de4[_0xaed28f]._0x987654;
                _0xac8de4[_0xaed28f - _0xa0cd39(0x2)]._0x1a2b3c = _0xac8de4[_0xaed28f]._0x1a2b3c;
                strcpy(_0xac8de4[_0xaed28f - _0xa0cd39(0x2)]._0x49dea9, _0xac8de4[_0xaed28f]._0x49dea9);
                strcpy(_0xac8de4[_0xaed28f - _0xa0cd39(0x2)]._0x192837, _0xac8de4[_0xaed28f]._0x192837);
            }
            _0xff03e7 = fopen(_0x30aef9(17), _0x30aef9(18));

            _0x49340f--;

            for(_0xaed28f=_0xa0cd39(0x3); _0xaed28f<=_0x49340f - _0xa0cd39(0x2); _0xaed28f++) {
                fprintf(_0xff03e7, "\n%s %s %d %d %s %s", _0xac8de4[_0xaed28f]._0x439ed5, _0xac8de4[_0xaed28f]._0x123459, _0xac8de4[_0xaed28f]._0x987654, _0xac8de4[_0xaed28f]._0x1a2b3c, _0xac8de4[_0xaed28f]._0x49dea9, _0xac8de4[_0xaed28f]._0x192837);
            }
            fclose(_0xff03e7);

            _0x471ed8();
        }

        _0x49340f = _0xa0cd39(0x3);
        _0xa9ff3d(120, 30);


        _0x495fe9 = fopen(_0x30aef9(17), _0x30aef9(19));
        while(_0x495fe9 && _0xa0cd39(0x3)) {
            fscanf(_0x495fe9, _0x30aef9(20), _0x39aee7, _0x39aee7, &_0x9939a7, &_0x9939a7, _0x39aee7, _0x39aee7);
            _0x49340f++;
        }
        fclose(_0x495fe9);

        _0xff03e7 = fopen(_0x30aef9(17), _0x30aef9(19));
        for(_0xaed28f=_0xa0cd39(0x3); _0xaed28f<=_0x49340f - _0xa0cd39(0x2); _0xaed28f++) {
            fscanf(_0xff03e7, _0x30aef9(20), _0xac8de4[_0xaed28f]._0x439ed5, _0xac8de4[_0xaed28f]._0x123459, &_0xac8de4[_0xaed28f]._0x987654, &_0xac8de4[_0xaed28f]._0x1a2b3c, _0xac8de4[_0xaed28f]._0x49dea9, _0xac8de4[_0xaed28f]._0x192837);
        }
        fclose(_0xff03e7);

        _0xad937f = _0xa0cd39(0x3);
        _0x33efc7 = 20;

        _0x471ed8();

        int _0xf709a3 = _0xa0cd39(0x3);

        while(_0xa0cd39(0x2) && _0xa0cd39(0x3)) {
            _0xf709a3 = getch();
            if(_0xf709a3 == 224)
                _0xf709a3 = getch();
            if(_0xf709a3 == 72) {
                if(_0x4930ff - _0xa0cd39(0x2) > _0xa0cd39(0x3) && _0x3939ff == _0xa0cd39(0x3)) {
                    _0x4930ff--;
                    _0x49430d(_0xc0ef83.X - _0xa0cd39(0x2), _0xc0ef83.Y);
                    printf(" ");
                    _0x49430d(_0xc0ef83.X, _0xc0ef83.Y - _0xa0cd39(0x2));
                    _0xc0ef83.Y -= _0xa0cd39(0x2);
                    printf(_0x30aef9(30));
                }
            } else if(_0xf709a3 == 80) {
                if(_0x4930ff + _0xa0cd39(0x2) <= _0x33efc7 - _0xad937f + _0xa0cd39(0x2) && _0x4930ff + _0xa0cd39(0x2) <= _0x49340f - _0xad937f && _0x3939ff == _0xa0cd39(0x3)) {
                    _0x4930ff++;
                    _0x49430d(_0xc0ef83.X - _0xa0cd39(0x2), _0xc0ef83.Y);
                    printf(" ");
                    _0x49430d(_0xc0ef83.X, _0xc0ef83.Y + _0xa0cd39(0x2));
                    _0xc0ef83.Y += _0xa0cd39(0x2);
                    printf(_0x30aef9(30));
                }
            } else if(_0xf709a3 == 32) {
                if(_0x3939ff == _0xa0cd39(0x3)) {
                    _0x3939ff = _0xa0cd39(0x2);
                    _0x4399ed();
                }
            } else if(_0xf709a3 == 'q') {
                if(_0x3939ff == _0xa0cd39(0x2) || _0x3939ff == 2) {
                    _0x4930ff = _0xa0cd39(0x2);
                    _0x30fde3 = _0xa0cd39(0x2);
                    _0xad937f = _0xa0cd39(0x3);
                    _0x33efc7 = 20;
                    _0x471ed8();
                    _0x3939ff = _0xa0cd39(0x3);
                }
            } else if(_0xf709a3 == '_0xaed28f') {
                if(_0x3939ff == _0xa0cd39(0x3)) {
                    _0x3939ff = 2;
                    _0x349def();
                }
            } else if(_0xf709a3 == 'e') {
                if(_0x3939ff == _0xa0cd39(0x3)) {
                    _0x3939ff = 3;
                    _0x3494ff();
                }
            } else if(_0xf709a3 == 'n') {
                if(_0x3939ff == _0xa0cd39(0x3)) {
                    _0x394e9f();
                }
            } else if(_0xf709a3 == 'x') {
                _0x49dea9(_0x30aef9(31));
                return _0xa0cd39(0x3);
            } else if(_0xf709a3 == 'n') {
                if(_0x3939ff == _0xa0cd39(0x3) && _0xad937f + 20 < _0x49340f) {
                    _0x30fde3++;
                    _0xad937f = _0xad937f + 21;
                    _0x33efc7 = _0x33efc7 + 21;
                    _0x471ed8();
                }
            } else if(_0xf709a3 == 'b') {
                if(_0x3939ff == _0xa0cd39(0x3) && _0xad937f - 20 >= _0xa0cd39(0x3)) {
                    _0x30fde3--;
                    _0xad937f = _0xad937f - 21;
                    _0x33efc7 = _0x33efc7 - 21;
                    _0x471ed8();
                }
            } else if(_0xf709a3 == 'o') {
                if(_0x3939ff == _0xa0cd39(0x3)) {
                    system(_0x30aef9(0xA));
                    system("cmd");
                    _0x471ed8();
                }
            } else if(_0xf709a3 == 'm') {
                if(_0x3939ff == _0xa0cd39(0x3)) {
                    if((_0x49340f - _0xa0cd39(0x2)) / 21 + _0xa0cd39(0x2) != _0x30fde3) {
                        _0x30fde3 = _0xa0cd39(0x2);
                        _0xad937f = _0xa0cd39(0x3);
                        _0x33efc7 = 21;
                        for(_0xaed28f=2; _0xaed28f<=(_0x49340f - _0xa0cd39(0x2)) / 21 + _0xa0cd39(0x2); _0xaed28f++) {
                            _0x30fde3++;
                            _0xad937f = _0xad937f + 21;
                            _0x33efc7 = _0x33efc7 + 21;
                        }
                        _0x471ed8();
                    }
                }
            } else if(_0xf709a3 == 'v') {
                if(_0x3939ff == _0xa0cd39(0x3)) {
                    _0x30fde3 = _0xa0cd39(0x2);
                    _0xad937f = _0xa0cd39(0x3);
                    _0x33efc7 = 21;
                    _0x471ed8();
                }
            }
            _0x49430d(4, 3);
        }
    }

    for(_0x39a938=_0xa0cd39(0x3); _0x39a938 == _0xa0cd39(0x3); _0x39a938++) {
        typedef struct {
            long long _0x349ad0;
            long long _0x1afec8;
        } _0x439ae5;

        _0x439ae5 _0x0489ad[_0xa0cd39(0xA)];

        long long _0x4847ed, _0x43aefc, _0x49ae0f, _0x49a0fe, _0x39aef8 = _0xa0cd39(0x3), _0x39aaed;

        scanf(_0x30aef9(0x2), &_0x4847ed, &_0x43aefc);

        for(_0x49ae0f=_0xa0cd39(0x2); _0x49ae0f<=_0x4847ed; _0x49ae0f++) {
            _0x0489ad[_0x49ae0f]._0x349ad0 = _0x390adf();
            _0x0489ad[_0x49ae0f]._0x1afec8 = _0x390adf();
        }

        _0x39aef8 = _0xa0cd39(0x3);
        for(_0x49ae0f=_0xa0cd39(0x2); _0x49ae0f<=_0x4847ed; _0x49ae0f++) {
            _0x39aaed = _0x0489ad[_0x49ae0f]._0x349ad0 * _0x0489ad[_0x49ae0f]._0x1afec8;

            for(_0x49a0fe=_0x49ae0f-_0xa0cd39(0x2); _0x49a0fe>=_0xa0cd39(0x2); _0x49a0fe--) {
                if(_0x39aaed > (_0x0489ad[_0x49a0fe]._0x349ad0 + (_0x49ae0f-_0x49a0fe) * _0x43aefc) * _0x0489ad[_0x49ae0f]._0x1afec8) {
                    _0x39aaed = (_0x0489ad[_0x49a0fe]._0x349ad0 + (_0x49ae0f-_0x49a0fe) * _0x43aefc) * _0x0489ad[_0x49ae0f]._0x1afec8;
                }
            }

            _0x39aef8 += _0x39aaed;
        }

        printf(_0x30aef9(0x5), _0x39aef8);
    }

    while(0x1 || 0x9) {
        scanf(_0x987654, _0x39a938, _0xab29dc);

        for(_0x29482a=_0xab29dc; ; _0x987654 += 1234) {
            int _0xac8204 = getch();
            float _0xac29da = pow(_0xac8204, 0xF);
        }
    }

    return _0xa0cd39(_0xa0cd39(0x3));
}

9. 디스코드 API 메시지 파서[편집]

/api/v8/channels/.../messages에서 받아온 메시지들을 파싱해줌. Windows XP에서 실행 가능.

const fs       = require('fs');
const readline = require('readline');
const emoji    = require('node-emoji');

const print = console.log;

const rl = readline.createInterface({
	input:  process.stdin,
	output: process.stdout
});

function convertMention(mention) {
	var retval = mention;
	
	const matches = mention.match(/<@!?(\d+)>/g); // @멘션 정규식

	if (!matches) return mention; // @멘션 없으면 그대로 반환
	
	for(m of matches) {
		try {
			// @멘션을 읽을 수 있게 변환
			const id = m.match(/<@!?(\d+)>/)[1];
			const us = client.users.find(user => user.id == id)['username'];
			const dc = client.users.find(user => user.id == id)['discriminator'];
			retval = retval.replace(m, `[@${us}#${dc}]`);
		} catch(e) {}
	}
	
	// 결과값 반환
	return retval;

	//const id = matches[1];

	//return client.users.find(user => user.id == id);
}

print('이 프로그램은 Disocrd API - /v8/channels/.../messages에서 받아온 JSON을 파싱하여 CSV로 저장해줍니다.\n');

rl.question('JSON 파일 이름: ', fn => {
	rl.close();
	const jsnMesages = fs.readFileSync('./' + fn);
	var messages = {};
	
	var arr = [], ret = '"타임스탬프","시간","사용자 번호","사용자 이름","메시지 번호","내용","반응","수정시각","첨부파일","플래그"\n';
	
	try {
		messages = JSON.parse(jsnMesages);
	} catch(e) {
		print('JSON 데이타가 올바르지 않습니다.');
		process.exit(1);
	}
	
	for(msg of messages) {
		arr.push({
			id: msg.id,
			timestamp: (new Date(msg.timestamp)).getTime(),
			edited_timestamp: (new Date(msg.edited_timestamp)).getTime(),
			username: msg.author.username + '#' + msg.author.discriminator,
			userid: msg.author.id,
			pinned: msg.pinnded,
			tts: msg.tts,
			attachments: msg.attachments,
			embeds: msg.embeds,
			content: msg.content,
			reactions: msg.reactions || []
		});
	}
	
	function parseDate(date) {
		var hour = date.getHours();
		hour = (hour < 10 ? "0" : "") + hour;

		var min  = date.getMinutes();
		min = (min < 10 ? "0" : "") + min;

		var sec  = date.getSeconds();
		sec = (sec < 10 ? "0" : "") + sec;

		var year = date.getFullYear();

		var month = date.getMonth() + 1;
		month = (month < 10 ? "0" : "") + month;

		var day  = date.getDate();
		day = (day < 10 ? "0" : "") + day;

		return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
	}
	
	arr.sort(function(l, r) {
		return Number(l.timestamp) - Number(r.timestamp);
	});
	
	for(msg of arr) {
		const date = new Date(msg.timestamp);
		const datestr = parseDate(date);
			
		const date2 = new Date(msg.edited_timestamp);
		const datestr2 = 
			!date2.getTime() ? '-' : parseDate(date2);
		
		var r = '';
		for(re of msg.reactions) {
			const emj = re.emoji.name;
			
			if(emoji.hasEmoji(emj)) {
				r += emoji.find(emj).key + ' ';
			} else {
				r += emj + ' ';
			}
		}
		
		var a = '';
		for(at of msg.attachments) {
			a += `[${at.filename} (${at.width}*${at.height} / ${at.size})] `;
		}
		
		var c = msg.content;
		if(msg.type == 7) {
			c = '[서버에 참가했읍니다.]';
		}
		if(msg.embeds) {
			
		}
		
		ret +=
			'"' + msg.timestamp + '",' +
			'"' + datestr + '",' +
			'"' + msg.userid + '",' +
			'"' + msg.username.replace(/["]/g, '""') + '",' +
			'"' + msg.id + '",' +
			'"' + c.replace(/["]/g, '""') + '",' +
			'"' + r.replace(/["]/g, '""') + '",' +
			'"' + datestr2 + '",' +
			'"' + a.replace(/["]/g, '""') + '",' +
			'" "\n'
			;
	}
	
	const rl_2 = readline.createInterface({
		input: process.stdin,
		output: process.stdout
	});
	
	rl_2.question('저장할 파일의 이름: ', cfn => {
		fs.writeFile(cfn + '.csv', ret, e => {
			if(e) print('저장 실패: ' + e);
			else print('저장되었읍니다! MS 엑셀을 사용 중이시라면 인코딩을 CP949로 바꾸시면 됩니다~^^');
		});
		rl_2.close();
	});
});

10. 디스코드 메시지 추출기[편집]

Windows 7 이상에서만 실행 가능 지못미 액스피 그래도 윈도우 7 가상머신이 있으니까

const fs = require('fs'); // 화일시스템 라이브러리 가져오기
const inputReader = require('wait-console-input') // 입력받는 라이브러리 가져오기
const readline = require('readline'); // 한글 입력받기 위함

const Discord = require('discord.js'); // DJS 라이브러리
// const Constants = require('discord.js/src/util/Constants.js'); // 안 씀.

const emoji = require('node-emoji'); // 반응을 텍스트로 변환

const cliProgress = require('cli-progress'); // 진행율 표시기

// Constants.DefaultOptions.ws.properties.$browser = `Discord Android`; // 안 씀. 봇에 휴대폰 표시 나오게 하는거.
const client = new Discord.Client();

// 익숙한 BASIC과 파이선 따라가기
function print(x) {
	console.log(x);
}

// 개행 없이 출력
function prt(x) {
	process.stdout.write(x);
}

// 입력 함수
function input(p) {
	prt(p); // 일부러 이렇게. 바로하면 한글 깨짐.
	return inputReader.readLine('');
}

// 대상 채널 ID
var chid = '12345678';

// 저장할 화일명
var fn = String(Math.floor(Math.random() * (99999999 - 10000000) + 10000000)) + ".CSV";

// 화일 저장하는 함수
function appendFile(filename, content) {
	fs.appendFile(filename, content, 'utf-8', function(err) {
		if(err) {
			return;
		}
	}); 
	
	// fs.close();
}

// @멘션을 읽을 수 있게 변환
function convertMention(mention) {
	var retval = mention;
	
	const matches = mention.match(/<@!?(\d+)>/g); // @멘션 정규식

	if (!matches) return mention; // @멘션 없으면 그대로 반환
	
	for(m of matches) {
		try {
			// @멘션을 읽을 수 있게 변환
			const id = m.match(/<@!?(\d+)>/)[1];
			const us = client.users.find(user => user.id == id)['username'];
			const dc = client.users.find(user => user.id == id)['discriminator'];
			retval = retval.replace(m, `[@${us}#${dc}]`);
		} catch(e) {}
	}
	
	// 결과값 반환
	return retval;

	//const id = matches[1];

	//return client.users.find(user => user.id == id);
}

client.once('ready', async function() {
	// 혹시 모르니..
	client.user.setPresence({
		status: "invisible"
	});
	
	var s  = 1;
	var sl = [];
	
	for(server of client.guilds.array())
		{
			print(`[${s}] ${server['name']}`);
			sl.push(s++);
		}
	
	var guildname = input("대상 서버: ");
		
	if(!sl.includes(Number(guildname))) {
		print('\n서버가 존재하지 않습니다.');
		return;
	}
	
	var guild = client.guilds.array()[Number(guildname) - 1];
	prt('\n');
	
	var c  = 0;
	var cl = [];
	
	for(ch of guild.channels.array())
		{
			if(ch['type'] == 'category') { c++; continue; }
			if(ch['type'] == 'voice') { c++; continue; }
			print(`[${c}] ${ch['name']}`);
			cl.push(c++);
		}
		
	var chname = input("대상 채널: ");
		
	if(!cl.includes(Number(chname))) {
		print('\n채널이 사용가능하지 않습니다.');
		return;
	}
	
	prt('\n');
	
	print('[1] CSV');
	print('[2] HTML');
	print('[0] 모두');
	
	var fmt = Number(input('저장 형식(모르면 2): ')) || 0;
	var html = `
		<style>
			.res-wrapper .res .r-head {
				border-radius: 5px 5px 0 0;
				padding: 8px 10px 8px 10px;
				background: linear-gradient(rgb(226\, 237\, 254) 0%\, rgb(202\, 219\, 243) 51%\, rgb(161\, 191\, 229) 50%\, rgb(90\, 139\, 204) 100%);
				text-shadow: 1px 1px 0 #cecece;
			}
			
			.res-wrapper .res .r-body {
				padding: 8px 10px 8px 10px;
				background: linear-gradient(#eee\, #ccc);
				overflow-x: scroll;
			}
			
			.res-wrapper .res.res-type-status .r-body {
				background: linear-gradient(orange\, #ccc);
			}
			
			.res-wrapper .res .combo {
				border-radius: 0 0 5px 5px;
				padding: 8px 10px 8px 10px;
				background: linear-gradient(#777\, #333);
				color: white;
			}
			
			.res-wrapper {
				margin: 20px 0 20px 0;
			}
			
			.pull-right {
				float: right;
			}
		</style>
		
		<div id=res-container>
	`;
	
	var channel = guild.channels.array()[chname];
	
	chid = channel.id;
	
	fn = guild.name + '-' + channel.name + '(' + (String(new Date().getFullYear()).slice(2, 4)) + (new Date().getMonth() + 1) + new Date().getDate() + ').CSV';
	
	var excludedUser = '';
	
	const fromst = Number(input("다음 메시지 ID부터(처음부터는 0): ")) || 1;
	
	const rl = readline.createInterface({
		input: process.stdin,
		output: process.stdout
	});
	
	rl.question("\n제외할 사용자 이름(없으면 빈칸): ", (answer) => {
		excludedUser = answer.toLowerCase();
		
		rl.close();
		
		const rl2 = readline.createInterface({
			input: process.stdin,
			output: process.stdout
		});
		
		rl2.question("제외할 메시지 키워드(없으면 빈칸): ", (answer2) => {
			excludedKeyword = answer2.toLowerCase();
			
			rl2.close();

			print("\n내보내기를 시작합니다. 취소하려면 3초 이내에 <Ctrl+C>을 누르십시오.\n");
			print("       0         25        50        75        100 (%)");

			var sid = String(fromst) || '1';
			var bid = '0'; // 채널의 첫 메시지 ID
			var lid = '0'; // 채널의 가장 마지막 메시지 ID
			
			// 먼저 가장 최근 1개의 메시지를 가져와서 그것의 ID를 lid에 저장
			channel.fetchMessages({ limit: 1 }).then(async function(messages) {
				for(rmsg of messages) {
					const cm = rmsg[1];
					
					lid = String(cm['id']);
				}
				
				// 가장 첫 1개의 메시지를 가져와서 그것의 ID를 bid에 저장
				channel.fetchMessages({ limit: 1, after: '1' }).then(async function(messages) {
					if(fromst) {
						bid = String(fromst);
					} else {
						for(rmsg of messages) {
							const cm = rmsg[1];
							
							bid = String(cm['id']);
						}
					}
					
					const pb = new cliProgress.Bar({ // 진행율 표시기 생성
						barIncompleteChar: '_',
						barCompleteChar: '█',
						format: '처리중 [{bar}] ({percentage}%) {total} 중 {value} 완료'
					}, cliProgress.Presets.legacy);
					
					pb.start(Number(lid.slice(0, 7)) - Number(bid.slice(0, 7)), 0); // 진행율 표시기 시작
					
					// 이제 메시지들을 가장 오래된 것부터 가져온다.
					var msglst    = []; // 2차원 배열. 가져온 메시지들을 저장하고 나중에 화일로 저장하기.
					var save      = 0;
					var msgcount  = 0;
					var excmsgcnt = 0;
					
					function time(i) {
						// 메시지 개수 한계 지정. 높여도 됨. 너무 많이는 높이지 말 것.
						if(i <= 12345678) {
							setTimeout(async function() { // 3초마다 100개씩 가져오기. 한 번에 해 버리면 일시적 차단이 되므로 하지말것.
								const msgs = await channel.fetchMessages({ limit: 100, after: sid }); // .then()로 하면 구현이 불가하므로 이제는 비동기 await로.
								
								try {
									pb.update(Number(msgs.first()['id'].slice(0, 7)) - Number(bid.slice(0, 7))); // 진행율 증가
								} catch(e) {}
								
								for(var msg of msgs) {
									const cm = msg[1]; // 메시지 오브젝트
									
									if (
										(cm.content.toLowerCase().includes(excludedKeyword) && excludedKeyword != '') ||
										(cm.author.username.toLowerCase() == excludedUser && excludedUser != '')
									) {
										excmsgcnt++; continue;
									}
									
									// 유닉스 시각을 가져와서 일반 시간으로 변환
									var date = new Date(Number(cm['createdTimestamp']));

									var hour = date.getHours();
									hour = (hour < 10 ? "0" : "") + hour;

									var min  = date.getMinutes();
									min = (min < 10 ? "0" : "") + min;

									var sec  = date.getSeconds();
									sec = (sec < 10 ? "0" : "") + sec;

									var year = date.getFullYear();

									var month = date.getMonth() + 1;
									month = (month < 10 ? "0" : "") + month;

									var day  = date.getDate();
									day = (day < 10 ? "0" : "") + day;

									// 변환된 시간을 tsp에 저장
									const tsp = year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
									
									var atm = ''; // 첨부화일 URL 목록
									var rec = ''; // 반응 목록
									var rr  = '';
									
									for(var r of cm['reactions']) {
										if(emoji.hasEmoji(r[0])) {
											rec += emoji.find(r[0])['key'] + ' ';
										} else {
											rec += r[0] + ' ';
										}
										
										rr += r[0] + ' ';
									}
									
									for(var am of cm.attachments) {
										atm += ` [파일 ${am[1]['url']}]`; // attachments 콜랙션에서 하나씩 추가
									}
									
									// if(atm == '') atm = '-'; // 없으면 -로
									
									var msgcntnt = cm['content'];
									
									if(cm['embeds'].length && cm['author']['bot']) {
										msgcntnt = `[임베드] `;
										for(var embed of cm['embeds']) {
											msgcntnt += `${embed['title']}: ${embed['description']}   `;
										}
									}
									if(cm['system']) {
										switch(cm['type']) {
											case 'GUILD_MEMBER_JOIN':
												msgcntnt = '[시스템] 서버에 참가함.';
											break;case 'PINS_ADD':
												msgcntnt = '[시스템] 메시지를 고정함.';
											break;default:
												msgcntnt = '[시스템] 서버를 부스트했거나 채널 이름이나 아이콘을 변경, 혹은 통화를 시작함.';
										}
									}
									
									var raw = msgcntnt;
									
									// 이모티콘 변환(유니코드 안되는 윈도우 사용자 배려)
									if(!cm['embeds'].length && !cm['system'] && cm['content'].length >= 2) {
										for(var chr=0; chr<cm['content'].length-1; chr++) {
											const emj = String(cm['content'][chr]) + String(cm['content'][chr+1]);
											
											if(emoji.hasEmoji(emj) && emoji.find(emj)['key'] != emj) {
												msgcntnt = msgcntnt.replace(emj, ':' + emoji.find(emj)['key'] + ':')
											}
										}
									}
									
									var admin = 0;
									try {
									const roles = cm.member._roles;
									for(role of roles) {
										const trole = cm.guild.roles.find(r => r.id == role);
										const perms = trole.permissions;
										const { Permissions } = require('discord.js');
										const perm = new Permissions(perms);

										if(
											perm.has(['ADMINISTRATOR']) ||
											perm.has(['KICK_MEMBERS']) ||
											perm.has(['BAN_MEMBERS']) ||
											perm.has(['MANAGE_CHANNELS']) ||
											perm.has(['MANAGE_GUILD']) ||
											perm.has(['PRIORITY_SPEAKER']) ||
											perm.has(['MANAGE_MESSAGES']) ||
											perm.has(['MUTE_MEMBERS']) ||
											perm.has(['DEAFEN_MEMBERS']) ||
											perm.has(['MOVE_MEMBERS']) ||
											perm.has(['MANAGE_NICKNAMES']) ||
											perm.has(['MANAGE_ROLES']) ||
											perm.has(['MANAGE_ROLES_OR_PERMISSIONS']) ||
											perm.has(['MANAGE_WEBHOOKS']) ||
											perm.has(['MANAGE_EMOJIS']) ||
											
											cm.member.user.id == cm.guild.owner.user.id
										) {
											admin = 1;
										}
									}
									} catch(e) {}
									
									var io;
									try { io = cm.member.user.id == cm.guild.owner.user.id ? 1 : 0; } catch(e) { io = 0; }
									
									// msglst에 메시지 정보를 담은 배열 저장. [시간, 사용자ID, 사용자이름, 메시지ID, 메시지내용, 유닉스시간, 첨부화일 주소목록, 반응]
									msglst.push([tsp, cm['author']['id'], cm['author']['username'].replace(/["]/g, '""'), cm['id'], convertMention(msgcntnt).replace(/["]/g, '""').replace(/\r/g, ''), Number(cm['createdTimestamp']), atm, rec, cm['system'] ? 1 : 0, admin, io, rr, raw]);
									// msglst.push(`"(${cm['author']['id']})","${cm['author']['username'].replace(/["]/g, '""')}","(${cm['id']})","${cm['content'].replace(/["]/g, '""').replace(/\r/g, '')}"`);
									
									// sid = cm['id'];
									
									msgcount++;
								}
								
								// if(sid != '1') print(`(${sid} / ${lid})`); // sid와 lid 정보 표시
								// else print("처리 중입니다.\n");
								
								try {
									sid = msgs.first()['id']; // sid에 이번에 가져온 100개 메시지 중 가장 마지막 메시지 ID 저장
								} catch(e) { 
									save = 1;
								}
								
								if(Number(sid) > Number(lid) || save) { // 모든 메시지를 가져왔을 때 화일로 저장하기.
									pb.stop(); // 진행율 표시기 멈춤
									
									var ac = ''; // CSV 내용
									var ht = '';
									
									// 정렬
									print("\n\n시간 순으로 정렬하는 중입니다.\n");
									
									msglst.sort(function(l, r) {
										return l[5] - r[5]; // 5번지인 유닉스 시간을 비교
									});
									
									for(var it of msglst) {
										// ac에 CSV 행 추가
										ac += `"${it[0]}","'${it[5]}","'${it[1]}","${it[2]}","'${it[3]}","${it[4]}${it[6]}","${it[7]}"` + "\n";
									}
									
									var num = 1;
									
									for(var it of msglst) {
										html += `
											<div class=res-wrapper>
												<div class="res res-type-${it[8] ? 'status' : 'normal'}">
													<div class="r-head${it[10] ? ' first-author' : ''}">
														<span class=num>
															<a id=${num}>#${num++}</a>
														</span>
														<span style="${it[9] ? 'font-weight: bold;' : ''}">${it[2]}</span>
														
														<span class=pull-right>${it[0]}</span>
													</div>
													
													<div class=r-body>
														${it[12].replace(/\n/g, '<br />')}${it[6]}
													</div>
													
													<div class="combo admin-menu">${it[11]}</div>
												</div>
											</div>
										`;
									}
									
									html += '</div>';
									html += '<title>' + guild.name + ' - ' + channel.name + '</title>';
									
									// 화일로 저장
									if(fmt == 1 || fmt == 0) appendFile(fn, `"전송 시간","타임스탬프","사용자 번호","이름","메시지 번호","내용","반응"\n` + ac);
									if(fmt == 2 || fmt == 0) appendFile(fn + '.htm', html);
							
									print(`${excmsgcnt}개를 제외한 ${msgcount}개의 메시지가 ${fn}에 저장되었읍니다.`);
									print('창을 닫아도 좋습니다.');
									
									return;
								}
								
								// 다음 100개 메시지 가져오기
								time(i + 1);
							}, 1000); // 1500: 1.5초.(밀리초 단위) | 조금은 줄여도 되지만 봇이 차단될 경우 책임지지 않습니다.
						} else {
							// 한도 초과 시..
							
							print("메시지가 너무 많습니다. 메시지가 1,234,567,799통 이하인 채널만 내보낼 수 있읍니다.");
							
							return;
						}
					}
					
					time(1);
				}).catch(console.error);
			}).catch(console.error);
		});
	});
});

// 여기에 봇 토큰 입력. 실제계정 토큰으로 지정해서 벌어지는 일과 불이익에 대해서 책임지지 않습니다. 가능하면 봇 계정으로 할 것.
client.login("***************************************");

11. 디스코드 메시지 추출기 2[편집]

이건 액스피에서 실행 가능하지만 기능이 좀 떨어진다 독립실행형으로 모듈 설치 필요없음

const print = console.log;
const ln = () => process.stdout.write('\n');

const token = '토큰';
const readline = require('readline');
const fs = require('fs');
const http = require('https');

function request(path) {
    return new Promise((resolve, reject) => {
        http.request({
            host: 'discord.com',
            path: '/api/v8' + path,
            headers: {
                "Authorization": token,
                "User-Agent": 'Mozilla/5.0 (Windows NT 6.1; rv:83.0) Firefox/83.0'
            }
        }, function(res) {
            try {
                var ret = '';

                res.on('data', function(chunk) {
                    ret += chunk;
                });

                res.on('end', function() {
					var msg; ret = JSON.parse(ret);
					
					if(msg = ret.message) reject(msg);
                    else resolve(ret);
                });
            } catch(e) {
                reject(e);
            }
        }).end();
    });
}

const perms = {
	'관리자': 8,
	'관리 내역 보기': 128,
	'서버 인사이트 보기': 524288,
	'서버 관리자': 32,
	'권한 관리자': 268435456,
	'채널 관리자': 16,
	'추방': 2,
	'차단': 4,
	'초대': 1,
	'자신의 별명 변경': 67108864,
	'별명 관리자': 134217728,
	'그림 문자 관리자': 1073741824,
	'웹후크 관리자': 536870912,
	'메시지 읽기 & 음성 채널 보기': 1024,
	'메시지 보내기': 2048,
	'음성 메시지 보내기': 4096,
	'메시지 관리자': 8192,
	'링크 전송': 16384,
	'화일 첨부': 32768,
	'이전 메시지 보기': 65536,
	'모두 핑하기': 131072,
	'외부 그림문자 사용': 262144,
	'반응': 64,
	'음성 채널 접속': 1048576,
	'말하기': 2097152,
	'카메라 & 화면 공유': 512,
	'사용자 마이크 음소거': 4194304,
	'사용자 스피커 음소거': 8388608,
	'사용자 이동': 16777216,
	'음성 감지 사용': 33554432,
	'우선 발언자': 256
};

const hasPerm = (i, p) => (i & p) == p;

const rl = readline.createInterface(process.stdin, process.stdout);

var r, f;

rl.question('채널 ID: ', channel => {
	rl.close();
	
	var html = `
		<meta charset=utf-8 />
		
		<style>
			.res-wrapper .res .r-head {
				border-radius: 5px 5px 0 0;
				padding: 8px 10px 8px 10px;
				background: linear-gradient(rgb(226\, 237\, 254) 0%\, rgb(202\, 219\, 243) 51%\, rgb(161\, 191\, 229) 50%\, rgb(90\, 139\, 204) 100%);
				text-shadow: 1px 1px 0 #cecece;
			}
			
			.res-wrapper .res .r-body {
				padding: 8px 10px 8px 10px;
				background: linear-gradient(#eee\, #ccc);
				overflow-x: scroll;
			}
			
			.res-wrapper .res.res-type-status .r-body {
				background: linear-gradient(orange\, #ccc);
			}
			
			.res-wrapper .res .combo {
				border-radius: 0 0 5px 5px;
				padding: 8px 10px 8px 10px;
				background: linear-gradient(#777\, #333);
				color: white;
			}
			
			.res-wrapper {
				margin: 40px 0 40px 0;
			}
			
			.pull-right {
				float: right;
			}
		</style>
		
		<div id=res-container>
	`;
	
	var msgarr = [], arr = [];
	
	function parseDate(date) {
		var hour = date.getHours();
		hour = (hour < 10 ? "0" : "") + hour;

		var min  = date.getMinutes();
		min = (min < 10 ? "0" : "") + min;

		var sec  = date.getSeconds();
		sec = (sec < 10 ? "0" : "") + sec;

		var year = date.getFullYear();

		var month = date.getMonth() + 1;
		month = (month < 10 ? "0" : "") + month;

		var day  = date.getDate();
		day = (day < 10 ? "0" : "") + day;

		return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
	}
	
	print('추출 중...');
	
	(f = function(id) {
		request('/channels/' + channel + '/messages?limit=50' + (id ? ('&before=' + id) : '')).then(messages => { // 유저봇 의심 방지
			if(!messages.length) {  // 다 불러왔음
				print('추출 완료. 파싱 중...\n');
				
				var num = 0;
				
				arr.sort(function(l, r) {
					return Number(l.timestamp) - Number(r.timestamp);
				});
				
				print('정렬 완료.');
				
				for(msg of arr) {
					var re = '';
					for(r of msg.reactions) {
						re += r.emoji.name + ' ';
					}
					
					var cnt = msg.content.replace(/[&]/g, '&amp;').replace(/["]/g, '&quot;').replace(/[<]/g, '&lt;').replace(/[>]/g, '&gt;').replace(/\n/g, '<br />');
					if(msg.type == 'join') cnt = '서버에 참가함';
					if(msg.type == 'pin')  cnt = '메시지를 고정함';
					
					html += `
						<div class=res-wrapper>
							<div class="res res-type-${msg.type != 'normal' ? 'status' : 'normal'}">
								<div class=r-head>
									<span class=num>
										<a id=${++num}>#${num}</a>
									</span>
									
									${msg.username}
									
									<span class=pull-right>
										${parseDate(new Date(msg.timestamp))}
									</span>
								</div>
								
								<div class=r-body>
									${cnt}
								</div>
								
								<div class=combo>
									${re}
								</div>
							</div>
						</div>
					`;
				}
				
				print('HTML 생성 완료.');
				
				html += '</div>';
				html += '<title>' + channel + '</title>';
				
				fs.writeFileSync('./' + channel + '.htm', html);
				print('저장되었읍니다.');
				
				fs.writeFileSync('./' + channel + '.json', JSON.stringify(msgarr));  // parsemsg.js로 CSV로 변환할 때 필요
			}
			
			msgarr = msgarr.concat(messages);
			
			for(msg of messages) {
				arr.push({
					id: msg.id,
					timestamp: (new Date(msg.timestamp)).getTime(),
					edited_timestamp: (new Date(msg.edited_timestamp)).getTime(),
					username: msg.author.username + '#' + msg.author.discriminator,
					userid: msg.author.id,
					pinned: msg.pinnded,
					tts: msg.tts,
					attachments: msg.attachments,
					embeds: msg.embeds,
					content: msg.content,
					reactions: msg.reactions || [],
					type: msg.type == 7 ? 'join' : (msg.type == 6 ? 'pin' : 'normal')
				});
				
				print(msg.author.username + '> ' + msg.content);
			}
			
			setTimeout(() => {
				f(messages[messages.length - 1].id);
			}, Math.floor((Math.random() + 0.5) * 1000));
		});
	})();
});

12. 맞춤법 수정[편집]

const theseed = require('./theseed');
const client = theseed('alpha');

function print(prpt) {
	process.stdout.write(prpt + '\n');
}

client.on('ready', () => {
	client.login('gnote8_0', '777777777777').then(e => {
		(f = function() {
			client.random().then(doc => {
				console.log(doc);
				client.fetchRAW(doc).then(raw => {
					client.edit(doc, raw.replace(/[됬]/g, '됐').replace(/[되][서]/g, '돼서').replace(/VMWare/g, 'VMware'), '[자동 편집] 맞춤법 수정').then(d => {
						console.log(d); f();
					}).error(console.error);
				});
			});
		})();
	}).catch(console.error);
});

13. 사이트들[편집]

14. 할일[편집]

바나나 엔진에서
  • 수정 코멘트 뒷부분 (새 문서)를 코멘트 앞부분 [새 문서]로 변경
  • 토론 주시 및 알림
  • 자신의 편집요청 모음 페이지
  • 분류 페이지에 초성링크 분류 페이지 자체도 안 만들었다
  • 권한 부여 페이지에서 유저 이름 칸을 TEXTAREA로 바꿔서 각 줄에 여러 사용자 지정할 수 있게
  • 최근 변경에 다양한 필터(수정 코멘트, 변경점, ...)
  • 리비전 표기변경 => r<몇 번째로 생성된 문서인가?>[10].<그 리비전 번호>
  • 하위 위키
    • 조금만 더 추가하면 끝 귀찮다
    • 이동, 삭제, 역링크, 차단내역, 차단페이지
  • 차단 페이지에서 싸이더가 /32가 아닌 것을 반복문 없이 더 효율적으로 체크
    • fulliplist 열을 만들고 /32 대역 IP 목록을 ;로 구분해서 넣기
    • 맨 앞과 맨 뒤에도 세미콜론 있어야함
    • select ~ where fulliplist like '%;' || ? || ';%'라고 쓰고 물음표에 현재 아이피 주소 넘기기
  • 문법 메모장 기능 - IP는 쿠키, 계정은 서버에
    • 입력창에 노란색 그라데이션을 넣고 위에 스프링 이미지같은것도 넣기
    • 쿠키
      • notes 쿠키에 세미콜론이나 쉼표로 구분하여 메모 생성 순번 넣기
      • note_title_X(X는 숫자) 쿠키에 메모의 제목
      • note_content_X 쿠키에 메모의 위키문법을 URI 이스케이프 코드로 인코드하여 넣기
    • 실시간 최근변경 갱신 제대로 다시 만들기
  • 분류를 스택 오버플로우처럼 따로 입력창을 만들기
  • 토론 레스 모양을 사용자마다 변경할 수 있게 하기(플러그 인 기반)
  • 불러오기·저장 화면에서 간단하게 만화 영화 띄우기.
  • nunjucks나 swig로 틀 조건문 구현

병아리 엔진은 언제 만들지 빨리 끝내서 가지고 놀고 싶다

15. 무료 데이타·파티션 복구[편집]

하드 디스크는 복구가 되는데 SSD는 미확인

16. Windows Longhorn 설치 시 오류 발사해결하기[편집]

  • 하드가 준비되지 않았고 바이오스를 확인하라고 할 때
  • setup was unable to locate a locally attached hard drive suitable for holding temporary setup files
    • VM 설정에 들어가서 추가로 하드 디스크를 IDE 3GB로 만들기.

17. 틀:댓글[편집]

[고장] 1.1 1.2 [2] 배드섹타 13개[4] 새 주제 생성 탭에서 유형을 편집요청으로 바꾸기.[5] historyInit,discussPollCancel, discussPollStart, recaptchaInit, recaptchaExecute, recaptchaOnLoad 함수가 모두 존재할 경우[6] button#nfF**kingPJAX가 있으면 됨.[7] 이상하게 MSFN은 한국 IP로 접속되지 않는다. 한국 VPN도 불가하며 일본 VPN은 가능.[8] 주소 목록: [turbowiki.rf.gd, tbwiki.rf.gd, gnote8.rf.gd, gn8.pythonanywhere.com] [9] 이래야 RAM 12GB XP에서 윈도우 7 64비트 가상머신도 쾌적하게 돌아감.[10] 한 번 지워졌다 다시 만들어지면 2가 됨. 되돌리기는 해당없음.[매우위험] 모든 파티션과 데이타가 날아가므로 주의. 실수로 했으면 최대한 빨리 파티션 복구 프로그램으로 복구해야 한다. 새로 파티션을 만들고 파일을 저장하면 복구가 불가능해짐[12] 모든 명령어는 앞 3자리만 쓸 수 있는데 원래 assign임