text:
NSString * const ACArchiverCenterRootFolderPath = @"com.archiver.center.archives";
NSString * const ACArchiverCenterStorageNamesFilename = @"com.archiver.center.storage.names";

NSString * const ACArchiverCenterDefaultName = @"com.archiver.center.default";
NSString * const ACArchiverStorageDefaultName = @"com.archiver.storage.default";

NSString * const ACArchiveStorageSetPredicateString = @"^set[A-Z]([a-z]|[A-Z])*:forKey:$";
NSString * const ACArchiveStorageGetPredicateString = @"^[a-z]([a-z]|[A-Z])*ForKey:$";

#define BBLinkArchiverCenterRetain(obj)     if (@available(iOS 8, *)) CFRetain((__bridge void *)obj)

UIKIT_STATIC_INLINE id ACArchiveStorageBoxValue(const char *type, ...) {
    va_list v;
    va_start(v, type);
    id obj = nil;
    if (strcmp(type, @encode(id)) == 0) {
        id actual = va_arg(v, id);
        obj = actual;
    } else if (strcmp(type, @encode(CGPoint)) == 0) {
        CGPoint actual = (CGPoint)va_arg(v, CGPoint);
        obj = [NSValue value:&actual withObjCType:type];
    } else if (strcmp(type, @encode(CGSize)) == 0) {
        CGSize actual = (CGSize)va_arg(v, CGSize);
        obj = [NSValue value:&actual withObjCType:type];
    } else if (strcmp(type, @encode(UIEdgeInsets)) == 0) {
        UIEdgeInsets actual = (UIEdgeInsets)va_arg(v, UIEdgeInsets);
        obj = [NSValue value:&actual withObjCType:type];
    } else if (strcmp(type, @encode(double)) == 0) {
        double actual = (double)va_arg(v, double);
        obj = [NSNumber numberWithDouble:actual];
    } else if (strcmp(type, @encode(float)) == 0) {
        float actual = (float)va_arg(v, double);
        obj = [NSNumber numberWithFloat:actual];
    } else if (strcmp(type, @encode(int)) == 0) {
        int actual = (int)va_arg(v, int);
        obj = [NSNumber numberWithInt:actual];
    } else if (strcmp(type, @encode(long)) == 0) {
        long actual = (long)va_arg(v, long);
        obj = [NSNumber numberWithLong:actual];
    } else if (strcmp(type, @encode(long long)) == 0) {
        long long actual = (long long)va_arg(v, long long);
        obj = [NSNumber numberWithLongLong:actual];
    } else if (strcmp(type, @encode(short)) == 0) {
        short actual = (short)va_arg(v, int);
        obj = [NSNumber numberWithShort:actual];
    } else if (strcmp(type, @encode(char)) == 0) {
        char actual = (char)va_arg(v, int);
        obj = [NSNumber numberWithChar:actual];
    } else if (strcmp(type, @encode(bool)) == 0) {
        bool actual = (bool)va_arg(v, int);
        obj = [NSNumber numberWithBool:actual];
    } else if (strcmp(type, @encode(unsigned char)) == 0) {
        unsigned char actual = (unsigned char)va_arg(v, unsigned int);
        obj = [NSNumber numberWithUnsignedChar:actual];
    } else if (strcmp(type, @encode(unsigned int)) == 0) {
        unsigned int actual = (unsigned int)va_arg(v, unsigned int);
        obj = [NSNumber numberWithUnsignedInt:actual];
    } else if (strcmp(type, @encode(unsigned long)) == 0) {
        unsigned long actual = (unsigned long)va_arg(v, unsigned long);
        obj = [NSNumber numberWithUnsignedLong:actual];
    } else if (strcmp(type, @encode(unsigned long long)) == 0) {
        unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);
        obj = [NSNumber numberWithUnsignedLongLong:actual];
    } else if (strcmp(type, @encode(unsigned short)) == 0) {
        unsigned short actual = (unsigned short)va_arg(v, unsigned int);
        obj = [NSNumber numberWithUnsignedShort:actual];
    }
    va_end(v);
    return obj;
}

@interface ACArchiveStorage ()

@property (nonatomic, copy) NSString *name;

@property (nonatomic, copy) NSString *filePath;

@property (nonatomic, strong) NSMutableDictionary *mutableKeyValues;

@property (nonatomic, strong, readonly) NSDictionary *keyValues;

@property (nonatomic, strong) dispatch_queue_t queue;

@property (nonatomic, assign) void *queueTag;

@end

@implementation ACArchiveStorage

+ (instancetype)archiveStorageWithName:(NSString *)name filePath:(NSString *)filePath;{
    return [[self alloc] initWithName:name filePath:filePath];
}

- (instancetype)initWithName:(NSString *)name filePath:(NSString *)filePath;{
    if (self = [super init]) {
        self.name = name;
        self.filePath = filePath;
        self.queueTag = &_queueTag;
        self.queue = dispatch_queue_create([[@"com.archive.center.storage." stringByAppendingString:name] UTF8String], DISPATCH_QUEUE_SERIAL);

        dispatch_queue_set_specific([self queue], _queueTag, _queueTag, NULL);
        [self reload];
    }
    return self;
}

- (id)copyWithZone:(NSZone *)zone;{
    ACArchiveStorage *copy = [[ACArchiveStorage allocWithZone:zone] init];
    copy.mutableKeyValues = [[self mutableKeyValues] copy];
    copy.name = [[self name] copy];
    copy.filePath = [[self filePath] copy];
    return copy;
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [self init]) {
        self.mutableKeyValues = [coder decodeObjectForKey:@"mutableKeyValues"];
        self.name = [coder decodeObjectForKey:@"name"];
        self.filePath = [coder decodeObjectForKey:@"filePath"];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:[self mutableKeyValues] forKey:@"mutableKeyValues"];
    [coder encodeObject:[self name] forKey:@"name"];
    [coder encodeObject:[self filePath] forKey:@"filePath"];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation{
    NSMethodSignature *signature = [anInvocation methodSignature];
    NSString *selectorString = NSStringFromSelector([anInvocation selector]);
    if ([[NSPredicate predicateWithFormat:@"SELF MATCHES %@", ACArchiveStorageSetPredicateString] evaluateWithObject:selectorString]) {
        const char *type = [signature getArgumentTypeAtIndex:2];
        void *value = NULL; NSString *key = nil;
        [anInvocation getArgument:&value atIndex:2];
        [anInvocation getArgument:&key atIndex:3];
        BBLinkArchiverCenterRetain(key);

        NSString *copiedKey = [key copy];
        id result = ACArchiveStorageBoxValue(type, value);
        [self setObject:result forKey:copiedKey];

        anInvocation.target = nil;
        [anInvocation invoke];

        return;
    } else if ([[NSPredicate predicateWithFormat:@"SELF MATCHES %@", ACArchiveStorageGetPredicateString] evaluateWithObject:selectorString]){
        NSString *getter = [selectorString substringToIndex:[selectorString rangeOfString:@"ForKey:"].location];
        getter = [getter hasSuffix:@"Value"] ? getter : [getter stringByAppendingString:@"Value"];

        NSString *key = nil;
        [anInvocation getArgument:&key atIndex:2];
        BBLinkArchiverCenterRetain(key);

        NSString *copiedKey = [key copy];
        if ([copiedKey isKindOfClass:[NSString class]] && [copiedKey length]) {
            id object = [self objectForKey:copiedKey];
            if (object && [object respondsToSelector:NSSelectorFromString(getter)]) {
                anInvocation.selector = NSSelectorFromString(getter);
            }
            if (object) {
                [anInvocation invokeWithTarget:object];
            } else {
                anInvocation.target = nil;
                [anInvocation invoke];
            }
            return;
        }
    }

    [super forwardInvocation:anInvocation];
}

#pragma mark NSSecureCoding

+ (BOOL)supportsSecureCoding {
    return NO;
}

#pragma mark - public

- (NSMutableDictionary *)mutableKeyValues{
    if (!_mutableKeyValues) {
        _mutableKeyValues = [NSMutableDictionary dictionary];
    }
    return _mutableKeyValues;
}

- (NSDictionary *)keyValues{
    __block NSDictionary *keyValues = nil;
    [self _sync:^ {
        keyValues = [[self mutableKeyValues] copy];
    }];
    return keyValues;
}

- (NSArray<NSString *> *)allKeys {
    return [[self keyValues] allKeys];
}

- (NSArray<id> *)allValues {
    return [[self keyValues] allValues];
}

- (NSUInteger)count{
    return [[self keyValues] count];
}

- (NSArray<NSString *> *)allKeysForObject:(id)anObject{
    return [[self keyValues] allKeysForObject:anObject];
}

- (NSArray<NSObject, NSCopying, NSCoding> *)objectsForKeys:(NSArray<NSString *> *)keys notFoundMarker:(id)marker;{
    return [[self keyValues] objectsForKeys:keys notFoundMarker:marker];
}

- (NSString *)stringForKey:(NSString *)aKey;{
    id object = [self objectForKey:aKey];
    if ([object isKindOfClass:[NSString class]]) {
        return object;
    } else if ([object respondsToSelector:@selector(stringValue)]) {
        return [object stringValue];
    } else {
        return [object description];
    }
}

- (NSDate *)dateForKey:(NSString *)aKey;{
    id object = [self objectForKey:aKey];
    if ([object isKindOfClass:[NSDate class]]) {
        return object;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    } else if ([object respondsToSelector:@selector(dateValue)]) {
        return [object performSelector:@selector(dateValue)];
#pragma clang diagnostic pop
    } else if ([object isKindOfClass:[NSNumber class]] || [object isKindOfClass:[NSString class]]) {
        return [NSDate dateWithTimeIntervalSince1970:[object floatValue]];
    } else {
        return nil;
    }
}

