ThinkJS 2.0 Documentation ᳪفள᭛ Օᕨ ጱ Node.js MVC ຝֵ҅አ ES7 Ӿ async/await ҅ᘏ ES6ݎෛقThinkJS ฎӞֵྃአ ES6/7 ᇙ තԧࢵٖक़ռग़ຝጱᦡᦇቘஷޕӾጱ */yield ᇙବᥴ٬ԧ Node.js Ӿྍ્ॺጱᳯ̶᷌ݶ ṛප̶̵ܔᓌےNode.js ᶱፓๅ ݎమ҅ᦏ පሲ҅ฎ۠ಅࣁ̶ଚӬෛᇇጱ Node.js ES6 ᇙԞํԧݎᶱፓݢզय़य़ṛݎአ ES6/7 ᇙֵ Զᇙᬮဌํඪ೮҅Ԟݢզۗ Babel ᖫᦲඪ೮̶ํֵܨঅጱඪ೮҅ ᇙ ᶱፓݎአ ES6/7 ᇙֵ ᇇӧඪ೮̶੦ٌฎֵڹۗ Babel ᖫᦲ҅ݢզࣁᶱፓӾय़ᙦֵአ ES6/7 ಅํጱᇙ҅෫ᵱஞߺԶᇙ୮ አ async/await ᘏ */yield ᥴ٬ྍࢧ᧣ጱᳯ̶᷌ JavaScript //user controller, home/controller/user.js export default class extends think.controller.base { //login action async loginAction(self){ //ইຎฎget᧗҅ፗളดᐏጭ୯ᶭᶎ if(this.isGet()){ return this.display(); } ᬯ᯾ݢզ᭗ᬦpostොဩ឴ݐಅํጱහഝ҅හഝ૪ᕪࣁlogic᯾؉ԧ໊ḵ// let data = this.post(); let md5 = think.md5('think_' + data.pwd); ᯈහഝପӾԭጱፓ܃ݸጱੂᎱ݄ੂےአಁݷ// let result = await this.model('user').where({name: data.name, pwd: md5}).find(); ձ֜හഝ҅ᤒᐏአಁݷᘏੂᎱᲙکᯈ܃ইຎ๚// if(think.isEmpty(result)){ return this.fail('login fail'); } sessionفٟ௳מݸ҅ਖ਼አಁ௳מአಁک឴ݐ// await this.session('userInfo', result); return this.success(); } } ӤᶎጱդᎱ౯ժֵአԧ ES6 ᯾ጱ class , export , let զ݊ ES7 ᯾ጱ async await ᒵᇙ҅ Session ᮷ฎྍ֢҅֕ۗ async/await ҅դᎱ᮷ฎݶྍԡٟጱ̶๋ݸֵ فᡱᆐັᧃහഝପٟ አ Babel ᬰᤈᖫᦲ҅੪ݢզᑞਧᬩᤈࣁ Node.js ጱሾहӾԧ̶ ඪ೮ग़ᐿᶱፓᕮग़ᐿᶱፓሾह ̶ݎཛྷࣘཛྷୗᒵग़ᐿᶱፓᕮ҅ݢզჿ᪃ݱᐿᶱፓ॔ଶጱړཛྷࣘཛྷୗ̵ฦ᭗ཛྷୗ̵ܔᶱፓඪ೮ ἕᦊඪ೮ development ҅ testing prodution 3 ᐿᶱፓሾह҅ݢզࣁӧݶጱᶱፓሾहӥᬰᤈӧݶ ጱᯈᗝ҅ჿ᪃ࣁӧݶሾहӥጱᯈᗝᵱ҅ݶᬮݢզचԭᶱፓᵱᥝᬰᤈಘ̶ ඪ೮ӿጱහഝପ ThinkJS ඪ೮ mysql ҅ mongodb ҅ sqlite ᒵଉᥠጱහഝପ҅ଚӬᤰԧஉग़֢හഝପጱളݗ҅෫ᵱ ᚆ̶ۑᘶཛྷࣳᒵṛᕆى̵ۓᄋ၏̶ݶඪ೮Ԫقᒵਞفಋۖ೪ള SQL ݙ҅ᬮݢզᛔۖᴠྊ SQL ဳ դᎱᛔۖๅෛ Ԟӧአۗᒫӣ҅ۓNode.js ๐ ސኞප҅ӧአ᯿ܨදݸᒈץկ҅ګThinkJS ٖᗝԧӞॺդᎱᛔۖๅෛጱ ොཛྷ̶ࣘ ୌ REST ളݗڠᛔۖ ইຎమࣁ̶ݎݢਠ౮ REST API ጱܨୌ REST ളݗ҅ӧአٟձ֜ጱդᎱڠአ thinkjs եݢզᛔֵۖ REST ളݗӾᬦᄁਁྦྷᘏᬰᤈᴴ໊ḵ҅Ԟஉො॒ቘ̶ ඪ೮ग़ᐿ WebSocket ପ ThinkJS ඪ೮ socket.io ҅ sockjs ᒵଉᥠጱ WebSocket ପ҅ଚӬᬯԶପᬰᤈ۱ᤰ҅ಾଘݱӻପԏᳵ ᘏӞᛘጱ֛ḵ̶ݎളݗ᧣አӤጱ૧҅ᕳ ӿጱၥᦶአֺ ᚆۑᵑຝכද᮷ํଫጱၥᦶአֺץӞེྯ҅ %95 کጱၥᦶአֺ҅դᎱᥟፍሲᬡ +1500 ํތ ThinkJS ጱᑞਧ̶ ۓඪ೮եᤈ᧣አಗᤈਧձ ੪ݢզஉොګThinkJS ᯾ጱ Action ᴻԧݢզߥଫአಁጱ᧗҅ݶඪ೮ࣁեᤈӥᦢᳯ҅ۗᬯॺ ̶ۓጱಗᤈਧձ Hook Middleware ݢզᅎၚጱᦢᳯ᧗ᬰᤈೝ౼॒ቘ̶҅ګThinkJS ֵአ Hook Middleware ᧇᕡጱ෭ப ᚆ҅ݢզஉොጱັ፡ݱᐿ෭ப҅ො᭄ັᳯ̶᷌ۑThinkJS ٖᗝԧᧇᕡጱ෭ப HTTP ᧗෭ப [2015-10-12 14:10:03] [HTTP] GET /favicon.ico 200 5ms [2015-10-12 14:10:11] [HTTP] GET /zh-CN/doc.html 200 11ms [2015-10-12 14:10:11] [HTTP] GET /static/css/reset.css 200 3ms Socket ᬳള෭ப [2015-10-12 14:13:54] [SOCKET] Connect mysql with mysql://root:[email protected]:3306 Კ෭ப [2015-10-12 14:15:32] [Error] Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'root3'@'localhost' (using password: YES) [2015-10-12 14:16:12] [Error] Error: Address already in use, port:8360. http://www.thinkjs.org/doc/error.html#EADDRINUSE ګӿጱ᪠ኧ ےଚӬݢզचԭཛྷࣘᦡᗝ̶ݢզᦏ URL ๅ҅ګ᪠ኧ̵ᶉா᪠ኧᒵग़ᐿ᪠ኧڞ᪠ኧ̵ᥢڞThinkJS ඪ೮ྋ ᓌ၄ጱݶ݈ӧӶ०ᚆ̶ ඪ೮ࢵᴬ۸ग़Ԇ᷌ ᚆ̶ۑጱොဩ੪ݢզඪ೮ࢵᴬ۸ग़Ԇ᷌ᒵܔThinkJS ֵአஉᓌ Өٌ՜ຝጱྲ Ө express/koa ྲ ᶱፓӾᵱᥝۗय़ᰁጱᒫӣොൊկ҅ܔᚆྲᓌۑጱ׀ጱຝ҅ຝܔexpress/koa ฎ 2 ӻྲᓌ ಅզᅎၚଶྲṛ̶ֵ֕አஉग़ᒫӣොᕟկӞොᶎṛԧᶱፓጱ॔ଶ҅ݚӞොᶎᒫӣ҅ݎᚆਠ౮ᶱፓጱ ොൊկᨶᰁ݇૧ӧἶ҅Ԟտଃٖਂအᄋᒵᷚᴾ̶ koa 1.x ֵአ ES6 ᯾ጱ */yield ᥴ٬ԧྍࢧ᧣ጱᳯ᷌҅֕ */yield ݝտฎӻᬦჁᥴ٬ොໜ҅տᤩ ES7 ᯾ጱ async/await ಅ๊դ̶ ᚆ᮷ᕪᬦԧӸ໒ጱᚆٖਂအᄋᒵොᶎጱၥᦶ҅ଚӬࣁᶱፓӾݢۑԧෆॺᥴ٬ොໜ҅ྯӻ׀ᘒ ThinkJS զፗളֵአ ES6/7 ಅํጱᇙ̶ Ө sails ྲ ොᶎԞஉग़ᤰֵ҅አ᩸قෆॺᥴ٬ොໜጱ Node.js ຝ҅හഝପ̵REST API̵ਞ׀sails ԞฎӞӻ ො̶ྲ ଃஉय़ጱӧ҅ᛘᶱፓӾ෫ݎsails ྍࢧ᧣ጱᳯ᷌ᬮဌํս۸҅ᬮฎֵአ callback ጱොୗ҅ᕳ ֕ ဩঅጱֵአ ES6/7 ᇙ̶ ThinkJS ጱӧ᪃ Ӥᶎ᧔ԧஉग़ ThinkJS ጱսᅩ҅୮ᆐ ThinkJS Ԟํஉग़ጱӧ᪃̶ইғ ຝᬮྲෛ҅ᗌᐒ܄ᒵොᶎጱඪ೮ ᬮဌํᕪᬦ᩻य़ࣳᶱፓጱ༄ḵ ES6/7 ݇ᘍ ԭ ES6/7 ᇙݢզ݇ᘍӥᶎጱғى JavaScript Promiseᭁ֦ԡ learn-es2015 ᳪف ECMAScript 6 ஞᘏጱ ES2015 ਫڡ ᕳ JavaScript ECMAScript 6 Features ECMAScript 6 compatibility table ECMAScript 7 Features ECMAScript 7 compatibility table ୌᶱፓڠ ਞᤰ Node.js ਞᤰ Node.js ሾह҅ݢզ݄ ਥො ӥضᵱᥝ҅ڹThinkJS ฎӞྃ Node.js ጱ MVC ຝ҅ಅզਞᤰ ThinkJS ԏ ๋ෛጱਞᤰ۱ᬰᤈਞᤰ҅Ԟݢզ᭗ᬦٌ՜ӞԶჀ᭲ਞᤰ̶ ̶ۑᤒᐏਞᤰ౮ڞ҅ڊଫጱᇇݩᬌکਞᤰਠ౮ݸ҅ࣁեᤈಗᤈ node -v ҅ইຎᚆ፡ ๐ۖސ෫ဩڞވᕆ Node.js҅܋ThinkJS ᵱᥝ Node.js ጱᇇ >=0.12.0 ҅ইຎᇇੜԭᬯӻᇇ҅ᵱᥝ ๅṛᇇ̶ 4.2.1 کᕆ܋ୌᦓਖ਼ Node.js ᇇ̶ۓ ਞᤰ ThinkJS ݢਞᤰ ThinkJSғܨ᭗ᬦӥᶎጱե Bash npm install thinkjs@2 -g --verbose ইຎਞᤰஉౌጱᦾ҅ݢզᦶֵአ taobao ጱრᬰᤈਞᤰ̶ٍ֛ইӥғ Bash npm install thinkjs@2 -g --registry=https://registry.npm.taobao.org --verbose ਞᤰਠ౮ݸ҅ݢզ᭗ᬦ thinkjs --version thinkjs -V եັ፡ਞᤰጱᇇ̶ ᴻധ҅ݢզ᭗ᬦڢጱᇇڹਞᤰᬦ ThinkJS 1.x ጱᇇ҅ݢᚆᵱᥝਖ਼ԏڹဳ ғইຎԏ ᴻ̶ڢnpm uninstall -g thinkjs-cmd ե ๅෛ ThinkJS ੴጱ ThinkJSقๅෛ ੴጱ ThinkJSғقݢๅෛܨಗᤈӥᶎጱե Bash npm install -g thinkjs@2 ๅෛᶱፓ᯾ጱ ThinkJS ᶱፓጱ ThinkJSғڹݢๅෛ୮ܨࣁᶱፓፓ୯ӥ҅ಗᤈӥᶎጱե Bash npm install thinkjs@2 ୌᶱፓڠ :ୌᶱፓڠThinkJS ਞᤰਠ౮ݸ҅੪ݢզ᭗ᬦӥᶎጱե Bash thinkjs new project_path; #project_pathԅᶱፓਂනጱፓ୯ ୌӞӻ ES6 ཛྷୗጱᶱፓٍ֛҅ইӥғڠᶱፓጱᦾ҅ݢզݎইຎమአ ES6 ᇙ Bash thinkjs new project_path --es6; #project_pathԅᶱፓਂනጱፓ୯ ԧғۑୌ౮ڠᤒᐏᶱፓ҅ڊইຎᚆ፡ᥠᔄ֒ӥᶎጱᬌ create : demo/ create : demo/package.json create : demo/.thinkjsrc create : demo/nginx.conf create : demo/README.md create : demo/www/ create : demo/www/index.js create : demo/app create : demo/app/common/runtime create : demo/app/common/config create : demo/app/common/config/config.js create : demo/app/common/config/view.js create : demo/app/common/config/db.js ... create : demo/app/home/logic create : demo/app/home/logic/index.js create : demo/app/home/view create : demo/app/home/view/index_index.html enter path: $ cd demo/ install dependencies: $ npm install run the app: $ npm start ᚆ -> ThinkJS ե̶ۑ᧗ᥠ ಘ҅௳מୌᶱፓեጱๅग़ڠԭى ਞᤰׁᩢ ᶱፓፓ୯҅ಗᤈ npm install ਞᤰׁᩢ҅ݢզֵአ taobao რᬰᤈਞᤰ̶فᶱፓਞᤰݸ҅ᬰ Bash npm install --registry=https://registry.npm.taobao.org --verbose ᖫᦲᶱፓ ࣁᶱፓӥಗᤈեضӤԧ --es6 ݇හ҅դᎱᵱᥝᖫᦲݸᚆᬩᤈ̶ᮎԍᵱᥝےୌᶱፓڠইຎ දݸ੪տᛔۖᖫᦲԧ̶ץnpm run watch-compile ҅ᬯկํ ಗᤈեݸտ೯᩸Ӟӻᬰᑕ҅ဳӧᥝᕮᬯӻᬰᑕٌ҅՜եݢզٚෛӞӻຽᓋᶭ᯾ಗᤈ̶ ݢ̶ইຎฎᘌᶱፓݢܨۓ๐ۖސᚆ҅෫ᵱٚಗᤈᧆե҅ፗളۑဳ ғ 2.0.6 ᇇতٖᗝԧᛔۖᖫᦲጱ ݢҁනܨ ;()դᎱ instance.compileفے ෛᇇ҅ᆐݸࣁկ www/index.js๋کᕆ܋ զਖ਼ ThinkJS ҂̶ڹࣁ instance.run() ԏ ᶱፓۖސ ̶ۑ౮ۖސۓᔄ֒ӥᶎጱٖ҅ᤒᐏ๐کࣁᶱፓፓ୯ӥಗᤈե npm start ҅ইຎᚆ፡ [2015-09-21 20:21:09] [THINK] Server running at http://127.0.0.1:8360/ [2015-09-21 20:21:09] [THINK] ThinkJS Version: 2.0.0 [2015-09-21 20:21:09] [THINK] Cluster Status: closed [2015-09-21 20:21:09] [THINK] WebSocket Status: closed [2015-09-21 20:21:09] [THINK] File Auto Reload: true [2015-09-21 20:21:09] [THINK] App Enviroment: development ᦢᳯᶱፓ ݢ̶ܨ /ၨᥦ҅ᦢᳯ http://127.0.0.1:8360 ᦤ 8360 ᒒݗݢᦢᳯ̶כইຎฎࣁᬱᑕ҅ᵱᥝ᭗ᬦᬱᑕጱ IP ᦢᳯ҅ݶᥝ ᶱፓᕮ ୌਠᶱፓݸ҅ᶱፓፓ୯ᕮᔄ֒ইӥғڠ᭗ᬦ thinkjs ե |-- nginx.conf |-- package.json |-- src | |-- common | | |-- bootstrap | | | |-- generate_icon.js | | | `-- middleware.js | | |-- config | | | |-- config.js | | | |-- env | | | | |-- development.js | | | | `-- production.js | | | |-- hook.js | | | |-- locale | | | | |-- en.js | | | | `-- zh-CN.js | | | `-- route.js | | |-- controller | | | `-- error.js | | `-- runtime | `-- home | |-- config | |-- controller | | |-- base.js | | `-- index.js | |-- logic | | `-- doc.js | `-- model |-- view | `-- zh-CN | |-- common | | |-- error_400.html | | |-- error_403.html | | |-- error_404.html | | |-- error_500.html | | `-- error_503.html | `-- home | |-- doc_index.html | |-- doc_search.html | |-- inc | | |-- footer.html | | `-- header.html | |-- index_changelog.html | |-- index_demo.html | `-- index_index.html `-- www |-- favicon.ico |-- index.js |-- production.js `-- static |-- css |-- img `-- js ֛ฎᔄ֒ጱ̶֕҅ڦୌጱᶱፓፓ୯ݢᚆํᕡஙጱ૧ڠဳ ғਧӧݶጱཛྷୗ nginx.conf ݻդቘ̶ݍnginx ጱᯈᗝկ҅ୌᦓᕚӤֵአ nginx ؉ src کտᛔۖਖ਼ src ፓ୯ӥጱկᖫᦲۖސୌᶱፓํᧆፓ୯̶ᶱፓڠრդᎱፓ୯ֵ҅አ --es6 ݇හ app ፓ୯ӥ̶ ፗളํ app/ ፓ୯̶ڞୌᶱፓ҅ڠইຎဌํֵአ ES6 ᇙ src/common ጱ҅ common ཛྷࣘӥਂනӞԶ᭗አጱ॒ቘ᭦ᬋ̶ړښ᭗አཛྷࣘፓ୯҅ᶱፓፓ୯᮷ฎೲཛྷࣘ src/common/bootstrap ̶ ҅෫ᵱಋۖ requireےፓ୯҅ᧆፓ୯ӥጱկտᛔۖۖސᶱፓ ᚆ̶ۑහ̵ဳٙӾᳵկᒵଉአጱڍੴقݢզࣁᬯӻፓ୯ӥկ᯾ਧԎӞԶ හڍੴقਧԎ JavaScript // src/common/bootstrap/fn.js global.formatDate = obj => { ... } හ̶ڍහ formatDate ҅ᮎԍᶱፓ᯾ձ֜ࣈො᮷ݢզፗളֵአᧆڍੴقᬯ᯾ਧԎԧӞӻ ဳٙӾᳵկ JavaScript // src/common/bootstrap/middleware.js think.middleware('replace_image', http => { ... }); ᬯ᯾ਧԎԧӞӻӾᳵկ replace_image ҅ᮎԍ੪ݢզࣁᯈᗝկ hook.js ᯾ਖ਼ᧆӾᳵկဳٙᬰ݄ԧ̶ ဳ ғbootstrap ݝᚆනࣁ common ཛྷࣘ᯾̶ src/common/config ᯈᗝկ҅ᬯ᯾නӞԶ᭗አጱᯈᗝ̶ Ӿғ᪠ኧᯈᗝ̵hook ᯈᗝ̵ࣈ۸ᯈᗝᒵᶳනࣁᬯ᯾̶ٌ JavaScript 'use strict'; /** * config */ export default { //key: value }; src/common/controller ද̶ץ̶ٌӾ error.js ᯾Კ॒ቘጱӧݶᤈԅ҅ᶱፓ᯾ݢզ໑ഝᵱᥝᬰᤈګ҅නӞԶ᭗አጱഴګഴ src/common/runtime ᶱፓᬩᤈኞ౮ጱӞԶፓ୯҅ইғᖨਂկፓ୯҅አಁӤփጱկԁਂනጱፓ୯̶ src/home දᯈᗝ default_moduleץhome ཛྷࣘ҅ᶱፓἕᦊཛྷ̶ࣘݢզࣁ src/common/config/config.js Ӿ ᯿ෛਧԎἕᦊཛྷ̶ࣘ src/home/logic አڹྋଉ̵୮ވݳဩ̵Իጱහഝฎވғ݇හฎތᬰᤈ᭦ᬋ໊ḵ҅ݢզ۱ضݢզڹ᭦ᬋ॒ቘ̶ྯӻ֢ಗᤈ ᴴᒵ̶ᬯݢզᴳ֗ controller ᯾ጱ action ጱ॔ଶ̶ํވአಁฎڹ૪ᕪጭ୯̵୮ވಁฎ JavaScript 'use strict'; /** * logic * @param {} [] * @return {} [] */ export default class extends think.logic.base { /** * index action logic * @return {} [] */ indexAction(){ } } src/home/controller ̶ ̶Ӟӻ url ଫӞӻ controller ӥጱ actionګഴ JavaScript 'use strict'; import Base from './base.js'; export default class extends Base { /** * index action * @return {Promise} [] */ indexAction(){ //auto render template file index_index.html return this.display(); } } src/home/model ̶֢ىཛྷ̶ࣳහഝପፘ view ᥤࢶፓ୯҅ਂනଫጱཛྷᇇկ̶ইຎඪ೮ࢵᴬ۸ग़Ԇ᷌҅ᮎԍᥤࢶፓ୯ӥᵱᥝํଫጱৼፓ୯̶ www ྌፓ୯ӥ̶کᶱፓጱݢᦢᳯ໑ፓ୯҅nginx ᯾ጱ໑ፓ୯տᯈᗝ www/development.js ݗկ̶فද̶ www/production.js ԅᕚӤጱץݗկ҅ݢզ໑ഝᶱፓᵱᥝᬰᤈفཛྷୗӥᶱፓጱݎ ද̶ץݗկጱդᎱᔄ֒ইӥ҅ݢզ໑ഝᶱፓᵱᥝᬰᤈف JavaScript var thinkjs = require('thinkjs'); var path = require('path'); var rootPath = path.dirname(__dirname); var instance = new thinkjs({ APP_PATH: rootPath + '/app', ROOT_PATH: rootPath, RESOURCE_PATH: __dirname, env: 'development' }); instance.compile({retainLines: true, log: true}); instance.run(); www/static ਂනӞԶᶉாᩒრկ̶ դᎱᥢ կ᪠ஆᶳੜٟ ᶱፓ҅֕Ӟᛱ᮷᮱ᗟ Linux ᔮᕹӥ̶ݎฎࣁ Windows ᘏ Mac OSX ᔮᕹӥײஉग़ य़ੜٟጱ̶ᬯஉฃړ܄य़ੜٟጱ҅ᘒ Linux ӥฎړ܄ࣁ Windows Mac ᔮᕹӥ҅կ᪠ஆฎӧ ಸᲙԧ̶ܩሾहӥฎঅጱ҅֕Ӥᕚݸݎሿկय़ੜٟጱᳯ᷌ᛘڊ ҅ThinkJS տ༄ၥᶱፓӥկۖސۓኞ҅կ᪠ஆੱᰁ᮷ֵአੜٟਁᒧ̶ଚӬࣁ๐ݎጱ٭ᬯᐿఘعԅԧ ᦄ҅ইғޞտڞ᪠ஆ҅ইຎํय़ٟਁྮ [2015-10-13 10:36:59] [WARNING] filepath `admin/controller/apiBase.js` has uppercases. ᖽᬰֵአ 2 ӻᑮ໒ դᎱےෙ҅ᘏํӞԶྍ֢҅ᬯԶ᮷տीڣ᭦ᬋྲ॔҅ํݱᐿկײํ҅ݎࣁ Node.js ሾहӥ ጱᖽᬰ̶ ୌᦓֵአ 2 ӻᑮ໒֢ԅᖽᬰ̶਼҅ڜአԧॡग़ጱܛԅԧӧᛗԭᦏᖽᬰ ݎአ ES6 ဩֵ ᓌ၄ṛප̶ےES6 Ӿํय़ᰁጱဩᔥݢզᓌ۸౯ժጱդᎱ҅ᦏդᎱๅ Զဩӧඪ೮҅Ԟݢզ᭗ᬦ Babel ᖫᦲඪ೮̶ ಅํֵܨNode.js ๋ෛᇇ૪ᕪঅጱඪ೮ԧ ES6 ጱဩ҅ ᶱፓԧ̶ݎአ ES6 ဩֵײզฎ ӧᥝֵአ constrcutor ොဩ ᛔۖ᧣አ̶ইғײᔄਫֺ۸ጱکݢզֵአ constrcutor ොဩᬡ҅ײୌᔄጱڠአ ES6 ᯾ጱ class ֵ JavaScript export
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages238 Page
-
File Size-