Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScriptCore.frameworkでできること

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 JavaScriptCore.frameworkでできること

JavaScriptCore.frameworkの解説と、できることの限界を探ります。

Avatar for Kishikawa Katsumi

Kishikawa Katsumi

February 02, 2014
Tweet

More Decks by Kishikawa Katsumi

Other Decks in Programming

Transcript

  1. ! JSContext *context = [[JSContext alloc] init]; ! JSValue *result

    = [context evaluateScript:@"2 + 8"]; NSLog(@"%d", result.toInt32);
  2. JSContext *context = [[JSContext alloc] init]; ! context[@"factorial"] = ^(int

    x) { int factorial = 1; for (; x > 1; x--) { factorial *= x; } return factorial; }; ! JSValue *result = [context evaluateScript:@"factorial(5);"]; NSLog(@"%d", result.toInt32);
  3. JSContext *context = [[JSContext alloc] init]; ! context[@"factorial"] = ^(int

    x) { int factorial = 1; for (; x > 1; x--) { factorial *= x; } return factorial; }; ! JSValue *function = context[@“factorial"]; ! JSValue *result = [function callWithArguments:@[@(5)]]; NSLog(@"%d", result.toInt32);
  4. JSContext *context = [[JSContext alloc] init]; [context evaluateScript: @"function sum(a,

    b) { return a + b; }" ]; ! JSValue *function = context[@“sum"]; ! JSValue *result = [function callWithArguments:@[@(2), @(3)]] NSLog(@"%d", result.toInt32);
  5. w ͸ͯͳه๏1BSTFS  UFYUIBUFOBKT  IUUQUFDIOJUPZPODPNKBWBTDSJQUBQQMJDBUJPOUFYUIBUFOBEPXOMPBEIUNM w 5FYUJMF1BSTFS  UFYUJMFKT

     IUUQTHJUIVCDPNCPSHBSUFYUJMFKT w +40/ͷѹॖ  +40/)  IUUQTHJUIVCDPN8FC3FqFDUJPO+40/) +BWB4DSJQUͰॻ͔ΕͨϥΠϒϥϦΛ࢖͏
  6. NSBundle *bundle = [NSBundle mainBundle]; NSString *path = [bundle pathForResource:@"text-hatena"

    ofType:@"js"]; NSString *script = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; ! JSContext *context = [[JSContext alloc] init]; [context evaluateScript:script]; [context evaluateScript:@"var parser = new TextHatena();"]; ! JSValue *parser = context[@"parser"]; ! NSString *text = [NSString stringWithContentsOfFile: [bundle pathForResource:@“sample” ofType:@“txt"] encoding:NSUTF8StringEncoding error:nil]; ! NSLog(@"%@", [parser invokeMethod:@"parse" withArguments:@[text]]); ! return YES;
  7. *1384756611*[Objective-C][iOS]iOSΞϓϦέʔγϣϯͰΩʔϘʔυγϣʔτΧοτʹରԠ͢Δ ↓ ΑΓஸೡͳهࣄ͸ͪ͜ΒͰެ։͍ͯ͠·͢ɻ - [http://mobiletou.ch/2013/11/ ios%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E5%A4%96%E9%83%A8%E3%82%AD%E3%83%BC%E3%83%9C%E3 %83%BC%E3%83%89%E3%81%8B%E3%82%89%E3%81%AE%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB %E3%83%83%E3%83%88:title=iOSΞϓϦͰ֎෦ΩʔϘʔυ͔ΒͷγϣʔτΧοτʹରԠ͢Δํ๏ - iOSΞϓϦ։

    ൃ͜΅Ε࿩] ! ! iOS 7ͷSafari΍ϝʔϧͰ͸֎෦ΩʔϘʔυΛ࢖༻ͨ͠ࡍʹར༻Ͱ͖ΔͰ͖ΔγϣʔτΧοτ͕[http:// www.appbank.net/2013/11/08/iphone-news/696998.php:title=ҎલΑΓॆ࣮ͨ͜͠ͱ͕࿩୊ʹͳΓ·͠ ͨɻ] ! ! iOS 7Ͱ͸ΩʔϘʔυγϣʔτΧοτΛ࣮૷͢ΔͨΊͷAPI͕௥Ճ͞Ε͍ͯΔͷͰɺαʔυύʔςΟͷΞϓϦέʔγϣ ϯ΋ΩʔϘʔυγϣʔτΧοτʹରԠ͢Δ͜ͱ͕Ͱ͖·͢ɻ ! ! ಛఆͷΩʔϘʔυγϣʔτΧοτʹԠ౴͢Δʹ͸ԼهͷϓϩύςΟΛ࣮૷͠·͢ɻ >|objc| @property(nonatomic, readonly) NSArray *keyCommands ||<
  8. <div class="section"> <h3><a href="#1384756611" name="1384756611"><span class="sanchor">o-</span></a> [<a class="sectioncategory" href="searchdiary?word=*[Objective-C]">Objective-C</a>][<a class="sectioncategory"

    href="searchdiary?word=*[iOS]">iOS</a>]iOSΞϓϦέʔγϣϯͰΩʔϘʔυγϣʔτ ΧοτʹରԠ͢Δ</h3> <p>↓ ΑΓஸೡͳهࣄ͸ͪ͜ΒͰެ։͍ͯ͠·͢ɻ</p> <ul> <li> [http://mobiletou.ch/2013/11/ ios%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E5%A4%96%E9%83%A8%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%8 3%89%E3%81%8B%E3%82%89%E3%81%AE%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88:tit le=iOSΞϓϦͰ֎෦ΩʔϘʔυ͔ΒͷγϣʔτΧοτʹରԠ͢Δํ๏ - iOSΞϓϦ։ൃ͜΅Ε࿩]</li> </ul> <br> <p>iOS 7ͷSafari΍ϝʔϧͰ͸֎෦ΩʔϘʔυΛ࢖༻ͨ͠ࡍʹར༻Ͱ͖ΔͰ͖ΔγϣʔτΧοτ͕[http:// www.appbank.net/2013/11/08/iphone-news/696998.php:title=ҎલΑΓॆ࣮ͨ͜͠ͱ͕࿩୊ʹͳΓ·ͨ͠ɻ]</p> <br> <p>iOS 7Ͱ͸ΩʔϘʔυγϣʔτΧοτΛ࣮૷͢ΔͨΊͷAPI͕௥Ճ͞Ε͍ͯΔͷͰɺαʔυύʔςΟͷΞϓϦέʔγϣϯ΋ ΩʔϘʔυγϣʔτΧοτʹରԠ͢Δ͜ͱ͕Ͱ͖·͢ɻ</p> <br> <p>ಛఆͷΩʔϘʔυγϣʔτΧοτʹԠ౴͢Δʹ͸ԼهͷϓϩύςΟΛ࣮૷͠·͢ɻ</p> <pre class="syntax-highlight prettyprint lang-objc"> @property(nonatomic, readonly) NSArray *keyCommands </pre>
  9. NSBundle *bundle = [NSBundle mainBundle]; NSString *path = [bundle pathForResource:@"textile"

    ofType:@"js"]; NSString *script = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; ! JSContext *context = [[JSContext alloc] init]; [context evaluateScript:script]; ! JSValue *func = context[@"textile"]; ! NSString *text = [NSString stringWithContentsOfFile: [bundle pathForResource:@"sample" ofType:@“textile"] encoding:NSUTF8StringEncoding error:nil]; ! NSLog(@"%@", [func callWithArguments:@[text]]);
  10. ࠓճ͸ɺεϖγϟϧηογϣϯͱͯ͠Evernoteຊ͔ࣾΒMac൛EvernoteͷUIͷϦχϡʔΞϧͷࢦشΛ͞ Ε·ͨ͠["Jack Hirsch":https://twitter.com/Jackolicious]͞Μʹ͖͍͖ͯͨͩɺഎܠ΍։ ൃख๏ͳͲΛ͓࿩͍͖ͨͩ·͢ɻ ͢΂ͯͷ։ൃऀʹͱͬͯඇৗʹ༗ҙٛͳ࣌ؒʹͳΔͱࢥ͍·͢ͷͰͥͻ͓ӽ͍ͩ͘͠͞ɻ ! ! h3. ελοϑืू !

    ౰೔ɺձ৔ͷ४උ΍ड෇ͳͲΛख఻ͬͯͩ͘͞Δ͔ͨΛืू͍ͨ͠·͢ɻख఻ͬͯ΋͍͍Αɺͱ͍͏͔ͨ ͕͍Βͬ͠Ό͍·ͨ͠Β͝࿈བྷ͍ͩ͘͞·ͤɻ ! ["lesamoureuses":https://twitter.com/lesamoureuses] ["huin":https://twitter.com/huin] ["myb":https://twitter.com/myb] ["nun_":https://twitter.com/nun_] ["KohsakuNishida":https://twitter.com/KohsakuNishida] ["৿ౢେथ":https://www.facebook.com/hiroki.with.omnia] ! ! *։৔ 12:30* **৔ॴ** גࣜձࣾVOYAGE GROUP (౦ژ౎ौ୩۠ਆઘொ8-16 ौ୩ϑΝʔετϓϨΠε8F)
  11. <p>ࠓճ͸ɺεϖγϟϧηογϣϯͱͯ͠Evernoteຊ͔ࣾΒMac൛EvernoteͷUIͷϦχϡʔΞ ϧͷࢦشΛ͞Ε·ͨ͠<a href="https://twitter.com/Jackolicious">Jack Hirsch</a>͞Μʹ͖͍͖ͯͨͩɺഎܠ΍։ൃख๏ͳͲΛ͓࿩͍͖ͨͩ·͢ɻ<br /> ͢΂ͯͷ։ൃऀʹͱͬͯඇৗʹ༗ҙٛͳ࣌ؒʹͳΔͱࢥ͍·͢ͷͰͥͻ͓ӽ͍ͩ͘͠͞ɻ</p> <h3>ελοϑืू</h3> <p>౰೔ɺձ৔ͷ४උ΍ड෇ͳͲΛख఻ͬͯͩ͘͞Δ͔ͨΛืू͍ͨ͠·͢ɻख఻ͬͯ΋͍͍ Αɺͱ͍͏͔͕͍ͨΒͬ͠Ό͍·ͨ͠Β͝࿈བྷ͍ͩ͘͞·ͤɻ</p> <p><a

    href="https://twitter.com/lesamoureuses">lesamoureuses</a><br /> <a href="https://twitter.com/huin">huin</a><br /> <a href="https://twitter.com/myb">myb</a><br /> <a href="https://twitter.com/nun_">nun_</a><br /> <a href="https://twitter.com/KohsakuNishida">KohsakuNishida</a><br /> <a href="https://www.facebook.com/hiroki.with.omnia">৿ౢେथ</a> </p> <p><strong>։৔ 12:30</strong><br /> <b>৔ॴ</b><br /> גࣜձࣾ<span class="caps">VOYAGE</span> <span class="caps">GROUP</ span><br /> (౦ژ౎ौ୩۠ਆઘொ8-16 ौ୩ϑΝʔετϓϨΠε8F)</p>
  12. @protocol JSUIWindow <JSExport> ! @property (nonatomic) CGRect frame; @property (nonatomic)

    UIColor *backgroundColor; ! + (id)new; - (void)makeKeyAndVisible; ! @end
  13. JSContext *context = [[JSContext alloc] init]; context[@"JSUIWindow"] = [JSUIWindow class];

    JSContext *context = [[JSContext alloc] init]; context[@"JSUIWindow"] = [JSUIWindow class]; ! [context evaluateScript:@"var window = JSUIWindow.new();"]; ! JSValue *value = context[@"window"]; NSLog(@"%@", value.toObject);
  14. ! class_addProtocol([UIWindow class], @protocol(JSUIWindow)); JSContext *context = [[JSContext alloc] init];

    context[@"UIWindow"] = [UIWindow class]; [context evaluateScript:@"var window = UIWindow.new();"]; ! JSValue *value = context[@"window"]; NSLog(@"%@", value.toObject);
  15. static void setup(JSContext *context) { const char *prefix = "JSUI";

    unsigned int numberOfClasses; Class *classes = objc_copyClassList(&numberOfClasses); for (unsigned int i = 0; i < numberOfClasses; i++) { Class cls = classes[i]; const char *className = class_getName(cls); NSString *name = @(className); char protocolName[512]; snprintf(protocolName, sizeof(protocolName), "%s%s", prefix, className); Protocol *proto = objc_allocateProtocol(protocolName); traverce_class(proto, cls); protocol_addProtocol(proto, @protocol(JSExport)); objc_registerProtocol(proto); class_addProtocol(cls, proto); context[name] = cls; } free(classes); } 4*("#35
  16. @protocol JSBUIView; ! @protocol JSBUIAlertView <JSExport, JSBUIView> ! @property (nonatomic,

    readonly) NSInteger numberOfButtons; @property (nonatomic, readonly, getter = isVisible) BOOL visible; @property (nonatomic) NSInteger cancelButtonIndex; @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) NSString *message; @property (nonatomic, assign) id delegate; @property (nonatomic, assign) UIAlertViewStyle alertViewStyle; @property (nonatomic, readonly) NSInteger firstOtherButtonIndex; ! - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles , ...; - (NSInteger)addButtonWithTitle:(NSString *)title; - (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex; - (void)show; - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated: (BOOL)animated; - (UITextField *)textFieldAtIndex:(NSInteger)textFieldIndex; ! #pragma clang diagnostic pop ! @end
  17. @protocol JSBUIView <JSExport, JSBUIResponder> ! @property (nonatomic, getter = isOpaque)

    BOOL opaque; @property (nonatomic) CGRect frame; @property (nonatomic, getter = isHidden) BOOL hidden; @property (nonatomic) BOOL autoresizesSubviews; @property (nonatomic, readonly, copy) NSArray *subviews; ! ! + (Class)layerClass; + (void)beginAnimations:(NSString *)animationID context:(void *)context; + (void)commitAnimations;
  18. @protocol JSBNSObject <JSExport, NSObject> ! - (BOOL)isEqual:(id)object; - (NSUInteger)hash; !

    - (Class)superclass; - (Class)class; ! - (BOOL)isProxy; ! - (BOOL)isKindOfClass:(Class)aClass; - (BOOL)isMemberOfClass:(Class)aClass; - (BOOL)conformsToProtocol:(Protocol *)aProtocol; ! - (NSString *)description; - (NSString *)debugDescription; ! + (void)load; ! + (void)initialize; - (id)init; ! + (id)new; + (id)allocWithZone:(struct _NSZone *)zone;
  19. [context evaluateScript: @"var window = UIWindow.alloc().initWithFrame(UIScreen.mainScreen().bounds);" @"window.backgroundColor = UIColor.whiteColor();" @""

    @"var navigationController = UINavigationController.new();" @"" @"var tableViewController = UITableViewController.new();" @"tableViewController.navigationItem.title = 'JavaScriptBridge';" @"navigationController.viewControllers = [tableViewController];" @"" @"window.rootViewController = navigationController;" @"" @"window.makeKeyAndVisible();" @"" @"var alertView = UIAlertView.new();" @"alertView.message = 'Hello JavaScriptBridge!';" @"alertView.addButtonWithTitle('OK');" @"alertView.show();" ];
  20. UISlider *slider = [[UISlider alloc] initWithFrame:frame]; slider.backgroundColor = [UIColor clearColor];

    slider.minimumValue = 0.0; slider.maximumValue = 100.0; slider.continuous = YES; slider.value = 50.0; var slider = UISlider.alloc().initWithFrame(frame); slider.backgroundColor = UIColor.clearColor(); slider.minimumValue = 0.0; slider.maximumValue = 100.0; slider.continuous = true; slider.value = 50.0; ϓϩύςΟΞΫηε
  21. UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; var window

    = UIWindow.alloc().initWithFrame(UIScreen.mainScreen().bounds); ϝιουݺͼग़͠
  22. UIView *view = [UIView new]; view.frame = CGRectMake(20, 80, 280,

    80); ! CGFloat x = view.frame.origin.x; CGFloat width = view.frame.size.width; var view = UIView.new(); view.frame = {x: 20, y: 80, width: 280, height: 80}; ! var x = view.frame.x; var width = view.frame.width; ߏ଄ମ
  23. var MainViewController = JSB.defineClass('MainViewController : UITableViewController', { // Instance Method

    Definitions viewDidLoad: function() { self.navigationItem.title = 'UICatalog'; }, viewWillAppear: function(animated) { self.tableView.reloadData(); } }, { // Class Method Definitions attemptRotationToDeviceOrientation: function() { ... } });
  24. Class cls = objc_allocateClassPair(NSClassFromString(parentClassName), className.UTF8String, 0); objc_registerClassPair(cls); ! Class superClass

    = class_getSuperclass(cls); if (superClass) { setupForwardingImplementations(cls, superClass, instanceMembers, staticMembers); } ! NSString *types; BOOL result; ! Class metaClass = objc_getMetaClass(className.UTF8String); ! types = [NSString stringWithFormat: @"%s%s%s%s", @encode(NSMethodSignature), @encode(id), @encode(SEL), @encode(SEL)]; result = class_addMethod(cls, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); result = class_addMethod(metaClass, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); ! types = [NSString stringWithFormat: @"%s%s%s%s", @encode(void), @encode(id), @encode(SEL), @encode(NSInvocation)]; result = class_addMethod(cls, @selector(forwardInvocation:), (IMP)forwardInvocation, types.UTF8String); result = class_addMethod(metaClass, @selector(forwardInvocation:), (IMP)forwardInvocation, types.UTF8String); ! types = [NSString stringWithFormat: @"%s%s%s%s", @encode(BOOL), @encode(id), @encode(SEL), @encode(SEL)]; result = class_addMethod(cls, @selector(respondsToSelector:), (IMP)respondsToSelector, types.UTF8String); result = class_addMethod(metaClass, @selector(respondsToSelector:), (IMP)respondsToSelector, types.UTF8String); ! for (NSString *protocol in [protocols componentsSeparatedByString:@","]) { class_addProtocol(cls, NSProtocolFromString([protocol stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]])); } ! class_addProtocol(cls, @protocol(JSBNSObject)); ! NSString *key = mangledNameFromClass(cls); globalContext[key] = cls; globalContext[key][JSBInstanceMembersKey] = instanceMembers; globalContext[key][JSBStaticMembersKey] = staticMembers; ! return cls;
  25. NSString *types; BOOL result; ! types = [NSString stringWithFormat: @“%s%s%s%s",

    @encode(NSMethodSignature), @encode(id), @encode(SEL), @encode(SEL)]; ! result = class_addMethod(cls, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); ΫϥεʹϝιουΛ௥Ճ ʢΠϯελϯεϝιουʣ
  26. NSMethodSignature *methodSignatureForSelector(id self, SEL _cmd, SEL selector) { NSMethodSignature *methodSignature

    = nil; Class cls = object_getClass(self); if (class_isMetaClass(cls)) { methodSignature = [cls instanceMethodSignatureForSelector:selector]; if (methodSignature) { return methodSignature; } } else { methodSignature = [cls instanceMethodSignatureForSelector:selector]; if (methodSignature) { return methodSignature; } } NSUInteger numberOfArguments = [[NSStringFromSelector(selector) componentsSeparatedByString:@":"] count] - 1; return [NSMethodSignature signatureWithObjCTypes:[[@"@@:" stringByPaddingToLength:numberOfArguments + 3 withString:@"@" startingAtIndex:0] UTF8String]]; } ϝιουݺͼग़͠Λసૹ
  27. BOOL respondsToSelector(id self, SEL _cmd, SEL selector) { NSString *propertyName

    = propertyNameFromSelector(selector); JSValue *function = propertyForObject(self, propertyName); return !function.isUndefined; } ϝιουݺͼग़͠Λసૹ
  28. void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation) { JSContext *context

    = [JSBScriptingSupport globalContext]; if ([[self superclass] instancesRespondToSelector:invocation.selector]) { invokeSuper(invocation); } id currentSelf = context[@"self"]; context[@"self"] = self; NSString *propertyName = propertyNameFromSelector(invocation.selector); JSValue *function = propertyForObject(self, propertyName); if (!function.isUndefined) { NSArray *arguments = extractArguments(invocation); JSValue *returnValue = [function callWithArguments:arguments]; setReturnValue(returnValue, invocation); } context[@"self"] = currentSelf; } ϝιουݺͼग़͠Λసૹ
  29. NSString *types; BOOL result; ! Class metaClass = objc_getMetaClass(className.UTF8String); !

    types = [NSString stringWithFormat: @"%s%s%s%s", @encode(NSMethodSignature), @encode(id), @encode(SEL), @encode(SEL)]; ! result = class_addMethod(metaClass, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); ΫϥεʹϝιουΛ௥Ճ ʢΫϥεϝιουʣ
  30. JSValue *propertyForObject(id obj, NSString *propertyName) { JSContext *context = [JSBScriptingSupport

    globalContext]; JSValue *properties = nil; Class cls = object_getClass(obj); if (class_isMetaClass(cls)) { properties = context[mangledNameFromClass(obj)][JSBStaticMembersKey]; } else { properties = context[mangledNameFromClass(cls)][JSBInstanceMembersKey]; } return properties[propertyName]; } JEܕͷΦϒδΣΫτ͕ ΫϥεΦϒδΣΫτ͔Ͳ͏͔
  31. unsigned int numberOfInstanceMethods = 0; Method *instanceMethods = class_copyMethodList(cls, &numberOfInstanceMethods);

    for (unsigned int i = 0; i < numberOfInstanceMethods; i++) { Method method = instanceMethods[i]; struct objc_method_description *description = method_getDescription(method); NSString *propertyName = propertyNameFromSelector(description->name); JSValue *function = instanceFunctions[propertyName]; if (!function.isUndefined) { class_addMethod(targetClass, description->name, _objc_msgForward, description->types); } } if (instanceMethods) { free(instanceMethods); } ΫϥεʹϝιουΛ௥Ճ ʢΦʔόʔϥΠυʣ
  32. void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation) { JSContext *context

    = [JSBScriptingSupport globalContext]; if ([[self superclass] instancesRespondToSelector:invocation.selector]) { invokeSuper(invocation); } id currentSelf = context[@"self"]; context[@"self"] = self; NSString *propertyName = propertyNameFromSelector(invocation.selector); JSValue *function = propertyForObject(self, propertyName); if (!function.isUndefined) { NSArray *arguments = extractArguments(invocation); JSValue *returnValue = [function callWithArguments:arguments]; setReturnValue(returnValue, invocation); } context[@"self"] = currentSelf; } ʢͳΜͱͳ͘ʣ+4ͱ0CK$͕ର࿩Ͱ͖Δ
  33. var ButtonsViewController = JSB.require('buttonsViewController'); var ControlsViewController = JSB.require('controlsViewController'); var WebViewController

    = JSB.require('webViewController'); var MapViewController = JSB.require('mapViewController'); ! var MainViewController = JSB.defineClass('MainViewController : UITableViewController', { viewDidLoad: function() { self.navigationItem.title = 'UICatalog'; ... }); JSB.exports = MainViewController;
  34. w 8FCΤϯδχΞ w J04ΤϯδχΞ w σβΠφʔ ! w ϢϏϨδΛࢧ͑Δٕज़ w

    IUUQBLJTVUFDPNCMPHQPTUIUNM w ब׆೔ه  ϢϏϨδ๚໰ w IUUQMBJTPIBUFOBCMPHDPNFOUSZ&##&###&"&"@ @&"&&"$&#&"""&'