- (NSData *)dataForKey:(NSString *)aKey;{
    id object = [self objectForKey:aKey];
    if ([object isKindOfClass:[NSData class]]) {
        return object;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    } else if ([object respondsToSelector:@selector(dataValue)]) {
        return [object performSelector:@selector(dataValue)];
#pragma clang diagnostic pop
    } else if ([object isKindOfClass:[NSString class]]) {
        return [object dataUsingEncoding:NSUTF8StringEncoding];
    } else if ([object isKindOfClass:[NSNumber class]]) {
        return [[object stringValue] dataUsingEncoding:NSUTF8StringEncoding];
    } else {
        return nil;
    }
}

- (NSURL *)URLForKey:(NSString *)aKey;{
    id object = [self objectForKey:aKey];
    if ([object isKindOfClass:[NSURL class]]) {
        return object;
    } else if ([object respondsToSelector:@selector(URL)]) {
        return [object URL];
    } else if ([object isKindOfClass:[NSString class]]) {
        return [NSURL URLWithString:object];
    } else {
        return nil;
    }
}

- (id<NSObject, NSCopying, NSCoding>)objectForKey:(NSString *)aKey;{
    __block id object = nil;
    [self _sync:^ {
        object = [self keyValues][aKey];
    }];
    return object;
}

- (void)setObject:(id<NSObject, NSCopying, NSCoding>)anObject forKey:(NSString *)aKey{
    [self _setObject:anObject forKey:aKey];
}

- (void)syncSetObject:(id<NSObject, NSCopying, NSCoding>)anObject forKey:(NSString *)aKey;{
    [self setObject:anObject forKey:aKey];
    [self save];
}

- (void)removeObjectForKey:(NSString *)aKey{
    [self _asyncSaveWithSyncBlock:^ {
        [[self mutableKeyValues] removeObjectForKey:aKey];
    }];
}

- (void)reload;{
    [self _sync:^ {
        self.mutableKeyValues = [NSKeyedUnarchiver unarchiveObjectWithFile:[self filePath]] ?: [@{} mutableCopy];
    }];
}

- (BOOL)save;{
    __block BOOL result = NO;
    [self _sync:^ {
        result = [self _save];
    }];
    return result;
}

- (NSString *)description{
    __block NSString *description = nil;
    [self _sync:^ {
        description = [[self mutableKeyValues] description];
    }];
    return description;
}

#pragma mark - private

- (void)_async:(dispatch_block_t)block;{
    if (dispatch_get_specific(_queueTag)) {
        block();
    } else {
        dispatch_async([self queue], block);
    }
}

- (void)_sync:(dispatch_block_t)block;{
    if (dispatch_get_specific(_queueTag)) {
        block();
    } else {
        dispatch_sync([self queue], block);
    }
}

- (void)_asyncSaveWithSyncBlock:(dispatch_block_t)block;{
    dispatch_block_t innerBlock = ^{
        block();

        [self _async:^{
            [self _save];
        }];
    };
    [self _sync:innerBlock];
}

- (BOOL)_save;{
    return [NSKeyedArchiver archiveRootObject:[self mutableKeyValues] toFile:[self filePath]];
}

- (void)_setObject:(id<NSObject, NSCopying, NSCoding>)anObject forKey:(NSString *)aKey{
    if (!anObject || ![aKey length]) return;
    if (![anObject respondsToSelector:@selector(copyWithZone:)]) return;
    if (![anObject respondsToSelector:@selector(encodeWithCoder:)]) return;
    if (![anObject respondsToSelector:@selector(initWithCoder:)]) return;

    [self _asyncSaveWithSyncBlock:^{
        [self willChangeValueForKey:aKey];

        self.mutableKeyValues[[aKey copy]] = anObject;

        [self didChangeValueForKey:aKey];
    }];
}

- (void)setObject:(id<NSObject, NSCopying, NSCoding>)anObject forKeyedSubscript:(NSString *)aKey{
    [self _setObject:anObject forKey:aKey];
}

- (id)objectForKeyedSubscript:(NSString *)key{
    return [self objectForKey:key];
}

@end

@interface ACArchiverCenter ()

@property (nonatomic, strong) NSMutableArray<NSString *> *storageNames;

@property (nonatomic, strong) NSMutableDictionary<NSString*, id<ACArchiveStorage>> *cachedStorages;

@property (nonatomic, copy) NSString *directory;

@property (nonatomic, copy) NSString *uniqueIdentifier;

@property (nonatomic, copy, readonly) NSString *rootFolderPath;
@property (nonatomic, copy, readonly) NSString *storageNamesFilePath;

@end

@implementation ACArchiverCenter

+ (id)defaultCenter;{
    static ACArchiverCenter *center = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSString *rootFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        center = [[self alloc] initWithUniqueIdentifier:ACArchiverCenterDefaultName directory:rootFolder];
    });
    return center;
}

+ (id<ACArchiveStorage>)defaultStorage;{
    return [[self defaultCenter] defaultStorage];
}

- (id<ACArchiveStorage>)defaultStorage;{
    return [self requireStorageWithName:ACArchiverStorageDefaultName];
}

- (instancetype)initWithUniqueIdentifier:(NSString *)uniqueIdentifier directory:(NSString *)directory;{
    if (self = [super init]) {
        self.directory = directory;
        self.uniqueIdentifier = uniqueIdentifier;

        [self initialize];
    }
    return self;
}

- (void)initialize{
    [self reloadAll];
}

#pragma mark = accessor

- (NSMutableArray<NSString *> *)storageNames{
    if (!_storageNames) {
        _storageNames = [NSMutableArray array];
    }
    return _storageNames;
}

- (NSMutableDictionary<NSString *,id<ACArchiveStorage>> *)cachedStorages{
    if (!_cachedStorages) {
        _cachedStorages = [NSMutableDictionary dictionary];
    }
    return _cachedStorages;
}

- (NSString *)rootFolderPath{
    return [NSString stringWithFormat:@"%@/%@/%@", [self directory], ACArchiverCenterRootFolderPath, [self uniqueIdentifier]];
}

- (NSString *)storageNamesFilePath{
    return [self _storageFilePathWithName:ACArchiverCenterStorageNamesFilename];
}

#pragma mark - private

- (NSString *)_storageFilePathWithName:(NSString *)name{
    return [NSString stringWithFormat:@"%@/%@.archiver", [self rootFolderPath], name];
}

- (BOOL)_saveStorageNames{
    return [NSKeyedArchiver archiveRootObject:[self storageNames] toFile:[self storageNamesFilePath]];
}

- (void)_readStorageNames{
    BOOL isDirectory = NO;
    void (^createDirectoryHandler)(void) = ^{
        NSError *error = nil;
        [[NSFileManager defaultManager] createDirectoryAtPath:[self rootFolderPath] withIntermediateDirectories:YES attributes:nil error:&error];
        if (error) {
            NSLog(@"Failed to create directorr with error : %@", error);
        }
    };
    if ([[NSFileManager defaultManager] fileExistsAtPath:[self rootFolderPath] isDirectory:&isDirectory]) {
        if (!isDirectory) {
            NSError *error = nil;
            [[NSFileManager defaultManager] removeItemAtPath:[self rootFolderPath] error:&error];
            if (error) {
                NSLog(@"Failed to remove file path with error : %@", error);
            }
            createDirectoryHandler();
        }
    } else {
        createDirectoryHandler();
    }

    self.storageNames = [NSKeyedUnarchiver unarchiveObjectWithFile:[self storageNamesFilePath]] ?: [NSMutableArray array];
}

#pragma mark - public

- (id<ACArchiveStorage>)requireStorageWithName:(NSString *)name {
    NSParameterAssert([name length]);
    id<ACArchiveStorage> result = nil;
    id<ACArchiveStorage> (^newStorage)(NSString *storageName) = ^(NSString *storageName){
        // New an storage from archive file.
        id<ACArchiveStorage> storage = [ACArchiveStorage archiveStorageWithName:storageName filePath:[self _storageFilePathWithName:storageName]];
        if (storage) {
            self.cachedStorages[name] = storage;
        }
        return storage;
    };
    // Append name if the storage hasn't loaded.
    if ([[self storageNames] containsObject:name] && [[[self cachedStorages] allKeys] containsObject:name]) {
        result = [self cachedStorages][name];
    } else {
        result = newStorage(name);
    }

    if (result && ![[self storageNames] containsObject:name]) {
        [[self storageNames] addObject:name];
        [self _saveStorageNames];
    }

    return result;
}

- (void)reloadAll {
    [[self storageNames] removeAllObjects];
    for (id<ACArchiveStorage> storage in [[self cachedStorages] allValues]) {
        [storage reload];
    }
    [self _readStorageNames];
}

- (void)saveAll;{
    for (id<ACArchiveStorage> storage in [[self cachedStorages] allValues]) {
        [storage save];
    }
    [self _saveStorageNames];
}

@end


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using DesktopLauncher.Extensions;
using System.Reflection;
using System.Diagnostics;
using System.Collections.ObjectModel;

namespace DesktopLauncher
{
    /// <summary>
    /// OptionsWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class OptionsWindows : Window
    {
        public OptionsWindows()
        {
            InitializeComponent();
            ApplicationTitle.Content = string.Format(ApplicationTitle.Content as string, Assembly.GetExecutingAssembly().GetName().Version);
        }

        public IReadOnlyList<ILaunchable> Apps
        {
            set
            {
                (this.Resources["ViewModel"] as OptionsViewModel).Apps = new ObservableCollection<ILaunchable>(value);
            }
        }

        private void Window_SourceInitialized(object sender, EventArgs e)
        {
            this.HideMinimizeAndMaximizeButtons();
        }

        private void OK_Click(object sender, RoutedEventArgs e)
        {
            (this.Resources["ViewModel"] as OptionsViewModel).Save();
            DialogResult = true;
            Close();
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            System.Windows.Data.CollectionViewSource optionsViewModelViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("optionsViewModelViewSource")));
            // CollectionViewSource.Source プロパティを設定してデータを読み込みます:
            // optionsViewModelViewSource.Source = [汎用データ ソース]
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
            {
                var result = dialog.ShowDialog();
                if (result == System.Windows.Forms.DialogResult.OK)
                {
                    var rowItem = (e.Source as Button).Tag;

                    // 既存行の場合
                    if(rowItem is ExtraFolderViewModel)
                    {
                        (rowItem as ExtraFolderViewModel).FolderPath = dialog.SelectedPath;
                    }
                    // 新規行の場合
                    else
                    {
                        var viewModel = FindResource("ViewModel") as OptionsViewModel;
                        viewModel.ExtraFolders.Add(new ExtraFolderViewModel(dialog.SelectedPath, ""));
                    }
                }
            }
        }

        private void HotKey_KeyUp(object sender, KeyEventArgs e)
        {
            HotKey.SelectedValue = HotKeyConverter.ConvertToString(e.Key);
        }

        private void RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
        {
            Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
            e.Handled = true;
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
class CorrectSomePolymorphicIndexAndAddMoreMissing < ActiveRecord::Migration
  def change
    add_index :spree_addresses, :country_id
    add_index :spree_addresses, :state_id

    remove_index :spree_adjustments, [:source_type, :source_id]
    add_index :spree_adjustments, [:source_id, :source_type]

    add_index :spree_inventory_units, :return_authorization_id

    add_index :spree_log_entries, [:source_id, :source_type]

    add_index :spree_orders, :approver_id
    add_index :spree_orders, :created_by_id
    add_index :spree_orders, :ship_address_id
    add_index :spree_orders, :bill_address_id
    add_index :spree_orders, :considered_risky

    add_index :spree_orders_promotions, [:order_id, :promotion_id]

    add_index :spree_payments, [:source_id, :source_type]

    add_index :spree_product_option_types, :position

    add_index :spree_product_properties, :position
    add_index :spree_product_properties, :property_id

    add_index :spree_promotion_action_line_items, :promotion_action_id
    add_index :spree_promotion_action_line_items, :variant_id

    add_index :spree_promotion_rules, :promotion_id

    add_index :spree_promotions, :advertise

    add_index :spree_return_authorizations, :number
    add_index :spree_return_authorizations, :order_id
    add_index :spree_return_authorizations, :stock_location_id

    add_index :spree_shipments, :address_id

    add_index :spree_shipping_methods, :tax_category_id

    add_index :spree_state_changes, [:stateful_id, :stateful_type]
    add_index :spree_state_changes, :user_id

    add_index :spree_stock_locations, :country_id
    add_index :spree_stock_locations, :state_id

    add_index :spree_tax_rates, :deleted_at
    add_index :spree_tax_rates, :tax_category_id
    add_index :spree_tax_rates, :zone_id

    add_index :spree_taxonomies, :position

    add_index :spree_taxons, :position

    add_index :spree_variants, :position
    add_index :spree_variants, :track_inventory

    add_index :spree_zone_members, :zone_id
    add_index :spree_zone_members, [:zoneable_id, :zoneable_type]
  end
end


text:
rm -rf out || exit 0;
mkdir out;

GH_REPO="@github.com/stephlocke/ezknitrTest.git"

FULL_REPO="https://$GH_TOKEN$GH_REPO"

R CMD BATCH 'rendercheck.R'

cp rendercheck.Rout out
cp ~/ezknitrTest/out/* out
cd out
ls -l

git init
git config user.name "stephs-travis"
git config user.email "travis"
git add .
git commit -m "deployed to github pages"
git push --force --quiet $FULL_REPO master:gh-pages


text:
package by.itransition.dpm.service;

import by.itransition.dpm.Main;
import by.itransition.dpm.dao.UserDao;
import by.itransition.dpm.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserRegistration {

    @Autowired
    private MailSender mailSender;

    @Autowired
    private SimpleMailMessage message;

    @Autowired
    private UserDao userDao;

    private User user;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setMessage(SimpleMailMessage message) {
        this.message = message;
    }

    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }

    public void setUser(User user){
        this.user = user;
    }

    @Transactional
    public void registrate(){
        user.setRole(2);
        addUser();
        sendMessage(generateLink());
    }

    public void sendMessage(String link) {
        message.setFrom("dpm-project@mail.ru");
        message.setTo(user.getEmail());
        message.setSubject("Activation on DPM");
        message.setText(Main.ACTIVATION_MESSAGE_1 + user.getUsername() + Main.ACTIVATION_MESSAGE_2 + user.getPassword() + Main.ACTIVATION_MESSAGE_3 + link + Main.ACTIVATION_MESSAGE_4);
        mailSender.send(message);
    }

    @Transactional
    public void addUser() {
        userDao.addUser(user);
    }

    private String generateLink(){
        StringBuffer link = new StringBuffer(Main.DOMAIN_NAME);
        link.append("/activate/");
        link.append(Activation.generateActivationCode(user));
        return new String(link);
    }
}


text:
import EditableUIView from "../editableuiview";

export default class InlineEditableUIView extends EditableUIView {}


text:
module SimpleRoles
  VERSION = "0.0.12"
end


text:
React-Quill [![Build Status](https://travis-ci.org/zenoamaro/react-quill.svg?branch=master)](https://travis-ci.org/zenoamaro/react-quill)
==============================================================================

A [Quill] component for [React].

See a [live demo] or [Codepen](http://codepen.io/alexkrolick/pen/xgyOXQ/left?editors=0010#0).

[Quill]: https://quilljs.com
[React]: https://facebook.github.io/react/
[live demo]: https://zenoamaro.github.io/react-quill/

1. [Quick start](#quick-start)
1. [Options](#options)
   1. [Theme](#theme)
   1. [Custom Toolbar](#custom-toolbar)
   1. [Custom Formats](#custom-formats)
   1. [Custom Editing Area](#custom-editing-area)
   1. [Mixin](#mixin)
1. [Upgrading to React-Quill v1.0.0](#upgrading-to-react-quill-v100)
1. [API reference](#api-reference)
   1. [Exports](#exports)
   1. [Props](#props)
   1. [Methods](#methods)
1. [Browser support](#browser-support)
1. [Building and testing](#building-and-testing)
   1. [Bundling with Webpack](#bundling-with-webpack)
1. [Changelog](#changelog)
1. [Contributors](#contributors)
1. [License](#license)

---

💯 **React Quill now supports Quill v1.0.0!**
Thanks to @clemmy and @alexkrolick for landing this much-awaited change. There are many breaking changes, so be sure to read the [migration guide](#upgrading-to-react-quill-v100).

---

🎧 **Latest published package version: `v1.0.0`**

```sh
npm install react-quill@v1.0.0
```

Special thank you to everyone who contributed during the 1.0.0 release cycle!

---

🏵 **Welcoming @alexkrolick to the team!**
His contributions have been incredible so far, and his passion and dedication will bring some much-deserved love to this project.

---

## Quick Start

### Import the component (ES6 syntax below)

```jsx
import ReactQuill from 'react-quill'
```

### Import styles

_Two common examples are shown below. How stylesheets are included in your app depends on build system (Webpack, SCSS, LESS, etc). See the documentation on [Themes](#theme) for more information._

#### Using CDN

```html
<link rel="stylesheet" href="//cdn.quilljs.com/1.2.6/quill.snow.css">
```

#### Using `css-loader` with Webpack or `create-react-app`

```jsx
import theme from 'react-quill/dist/quill.snow.css'
```

### Use the component

```jsx
class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = { text: '' }
    this.handleChange = this.handleChange.bind(this)
  }

  handleChange(value) {
    this.setState({ text: value })
  }

  render() {
    return (
      <ReactQuill value={this.state.text}
                  onChange={this.handleChange} />
    )
  }
}
```

## Options

### Theme

The Quill editor supports [themes](http://quilljs.com/docs/themes/). It includes a full-fledged theme, called _snow_, that is Quill's standard appearance, a _bubble_ theme that is similar to the inline editor on Medium, and a _core_ theme containing only the bare essentials to allow modules like toolbars or tooltips to work.

These stylesheets can be found in the Quill distribution, but for convenience they are also linked in React Quill's `dist` folder. In a common case you would activate a theme by setting the theme [prop](#props). Pass a falsy value (`null`) to disable the theme.

```jsx
<ReactQuill theme="snow" /> // or "bubble", null to use minimal core theme
```

And then link the appropriate stylesheet (only link the CSS for the themes you want to use):

```html
<link rel="stylesheet" href="node_modules/react-quill/dist/quill.snow.css">
<link rel="stylesheet" href="node_modules/react-quill/dist/quill.bubble.css">
<link rel="stylesheet" href="node_modules/react-quill/dist/quill.core.css">
```

This may vary depending how application is structured, directories or otherwise. For example, if you use a CSS pre-processor like SASS, you may want to import that stylesheet inside your own.

### Custom Toolbar

#### Default Toolbar Elements

The [Quill Toolbar Module](http://quilljs.com/docs/modules/toolbar/) API provides an easy way to configure the default toolbar icons using an array of format names.

Example Code

```jsx
var MyComponent = React.createClass({

  modules: {
    toolbar: [
      [{ 'header': [1, 2, false] }],
      ['bold', 'italic', 'underline','strike', 'blockquote'],
      [{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'}],
      ['link', 'image'],
      ['clean']
    ],
  },

  formats: [
    'header',
    'bold', 'italic', 'underline', 'strike', 'blockquote',
    'list', 'bullet', 'indent',
    'link', 'image'
  ],

  render: function() {
    return (
      <div className="text-editor">
        <ReactQuill theme="snow"
                    modules={this.modules}
                    formats={this.formats}>
        </ReactQuill>
      </div>
    );
  },

});
```

#### HTML Toolbar

You can also supply your own HTML/JSX toolbar with custom elements that are not part of the Quill theme.

See this example live on Codepen: [Custom Toolbar Example](https://codepen.io/alexkrolick/pen/gmroPj?editors=0010)

Example Code

```jsx
/*
 * Custom "star" icon for the toolbar using an Octicon
 * https://octicons.github.io
 */
const CustomButton = () => <span className="octicon octicon-star" />

/*
 * Event handler to be attached using Quill toolbar module
 * http://quilljs.com/docs/modules/toolbar/
 */
function insertStar () {
  const cursorPosition = this.quill.getSelection().index
  this.quill.insertText(cursorPosition, "★")
  this.quill.setSelection(cursorPosition + 1)
}

/*
 * Custom toolbar component including insertStar button and dropdowns
 */
const CustomToolbar = () => (
  <div id="toolbar">
    <select className="ql-header">
      <option value="1"></option>
      <option value="2"></option>
      <option selected></option>
    </select>
    <button className="ql-bold"></button>
    <button className="ql-italic"></button>
    <select className="ql-color">
      <option value="red"></option>
      <option value="green"></option>
      <option value="blue"></option>
      <option value="orange"></option>
      <option value="violet"></option>
      <option value="#d0d1d2"></option>
      <option selected></option>
    </select>
    <button className="ql-insertStar">
      <CustomButton />
    </button>
  </div>
)

/*
 * Editor component with custom toolbar and content containers
 */
class Editor extends React.Component {
  constructor (props) {
    super(props)
    this.state = { editorHtml: '' }
    this.handleChange = this.handleChange.bind(this)
  }

  handleChange (html) {
  	this.setState({ editorHtml: html });
  }

  render() {
    return (
      <div className="text-editor">
        <CustomToolbar />
        <ReactQuill
          onChange={this.handleChange}
          placeholder={this.props.placeholder}
          modules={Editor.modules}
        />
      </div>
    )
  }
}

/*
 * Quill modules to attach to editor
 * See http://quilljs.com/docs/modules/ for complete options
 */
Editor.modules = {
  toolbar: {
    container: "#toolbar",
    handlers: {
      "insertStar": insertStar,
    }
  }
}

/*
 * Quill editor formats
 * See http://quilljs.com/docs/formats/
 */
Editor.formats = [
  'header', 'font', 'size',
  'bold', 'italic', 'underline', 'strike', 'blockquote',
  'list', 'bullet', 'indent',
  'link', 'image', 'color',
]

/*
 * PropType validation
 */
Editor.propTypes = {
  placeholder: React.PropTypes.string,
}

/*
 * Render component on page
 */
ReactDOM.render(
  <Editor placeholder={'Write something or insert a star ★'}/>,
  document.querySelector('.app')
)
```

### Custom Formats

The component has two types of formats:

1. The default [Quill formats](http://quilljs.com/docs/formats/) that are enabled/disabled using the [`formats` prop](#props). All formats are enabled by default.
2. Custom formats created using Parchment and registered with your component's Quill instance

Example Code

ES6 Import
```js
import ReactQuill, { Quill } from 'react-quill'
```

CommonJS Require
```js
var ReactQuill = require('react-quill');
var Quill = ReactQuill.Quill;
```

```jsx
/*
 * Example Parchment format from
 * https://quilljs.com/guides/cloning-medium-with-parchment/
 */
let Inline = Quill.import('blots/inline');
class BoldBlot extends Inline { }
BoldBlot.blotName = 'bold';
BoldBlot.tagName = 'strong';
Quill.register(BoldBlot);

/*
 * Editor component with default and custom formats
 */
class MyComponent extends React.Component {
  constructor(props) {
    this.formats = ['italic, 'underline'] // default formats
    this.state = { text: '' }
  }

  handleChange(value) {
    this.setState({text: value})
  }

  render() {
    return (
      <ReactQuill
        value={this.state.text}
        onChange={this.handleChange}
        formats={this.formats} // the custom format is already registered
      />
    )
  }
}
```

### Custom editing area

If you instantiate ReactQuill without children, it will create a `<div>` for you, to be used as the editing area for Quill. If you prefer, you can specify your own element for ReactQuill to use. Note that `<textarea>`s are not supported by Quill at this time.

```jsx
class MyComponent extends React.Component {

  render() {
    return (
      <ReactQuill>
        <div className="my-editing-area"/>
      </ReactQuill>
    );
  }

});
```

### Mixin

The module exports a mixin which can be used to create custom editor components. (Note that mixins will be deprecated in a future version of React).

Example Code

The ReactQuill default component is built using the mixin. See [component.js](src/component.js) for source.

```jsx
import {Mixin} from 'react-quill'

var MyComponent = React.createClass({
  mixins: [ ReactQuill.Mixin ],

  componentDidMount: function() {
    var editor = this.createEditor(
      this.getEditingArea(),
      this.getEditorConfig()
    );
    this.setState({ editor:editor });
  },

  componentWillReceiveProps: function(nextProps) {
    if ('value' in nextProps && nextProps.value !== this.props.value) {
      this.setEditorContents(this.state.editor, nextProps.value);
    }
  },

});
```

## Upgrading to React-Quill v1.0.0

In most cases, ReactQuill will raise useful warnings to help you perform any necessary migration steps.

Please note that many [migration steps to Quill v1.0](http://quilljs.com/guides/upgrading-to-1-0/) may also apply.

Expand Upgrade Guide

### The toolbar module

With v1.0.0, Quill adopted a new [toolbar configuration format](https://quilljs.com/docs/modules/toolbar/), to which React Quill will delegates all toolbar functionality, and which is now the preferred way to customize the toolbar.

Previously, toolbar properties could be set by passing a `toolbar` prop to React Quill. Pass the same options as `modules.toolbar` instead.

Read More

```diff
+ modules: {
    toolbar: [
       ...
    ],
+ },

  <ReactQuill
-   toolbar={this.toolbar}
+   modules={this.modules}
  />
```

If you used to provide your own HTML toolbar component, you can still do the same:

```diff
+ modules: {
+   toolbar: '#my-toolbar-component',
+ },

  <ReactQuill
-   toolbar="#my-toolbar-component"
+   modules={this.modules}
  />
```

Note that it is not possible to pass a toolbar component as a child to ReactQuill anymore.

Previously, React Quill would create a custom HTML toolbar for you if you passed a configuration object as the `toolbar` prop. This will not happen anymore. You can still create a `ReactQuill.Toolbar` explicitly:

```diff
+ modules: {
+   toolbar: '#my-quill-toolbar',
+ },

+ <ReactQuill.Toolbar
+   id='my-quill-toolbar'
+   items={this.oldStyleToolbarItems}
+ />

  <ReactQuill
-   toolbar={this.oldStyleToolbarItems}
+   modules={this.modules}
  />
```

However, consider switching to the new Quill format instead, or provide your own [toolbar component](#html-toolbar).

React Quill now follows the Quill toolbar format closely. See the [Quill toolbar documentation](https://quilljs.com/docs/modules/toolbar/) for a complete reference on all supported options.

### Custom editing areas and refs

Previously, to provide a custom element for Quill to mount on, it was necessary to pass a child identified by a specific `ref`: `editor`.

This is now unnecessary, so you can omit the `ref` entirely if you don't need it. In addition, any `ref` you keep won't be stolen from the owner component anymore.

Note, however, that React Quill will now ensure that the element is compatible with Quill. This means that passing a `<textarea>` now produces an error.

### Passing children to ReactQuill

Previously, it was possible to pass arbitrary components as children of React Quill. Their `ref` would identify them as either a custom toolbar or a custom editing area.

This is not possible anymore, and the only child you can pass now is an optional [custom Editing Area](#custom-editing-area) element.

### Adding custom formats with the `formats` property is deprecated

As of 1.0.0, [use Parchment to define new formats](https://github.com/quilljs/parchment). Use the [Quill export](#exports) from the module to register and extend formats:

```js
Quill.register('formats/CustomFormat', MyCustomFormat);
```

### The `styles` property

Previously, it was allowed to inject CSS styles by providing an object to the `styles` property. This option has been removed from Quill 1.0, and support for it in React Quill has gone as well. If you need to inject styles, link an external stylesheet instead.

See the [Quill Release Notes](http://quilljs.com/guides/upgrading-to-1-0/#configuration).

### The `pollInterval` property

This property previously set the frequency with which Quill polled the DOM for changes. It does not have any effect anymore, and can safely be removed from the props.

## API reference

### Exports

```jsx
import ReactQuill, { Quill, Mixin, Toolbar } from 'react-quill'
```

`Mixin`
: Provides the bridge between React and Quill. `ReactQuill` implements this mixin; in the same way you can use it to build your own component, or replace it to implement a new core for the default component. _Note that mixins are deprecated in React and this export will be replaced by an HOC in the future._

`Toolbar`
: The component that renders the custom ReactQuill toolbar. The default collection of items and color swatches is available as `ReactQuill.Toolbar.defaultItems` and `ReactQuill.Toolbar.defaultColors` respectively. ⚠ The Toolbar component is deprecated since v1.0.0. See [upgrading to React Quill v1.0.0](#upgrading-to-react-quill-v100).

`Quill`
: The `Quill` namespace on which you can call `registerModule` and such.

### Props

`id`
: ID to be applied to the DOM element.

`className`
: Classes to be applied to the DOM element.

`value`
: Value for the editor as a controlled component. Note that due to limitations in Quill, this is actually a _semi-controlled_ mode, meaning that the edit is not prevented, but changing `value` will still replace the contents.

`defaultValue`
: Initial value for the editor as an uncontrolled component.

`readOnly`
: If true, the editor won't allow changing its contents.

`placeholder`
: The default value for the empty editor.

`modules`
: An object specifying which modules are enabled, and their configuration. The editor toolbar is a commonly customized module. See the [modules section](http://quilljs.com/docs/modules/) over the Quill documentation for more information on what modules are available.

`formats`
: An array of formats to be enabled during editing. All implemented formats are enabled by default. See [Formats](http://quilljs.com/docs/formats/) for a list.
  Custom formats should not be included in the array as of version 1.0.0. Instead they should be created through [Parchment](https://github.com/quilljs/parchment) and registered with the module's [Quill export](#exports).

`style`
: An object with custom CSS rules to apply on the editor's container. Rules should be in React's "camelCased" naming style.

`theme`
: The name of the theme to apply to the editor. Defaults to `snow`, Quill's standard theme. Pass `null` to use the minimal core theme. See the [docs on themes](#theme) for more information on including the required stylesheets.

`bounds`
: Selector or DOM element used by Quill to constrain position of popups. Defaults to `document.body`.

`children`
: A single React element that will be used as the editing area for Quill in place of the default, which is a `<div>`. Note that you cannot use a `<textarea>`, as it is not a supported target. Also note that updating children is costly, as it will cause the Quill editor to be recreated. Set the `value` prop if you want to control the html contents of the editor.

`onChange(content, delta, source, editor)`
: Called back with the new contents of the editor after change. It will be passed the HTML contents of the editor, a delta object expressing the change-set itself, the source of the change, and finally a read-only proxy to editor accessors such as `getText()`.

`onChangeSelection(range, source, editor)`
: Called back with the new selected range, or null when unfocused. It will be passed the selection range, the source of the change, and finally a read-only proxy to editor accessors such as `getBounds()`.

`onKeyPress(event)`
: Called after a key has been pressed and released.
: Note that, like its native counterpart, this won't be called for special keys such as shift or enter. If you need those, hook onto `onKeyDown` or `onKeyUp`.

`onKeyDown(event)`
: Called after a key has been pressed, but before it is released.
: Note that, due to how Quill works, it's possible that you won't receive events for keys such as enter, backspace or delete. If that's the case, try hooking onto `onKeyUp` instead.

`onKeyUp(event)`
: Called after a key has been released.

### Methods

If you have [a ref](https://facebook.github.io/react/docs/more-about-refs.html) to a ReactQuill node, you will be able to invoke the following methods:

`focus()`
: Focuses the editor.

`blur()`
: Removes focus from the editor.

`getEditor()`
: Returns the Quill instance that backs the editor. While you can freely use this to access methods such as `getText()`, please avoid from imperatively manipulating the instance.

Example

[View this example on Codepen](https://codepen.io/alexkrolick/pen/YNmGar?editors=0011)

```jsx
class Editor extends React.Component {
  constructor(props) {
    super(props)
    this.quillRef = null;      // Quill instance
    this.reactQuillRef = null; // ReactQuill component
  }

  componentDidMount() {
    this.attachQuillRefs()
  }

  componentDidUpdate() {
    this.attachQuillRefs()
  }

  attachQuillRefs = () => {
    if (typeof this.reactQuillRef.getEditor !== 'function') return;
    this.quillRef = this.reactQuillRef.getEditor();
  }

  insertText = () => {
    var range = this.quillRef.getSelection();
    let position = range ? range.index : 0;
    this.quillRef.insertText(position, 'Hello, World! ')
  }

  render() {
    return (
      <div>
        <ReactQuill
          ref={(el) => { this.reactQuillRef = el }}
          theme={'snow'} />
        <button onClick={this.insertText}>Insert Text</button>
      </div>
    )
  }
}
```

## Building and testing

You can run the automated test suite:

```sh
npm test
```

And build a minificated version of the source:

```sh
npm run build
```

More tasks are available on the [Makefile](Makefile):

    lint: lints the source
    spec: runs the test specs
    coverage: runs the code coverage test
    test: lint, spec and coverage threshold test
    build: builds the minified version

Note that `dist` is ignored in the git repository as of version 1.0.0. If you need to use the built files without downloading the package from NPM, you can run the build tasks yourself or use a CDN like [unpkg](https://unpkg.com/react-quill@1.0.0-beta-1/dist/react-quill.min.js).

### Bundling with Webpack

Quill ships only a pre-built javascript file, so Webpack will complain after building a bundle:

```
Error: ./~/react-quill/~/quill/dist/quill.js
Critical dependencies:
6:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
@ ./~/react-quill/~/quill/dist/quill.js 6:478-485
```

The warning is harmless, but if you want to silence it you can avoid parsing Quill by adding this to your Webpack configuration:

```js
module: {
  // Shut off warnings about using pre-built javascript files
  // as Quill.js unfortunately ships one as its `main`.
  noParse: /node_modules\/quill\/dist/
}
```

See [#7](https://github.com/zenoamaro/react-quill/issues/7) for more details.

## Browser support

Please check the browser support table for the upstream [Quill](https://github.com/quilljs/quill) dependency. The React part of the codebase is ES5-compatible.

## Changelog

#### v1.0.0
This release adds support for Quill v1.0.0+. ⚠ There are many breaking changes, both in Quill and in ReactQuill. See [Upgrading to React-Quill v1.0.0](#upgrading-to-react-quill-v100).

- Updated to support Quill v1.0.0+ (@clemmy, @alexkrolick)
- Bundling Quill with ReactQuill (@clemmy)
- Bundling CSS files in the NPM package
- Removed `dist` from source control (@alexkrolick)
- Deprecated `toolbar` property and component
- Deprecated the `styles` property
- Deprecated custom formats via the `formats` property
- Deprecated the `pollInterval` property
- Rerendering on `style` property change (@lavrton)
- Improved docs for `bounds`, which now rerenders on change
- Performing deep props comparison to avoid rerenders
- Fixed the unprivileged editor not returning values
- Restoring selection event after text change
- Fixed the order of parameters in change events (@webcarrot)
- Using 'core' instead of 'base' CSS (@alexkrolick)
- Added support for the `placeholder` property (@alexkrolick)
- Enable/disable editor using top-level Quill API (@alexkrolick)
- Prevent whitespace issues when initializing the editor (@bobrafie)
- Using buttons instead of spans for toolbar actions (@clemmy)
- Removed getHtml from unprivileged editor (@clemmy)
- Fixed calculations for range fields (@clemmy)
- Removed deprecated destroy functionality (@clemmy)
- Added return statement to proxy editor methods (@druti)
- Inline styles support for Quill Toolbar (@e-jigsaw)
- Fixed custom font size definitions (@clemmy)
- Support for bullet and ordered lists in toolbar (@clemmy)
- Updated the toolbar alignment section (@clemmy)
- Updated rendering of toolbar actions (@clemmy)
- Improved toolbar renderChoices implementation (@zhang-z)
- Fixed use of `defaultValue` in Toolbar selects
- Fixed bounds validation in setEditorSelection (@wouterh)
- Exposed Quill in exports (@tdg5)
- Added unhook function to clean up event listeners on unmount (@alexkrolick, @jrmmnr)
- Fixed documentation typos (@l3kn)
- Started testing with Enzyme (@alexkrolick)
- Fixed issue where changing props caused re-render artifacts (#147)
- Fixed bounds validation in setEditorSelection (@wouterh)
- Updated README.md to reference core.css instead of base.css (@sandbochs)
- Updated React peerDependency (@rpellerin)
- Removed inline Parchment formats for font-size and font-family (#217)

#### v0.4.1
- Added contents of `dist` to NPM package.

#### v0.4.0
This release adds support for React 0.14. ⚠ Shims to support older versions of React have been removed.

- React 0.14 support (@jacktrades, #49)
- Removed shims for React 0.12 and 0.13
- Bumped Quill.js to v0.20.1
- _Normal_ and _smaller_ sizes are not swapped anymore. (#63)
- Various toolbar choice items are now correctly ordered.
- Added image tooltips to the default set of modules (@kairxa, #54)
- Fixed extra white-space in classnames (@asiniy, #67)
- Published the Quill namespace on ReactQuill (@Sajam, #60)
- Quill stylesheets are now linked to `dist/` for convenience. (#70)
- Exposed editor accessor methods in change events. (#33)

[Full changelog](CHANGELOG.md)

## Contributors

React Quill would not be where it is today without the contributions of many people, which we are incredibly grateful for:
- @zenoamaro (maintainer)
- @alexkrolick (maintainer)
- @clemmy
- @asiniy
- @webcarrot
- @druti
- @e-jigsaw
- @zhang-z
- @Sajam
- @0bird512
- @jacktrades
- @1000hz
- @kkerr1
- @csk157
- @Janekk
- @AndyTheGiant
- @chrismcv
- @wouterh
- @tdg5
- @jrmmnr
- @l3kn
- @rpellerin
- @sandbochs
- @wouterh

## Roadmap

- [x] React 0.14 support
- [x] Quill v1.0.0+ support
- [x] Tests!
- [ ] Compatibility with React 16
- [ ] Additional APIs for working with Quill

## License

The MIT License (MIT)

Copyright (c) 2016, zenoamaro <zenoamaro@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


text:
#include <aws/athena/model/QueryExecutionStatus.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::Utils::Json;
using namespace Aws::Utils;

namespace Aws
{
namespace Athena
{
namespace Model
{

QueryExecutionStatus::QueryExecutionStatus() :
    m_state(QueryExecutionState::NOT_SET),
    m_stateHasBeenSet(false),
    m_stateChangeReasonHasBeenSet(false),
    m_submissionDateTimeHasBeenSet(false),
    m_completionDateTimeHasBeenSet(false)
{
}

QueryExecutionStatus::QueryExecutionStatus(JsonView jsonValue) :
    m_state(QueryExecutionState::NOT_SET),
    m_stateHasBeenSet(false),
    m_stateChangeReasonHasBeenSet(false),
    m_submissionDateTimeHasBeenSet(false),
    m_completionDateTimeHasBeenSet(false)
{
  *this = jsonValue;
}

QueryExecutionStatus& QueryExecutionStatus::operator =(JsonView jsonValue)
{
  if(jsonValue.ValueExists("State"))
  {
    m_state = QueryExecutionStateMapper::GetQueryExecutionStateForName(jsonValue.GetString("State"));

    m_stateHasBeenSet = true;
  }

  if(jsonValue.ValueExists("StateChangeReason"))
  {
    m_stateChangeReason = jsonValue.GetString("StateChangeReason");

    m_stateChangeReasonHasBeenSet = true;
  }

  if(jsonValue.ValueExists("SubmissionDateTime"))
  {
    m_submissionDateTime = jsonValue.GetDouble("SubmissionDateTime");

    m_submissionDateTimeHasBeenSet = true;
  }

  if(jsonValue.ValueExists("CompletionDateTime"))
  {
    m_completionDateTime = jsonValue.GetDouble("CompletionDateTime");

    m_completionDateTimeHasBeenSet = true;
  }

  return *this;
}

JsonValue QueryExecutionStatus::Jsonize() const
{
  JsonValue payload;

  if(m_stateHasBeenSet)
  {
   payload.WithString("State", QueryExecutionStateMapper::GetNameForQueryExecutionState(m_state));
  }

  if(m_stateChangeReasonHasBeenSet)
  {
   payload.WithString("StateChangeReason", m_stateChangeReason);

  }

  if(m_submissionDateTimeHasBeenSet)
  {
   payload.WithDouble("SubmissionDateTime", m_submissionDateTime.SecondsWithMSPrecision());
  }

  if(m_completionDateTimeHasBeenSet)
  {
   payload.WithDouble("CompletionDateTime", m_completionDateTime.SecondsWithMSPrecision());
  }

  return payload;
}

} // namespace Model
} // namespace Athena
} // namespace Aws


text:
package com.ultimate.camera.utilities;

import android.content.AsyncTaskLoader;
import android.content.Context;
import android.os.Environment;

import java.util.List;

import android.content.AsyncTaskLoader;
import android.content.Context;

import com.ultimate.camera.adapters.items.PhotoItem;

import java.util.List;

/**
 * AsyncTask loader used to load image resources in the background of a fragment.
 * Reference: http://developer.android.com/reference/android/content/AsyncTaskLoader.html
 *
 * Created by Rex St. John (on behalf of AirPair.com) on 3/4/14.
 */
public class PhotoGalleryAsyncLoader extends AsyncTaskLoader<List<PhotoItem>> {

    // Persistent list of photo list item
    private List<PhotoItem> mPhotoListItems;

    /**
     * Constructor
     * @param context
     */
    public PhotoGalleryAsyncLoader(Context context) {
        super(context);
    }

    /**
     * Matches code in MediaProvider.computeBucketValues.
     */
    public static String getBucketId(String path) {
        return String.valueOf(path.toLowerCase().hashCode());
    }

    /**
     * Load photo album image items in the background
     *
     * This is where the bulk of our work is done.  This function is
     * called in a background thread and should generate a new set of
     * data to be published by the loader.
     */
    @Override
    public List<PhotoItem> loadInBackground() {
        final Context context = getContext();
        List<PhotoItem> photos = PhotoGalleryImageProvider.getAlbumThumbnails(context);
        return photos;
    }

    /**
     * Called when there is new data to deliver to the client.  The
     * super class will take care of delivering it; the implementation
     * here just adds a little more logic.
     */
    @Override public void deliverResult(List<PhotoItem> newPhotoListItems) {
        if (isReset()) {
            // An async query came in while the loader is stopped.  We
            // don't need the result.
            if (newPhotoListItems != null) {
                onReleaseResources(newPhotoListItems);
            }
        }
        List<PhotoItem> oldPhotos = mPhotoListItems;
        mPhotoListItems = newPhotoListItems;

        if (isStarted()) {
            // If the Loader is currently started, we can immediately
            // deliver its results.
            super.deliverResult(newPhotoListItems);
        }

        // At this point we can release the resources associated with
        // 'oldApps' if needed; now that the new result is delivered we
        // know that it is no longer in use.
        if (oldPhotos != null) {
            onReleaseResources(oldPhotos);
        }
    }

    /**
     * Handles a request to start the Loader.
     */
    @Override protected void onStartLoading() {

        if (mPhotoListItems != null) {
            // If we currently have a result available, deliver it
            // immediately.
            deliverResult(mPhotoListItems);
        } else {
            // If the data has changed since the last time it was loaded
            // or is not currently available, start a load.
            forceLoad();
        }
    }

    /**
     * Handles a request to stop the Loader.
     */
    @Override protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    /**
     * Handles a request to cancel a load.
     */
    @Override public void onCanceled(List<PhotoItem> photoListItems) {
        super.onCanceled(photoListItems);

        // At this point we can release the resources associated with 'apps'
        // if needed.
        onReleaseResources(photoListItems);
    }

    /**
     * Handles a request to completely reset the Loader.
     */
    @Override protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        // At this point we can release the resources associated with 'apps'
        // if needed.
        if (mPhotoListItems != null) {
            onReleaseResources(mPhotoListItems);
            mPhotoListItems = null;
        }
    }

    /**
     * Helper function to take care of releasing resources associated
     * with an actively loaded data set.
     */
    protected void onReleaseResources(List<PhotoItem> photoListItems) {
        // For a simple List<> there is nothing to do.  For something
        // like a Cursor, we would close it here.
    }
}


text:
<?php

namespace Mellivora\Database\Migrations;

use Mellivora\Database\ConnectionResolverInterface as Resolver;
use Mellivora\Support\Arr;
use Mellivora\Support\Collection;
use Mellivora\Support\Str;

class Migrator
{
    /**
     * The migration repository implementation.
     *
     * @var \Mellivora\Database\Migrations\MigrationRepositoryInterface
     */
    protected $repository;

    /**
     * The connection resolver instance.
     *
     * @var \Mellivora\Database\ConnectionResolverInterface
     */
    protected $resolver;

    /**
     * The name of the default connection.
     *
     * @var string
     */
    protected $connection;

    /**
     * The notes for the current operation.
     *
     * @var array
     */
    protected $notes = [];

    /**
     * The paths to all of the migration files.
     *
     * @var array
     */
    protected $paths = [];

    /**
     * Create a new migrator instance.
     *
     * @param \Mellivora\Database\Migrations\MigrationRepositoryInterface $repository
     * @param \Mellivora\Database\ConnectionResolverInterface             $resolver
     *
     * @return void
     */
    public function __construct(MigrationRepositoryInterface $repository, Resolver $resolver)
    {
        $this->resolver   = $resolver;
        $this->repository = $repository;
    }

    /**
     * Run the pending migrations at a given path.
     *
     * @param array|string $paths
     * @param array        $options
     *
     * @return array
     */
    public function run($paths = [], array $options = [])
    {
        $this->notes = [];

        // Once we grab all of the migration files for the path, we will compare them
        // against the migrations that have already been run for this package then
        // run each of the outstanding migrations against a database connection.
        $files = $this->getMigrationFiles($paths);

        $this->requireFiles($migrations = $this->pendingMigrations(
            $files,
            $this->repository->getRan()
        ));

        // Once we have all these migrations that are outstanding we are ready to run
        // we will go ahead and run them "up". This will execute each migration as
        // an operation against a database. Then we'll return this list of them.
        $this->runPending($migrations, $options);

        return $migrations;
    }

    /**
     * Get the migration files that have not yet run.
     *
     * @param array $files
     * @param array $ran
     *
     * @return array
     */
    protected function pendingMigrations($files, $ran)
    {
        return Collection::make($files)
            ->reject(function ($file) use ($ran) {
                return in_array($this->getMigrationName($file), $ran);
            })->values()->all();
    }

    /**
     * Run an array of migrations.
     *
     * @param array $migrations
     * @param array $options
     *
     * @return void
     */
    public function runPending(array $migrations, array $options = [])
    {
        // First we will just make sure that there are any migrations to run. If there
        // aren't, we will just make a note of it to the developer so they're aware
        // that all of the migrations have been run against this database system.
        if (count($migrations) === 0) {
            $this->note('<info>Nothing to migrate.</info>');

            return;
        }

        // Next, we will get the next batch number for the migrations so we can insert
        // correct batch number in the database migrations repository when we store
        // each migration's execution. We will also extract a few of the options.
        $batch = $this->repository->getNextBatchNumber();

        $pretend = Arr::get($options, 'pretend', false);

        $step = Arr::get($options, 'step', false);

        // Once we have the array of migrations, we will spin through them and run the
        // migrations "up" so the changes are made to the databases. We'll then log
        // that the migration was run so we don't repeat it next time we execute.
        foreach ($migrations as $file) {
            $this->runUp($file, $batch, $pretend);

            if ($step) {
                ++$batch;
            }
        }
    }

    /**
     * Run "up" a migration instance.
     *
     * @param string $file
     * @param int    $batch
     * @param bool   $pretend
     *
     * @return void
     */
    protected function runUp($file, $batch, $pretend)
    {
        // First we will resolve a "real" instance of the migration class from this
        // migration file name. Once we have the instances we can run the actual
        // command such as "up" or "down", or we can just simulate the action.
        $migration = $this->resolve(
            $name = $this->getMigrationName($file)
        );

        if ($pretend) {
            return $this->pretendToRun($migration, 'up');
        }

        $this->runMigration($migration, 'up');

        // Once we have run a migrations class, we will log that it was run in this
        // repository so that we don't try to run it next time we do a migration
        // in the application. A migration repository keeps the migrate order.
        $this->repository->log($name, $batch);

        $this->note("<info>Migrated:</info> {$name}");
    }

    /**
     * Rollback the last migration operation.
     *
     * @param array|string $paths
     * @param array        $options
     *
     * @return array
     */
    public function rollback($paths = [], array $options = [])
    {
        $this->notes = [];

        // We want to pull in the last batch of migrations that ran on the previous
        // migration operation. We'll then reverse those migrations and run each
        // of them "down" to reverse the last migration "operation" which ran.
        $migrations = $this->getMigrationsForRollback($options);

        if (count($migrations) === 0) {
            $this->note('<info>Nothing to rollback.</info>');

            return [];
        }

        return $this->rollbackMigrations($migrations, $paths, $options);
    }

    /**
     * Get the migrations for a rollback operation.
     *
     * @param array $options
     *
     * @return array
     */
    protected function getMigrationsForRollback(array $options)
    {
        if (($steps = Arr::get($options, 'step', 0)) > 0) {
            return $this->repository->getMigrations($steps);
        }

        return $this->repository->getLast();
    }

    /**
     * Rollback the given migrations.
     *
     * @param array $migrations
     * @param array $paths
     * @param array $options
     *
     * @return array
     */
    protected function rollbackMigrations(array $migrations, array $paths, array $options)
    {
        $rolledBack = [];

        $this->requireFiles($files = $this->getMigrationFiles($paths));

        // Next we will run through all of the migrations and call the "down" method
        // which will reverse each migration in order. This getLast method on the
        // repository already returns these migration's names in reverse order.
        foreach ($migrations as $migration) {
            $migration = (object) $migration;

            $rolledBack[] = $files[$migration->migration];

            $this->runDown(
                $files[$migration->migration],
                $migration,
                Arr::get($options, 'pretend', false)
            );
        }

        return $rolledBack;
    }

    /**
     * Rolls all of the currently applied migrations back.
     *
     * @param array|string $paths
     * @param bool         $pretend
     *
     * @return array
     */
    public function reset($paths = [], $pretend = false)
    {
        $this->notes = [];

        // Next, we will reverse the migration list so we can run them back in the
        // correct order for resetting this database. This will allow us to get
        // the database back into its "empty" state ready for the migrations.
        $migrations = array_reverse($this->repository->getRan());

        if (count($migrations) === 0) {
            $this->note('<info>Nothing to rollback.</info>');

            return [];
        }

        return $this->resetMigrations($migrations, $paths, $pretend);
    }

    /**
     * Reset the given migrations.
     *
     * @param array $migrations
     * @param array $paths
     * @param bool  $pretend
     *
     * @return array
     */
    protected function resetMigrations(array $migrations, array $paths, $pretend = false)
    {
        // Since the getRan method that retrieves the migration name just gives us the
        // migration name, we will format the names into objects with the name as a
        // property on the objects so that we can pass it to the rollback method.
        $migrations = collect($migrations)->map(function ($m) {
            return (object) ['migration' => $m];
        })->all();

        return $this->rollbackMigrations(
            $migrations,
            $paths,
            compact('pretend')
        );
    }

    /**
     * Run "down" a migration instance.
     *
     * @param string $file
     * @param object $migration
     * @param bool   $pretend
     *
     * @return void
     */
    protected function runDown($file, $migration, $pretend)
    {
        // First we will get the file name of the migration so we can resolve out an
        // instance of the migration. Once we get an instance we can either run a
        // pretend execution of the migration or we can run the real migration.
        $instance = $this->resolve(
            $name = $this->getMigrationName($file)
        );

        if ($pretend) {
            return $this->pretendToRun($instance, 'down');
        }

        $this->runMigration($instance, 'down');

        // Once we have successfully run the migration "down" we will remove it from
        // the migration repository so it will be considered to have not been run
        // by the application then will be able to fire by any later operation.
        $this->repository->delete($migration);

        $this->note("<info>Rolled back:</info> {$name}");
    }

    /**
     * Run a migration inside a transaction if the database supports it.
     *
     * @param object $migration
     * @param string $method
     *
     * @return void
     */
    protected function runMigration($migration, $method)
    {
        $connection = $this->resolveConnection(
            $migration->getConnection()
        );

        $callback = function () use ($migration, $method) {
            $migration->{$method}();
        };

        $this->getSchemaGrammar($connection)->supportsSchemaTransactions()
            ? $connection->transaction($callback)
            : $callback();
    }

    /**
     * Pretend to run the migrations.
     *
     * @param object $migration
     * @param string $method
     *
     * @return void
     */
    protected function pretendToRun($migration, $method)
    {
        foreach ($this->getQueries($migration, $method) as $query) {
            $name = get_class($migration);

            $this->note("<info>{$name}:</info> {$query['query']}");
        }
    }

    /**
     * Get all of the queries that would be run for a migration.
     *
     * @param object $migration
     * @param string $method
     *
     * @return array
     */
    protected function getQueries($migration, $method)
    {
        // Now that we have the connections we can resolve it and pretend to run the
        // queries against the database returning the array of raw SQL statements
        // that would get fired against the database system for this migration.
        $db = $this->resolveConnection(
            $connection = $migration->getConnection()
        );

        return $db->pretend(function () use ($migration, $method) {
            $migration->{$method}();
        });
    }

    /**
     * Resolve a migration instance from a file.
     *
     * @param string $file
     *
     * @return object
     */
    public function resolve($file)
    {
        $class = Str::studly(implode('_', array_slice(explode('_', $file), 4)));

        return new $class;
    }

    /**
     * Get all of the migration files in a given path.
     *
     * @param array|string $paths
     *
     * @return array
     */
    public function getMigrationFiles($paths)
    {
        return Collection::make($paths)->flatMap(function ($path) {
            return glob($path . '/*_*.php');
        })->filter()->sortBy(function ($file) {
            return $this->getMigrationName($file);
        })->values()->keyBy(function ($file) {
            return $this->getMigrationName($file);
        })->all();
    }

    /**
     * Require in all the migration files in a given path.
     *
     * @param array $files
     *
     * @return void
     */
    public function requireFiles(array $files)
    {
        foreach ($files as $file) {
            require_once $file;
        }
    }

    /**
     * Get the name of the migration.
     *
     * @param string $path
     *
     * @return string
     */
    public function getMigrationName($path)
    {
        return str_replace('.php', '', basename($path));
    }

    /**
     * Register a custom migration path.
     *
     * @param string $path
     *
     * @return void
     */
    public function path($path)
    {
        $this->paths = array_unique(array_merge($this->paths, [$path]));
    }

    /**
     * Get all of the custom migration paths.
     *
     * @return array
     */
    public function paths()
    {
        return $this->paths;
    }

    /**
     * Set the default connection name.
     *
     * @param string $name
     *
     * @return void
     */
    public function setConnection($name)
    {
        $this->repository->setSource($name);

        $this->connection = $name;
    }

    /**
     * Resolve the database connection instance.
     *
     * @param string $connection
     *
     * @return \Mellivora\Database\Connection
     */
    public function resolveConnection($connection)
    {
        return $this->resolver->connection($connection ?: $this->connection);
    }

    /**
     * Get the schema grammar out of a migration connection.
     *
     * @param \Mellivora\Database\Connection $connection
     *
     * @return \Mellivora\Database\Schema\Grammars\Grammar
     */
    protected function getSchemaGrammar($connection)
    {
        if (is_null($grammar = $connection->getSchemaGrammar())) {
            $connection->useDefaultSchemaGrammar();

            $grammar = $connection->getSchemaGrammar();
        }

        return $grammar;
    }

    /**
     * Get the migration repository instance.
     *
     * @return \Mellivora\Database\Migrations\MigrationRepositoryInterface
     */
    public function getRepository()
    {
        return $this->repository;
    }

    /**
     * Determine if the migration repository exists.
     *
     * @return bool
     */
    public function repositoryExists()
    {
        return $this->repository->repositoryExists();
    }

    /**
     * Raise a note event for the migrator.
     *
     * @param string $message
     *
     * @return void
     */
    protected function note($message)
    {
        $this->notes[] = $message;
    }

    /**
     * Get the notes for the last operation.
     *
     * @return array
     */
    public function getNotes()
    {
        return $this->notes;
    }
}


text:
#include <android/log.h>
#include "../include/headers.h"
#include "../include/util.h"

#ifdef __cplusplus
extern "C" {
#endif

/* -------------------------------------------------------------------
 * If inMSS > 0, set the TCP maximum segment size  for inSock.
 * Otherwise leave it as the system default.
 * ------------------------------------------------------------------- */

const char warn_mss_fail[] = "\
WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
Setting the MSS may not be implemented on this OS.\n";

const char warn_mss_notset[] =
"WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";

void setsock_tcp_mss( int inSock, int inMSS ) {
#ifdef TCP_MAXSEG
    int rc;
    int newMSS;
    Socklen_t len;

    assert( inSock != INVALID_SOCKET );

    if ( inMSS > 0 ) {
        /* set */
        newMSS = inMSS;
        len = sizeof( newMSS );
        rc = setsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS,  len );
        if ( rc == SOCKET_ERROR ) {
            fprintf( stderr, warn_mss_fail, newMSS );
             __android_log_print(ANDROID_LOG_DEBUG, "LOG_IPERF_SOCKETS_JNI",warn_mss_fail, newMSS );
            return;
        }

        /* verify results */
        rc = getsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, &len );
        WARN_errno( rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG" );
        if ( newMSS != inMSS ) {
            fprintf( stderr, warn_mss_notset, inMSS, newMSS );
             __android_log_print(ANDROID_LOG_DEBUG, "LOG_IPERF_SOCKETS_JNI", warn_mss_notset, inMSS, newMSS );
        }
    }
#endif
} /* end setsock_tcp_mss */

/* -------------------------------------------------------------------
 * returns the TCP maximum segment size
 * ------------------------------------------------------------------- */

int getsock_tcp_mss_i2( int inSock ) {
    int theMSS = 0;

#ifdef TCP_MAXSEG
    int rc;
    Socklen_t len;
    assert( inSock >= 0 );

    /* query for MSS */
    len = sizeof( theMSS );
    rc = getsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &theMSS, &len );
    WARN_errno( rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG" );
#endif

    return theMSS;
} /* end getsock_tcp_mss_i2 */

/* -------------------------------------------------------------------
 * Attempts to reads n bytes from a socket.
 * Returns number actually read, or -1 on error.
 * If number read < inLen then we reached EOF.
 *
 * from Stevens, 1998, section 3.9
 * ------------------------------------------------------------------- */

ssize_t readn( int inSock, void *outBuf, size_t inLen ) {
    size_t  nleft;
    ssize_t nread;
    char *ptr;

    assert( inSock >= 0 );
    assert( outBuf != NULL );
    assert( inLen > 0 );

    ptr   = (char*) outBuf;
    nleft = inLen;

    while ( nleft > 0 ) {
        nread = read( inSock, ptr, nleft );
        if ( nread < 0 ) {
            if ( errno == EINTR )
                nread = 0;  /* interupted, call read again */
            else
                return -1;  /* error */
        } else if ( nread == 0 )
            break;        /* EOF */

        nleft -= nread;
        ptr   += nread;
    }

    return(inLen - nleft);
} /* end readn */

/* -------------------------------------------------------------------
 * Attempts to write  n bytes to a socket.
 * returns number actually written, or -1 on error.
 * number written is always inLen if there is not an error.
 *
 * from Stevens, 1998, section 3.9
 * ------------------------------------------------------------------- */

ssize_t writen( int inSock, const void *inBuf, size_t inLen ) {
    size_t  nleft;
    ssize_t nwritten;
    const char *ptr;

    assert( inSock >= 0 );
    assert( inBuf != NULL );
    assert( inLen > 0 );

    ptr   = (char*) inBuf;
    nleft = inLen;

    while ( nleft > 0 ) {
        nwritten = write( inSock, ptr, nleft );
        if ( nwritten <= 0 ) {
            if ( errno == EINTR )
                nwritten = 0; /* interupted, call write again */
            else
                return -1;    /* error */
        }

        nleft -= nwritten;
        ptr   += nwritten;
    }

    return inLen;
} /* end writen */

#ifdef __cplusplus
} /* end extern "C" */
#endif


text:
Due to operator's requirements, SMS business is available after personal real name certification or enterprise qualification certification.

### Personal Authentication

Support personal developer certification. The content of certification is required and cannot be modified after the certification is passed. Please fill in the personal certification information carefully to avoid affecting the use of the SMS service in the future.

#### Operation Path

Step1: Log in to the console
Step2: Enter your account
Step3: Select [Developer Certification] in the right menu
Step4: Select [Personal] in the Developer Type
![](./consoleguide_image/auth_personal.jpg)

### Enterprise Certification

Support enterprise developer certification. The content of the certification is required and cannot be modified after the certification is passed. Please fill in the enterprise certification information carefully to avoid affecting the future use of SMS services.

#### Operation Path

Step1: Log in to the console
Step2: Enter your account
Step3: Select [Developer Certification] in the right menu
Step4: Select [Enterprise] in the Developer Type
![](./consoleguide_image/auth_company.jpg)

## Create an Application

#### Steps

Step1: Log in to the console
Step2: Click the [Create Application] button
![](./consoleguide_image/app_createbutton.jpg)

Step3: Fill in [Application Name] and [Application Icon]. [Application Name] is required.
![](./consoleguide_image/app_create.jpg)

## Signature Settings

The signature is shown at the top of the text message, indicating which company, which product, or which software the message came from. Due to the operator's request, the signature needs to be used after the audit. Under normal circumstances, the audit cycle is two working days.

#### Operation Path

Step1: Log in to the console
Step2: Enter the SMS service template
Step3: Select [Signature Management] in the right menu
Step4: Click the [New Signature] button
![](./consoleguide_image/sign_createbutton.jpg)

#### Create a Signature

+ The signature supports the upload of 2 to 10 Chinese and English or numbers. Spaces or special symbols are not allowed.
+ When the signature is inconsistent with the developer certification information, please upload the signature related certificate picture;
+ If there is an in-use signature, the new signature created will directly replace the old signature after auditing
![](./consoleguide_image/sign_set.jpg)

## Template Settings

The template is the content of the short message with parameters, and template ID and the corresponding parameter content can be directly filled in when invoking API. Due to the operator's request, the template must be audited before use. Under normal circumstances, the audit cycle is within three hours of the working time.

#### Operation Path

Step1: Log in to the console
Step2: Enter the SMS service template
Step3: Select [Template Management] in the right menu
Step4: Click the [New Template] button
![](./consoleguide_image/mobile_createbutton.jpg)

### Create a Template

+ Template type: Support for creating SMS templates of text verification code, notification SMS templates, and marketing SMS templates;
+ Template format: The format of the parameter in the template is {{key-name}}, where the separator uses two braces;
+ Template of verification code: The parameter name must be code. When multiple parameters are set, the parameter name must be code. Validation period is supported in the verification code template. The valid period must be between 0 and 24 hours, and the unit is second.
 ![](./consoleguide_image/mobile_code.jpg)

+ Notification template: The template must contain at least one parameter and the parameter name is specified by the developer. Only letters and underscores are supported, and underscores are not allowed at the beginning and end;
![](./consoleguide_image/mobile_message.jpg)

+ Marketing template: The template must contain at least one parameter and the parameter name is specified by the developer. Only the letters and underscores are supported, and the underscore is not allowed at the beginning and end. According to the operator's regulations, the marketing message must contain unsubscribe related information. If the system has added "Send TD to unsubscribe" by default, could not fill in the template.
![](./consoleguide_image/mobile_market.jpg)

+ Default template: At present, only the verification code SMS template has a default template. When the signature is not set, the default template uses the signature of [JPush].

## Marketing SMS

In addition to sending by API, marketing messages can also be sent in the website, and supports for scheduled delivery.

### Create Marketing SMS

#### Operation Path

Step1: Log in to the console
Step2: Enter the SMS service template
Step3: Select [Pre-Send List] of [Marketing SMS] in the right menu
Step4: Click the [Create Marketing SMS] button
![](./consoleguide_image/market_createbutton.jpg)

#### Create Marketing SMS

+ The in-use signature will be automatically written. If the signature is not set, set the signature first to create a marketing message;
+ SMS content: Enter the content of the SMS. According to the regulations of the operator, the content of the marketing message must contain unsubscribe related information. If the system has added "Send TD to unsubscribe" by default, could not fill in the template
+ Sending time: Support for instant sending or timing sending. Marketing messages will be sent according to the scheduled time after the audition;
+ Target audience: Upload txt file with a mobile phone in a line;
+ After completing all the contents, click Next and confirm that the information is correct. Click OK and freeze the corresponding balance.
![](./consoleguide_image/market_create.jpg)

View the pre-sending list to check out the review results of the marketing message, and the marketing messages which are not sent yet.

## View Data

+ Data overview to view the application data, including SMS margin, delivery volume and consumption volume;
+ All types of text messages, including: recordings of verification code, notifications, marketing and push supplements, can be viewed in the history record;
+ All uplink SMS messages received can be viewed in the reply log;
+ Sending records of marketing messages can also be viewed in the sending history of marketing messages.