text:
<!doctype html>

    <meta charset="utf-8">
    <title>OptaPlanner presentation</title>
    <meta name="description" content="This slide deck explains OptaPlanner: an open source constraint satisfaction solver in Java">
    <link href="http://www.optaplanner.org/learn/slides/optaplanner-presentation/" rel="canonical">

    <link rel="stylesheet" href="website/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="website/reveal/css/reveal.min.css">
    <link rel="stylesheet" href="website/reveal/css/theme/simple.css" id="theme">

    <link rel="stylesheet" href="website/highlight/highlight.css">
    <link rel="stylesheet" href="website/optaplannerPresentation.css">

    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

        @GeoffreyDeSmet

            Presentation instructions

Press right arrow key to go to the first real slide

Press escape key for an overview of all slides

Tips:

Feel free to reuse slides to promote OptaPlanner

Print to PDF (Google Chrome recommended)

            Do more business

            with less resources

                by Geoffrey De Smet

                OptaPlanner lead

What is business resource optimization?

TSP demo

            TSP

            is an academic problem

            What is realistic

            business resource optimization?

VRP demo

Planning problem use cases

Agenda scheduling: doctor appointments, court hearings,
maintenance jobs, TV advertisements, ...

Educational timetabling: lectures, exams, conference presentations, ...

Task assignment: affinity/skill matchmaking for tax audits, wage calc, ...

Employee shift rostering: nurses, repairmen, help desk, firemen, ...

Vehicle routing: route trucks, buses, trains, boats, airplanes, ...

Bin packing: fill containers, trucks, ships, storage warehouses,
cloud computers nodes, prisons, hospitals, ...

Job shop scheduling: assembly lines for cars, furniture, books, ...

Cutting stock: minimize waste while cutting paper, steel, carpet, ...

Sport scheduling: football/baseball league, tennis court utilization, ...

Financial optimization: investment portfolio balance, risk spreading, ...

            Are planning problems

            difficult to solve?

What is business resource optimization?

Cloud Balancing demo

            Find optimal solution and scale out

            for an NP-complete problem?

⇔ Is P = NP?

Unresolved since 1971

1 000 000 $ reward since 2000

One of the 7 Millennium Problems

Most believe P ≠ NP

⇔ Impossible to find optimal solution and scale out

3000+ known NP-complete problems (wikipedia)

            Planning problems are

            difficult to solve!

And human aren't good at it

But they don't realize it
(nor does their manager)

Reuse optimization algorithms

Find better solutions in time and scale out

Open source
Apache License

Regular releases
Download the zip or from Maven Central

Documented
Reference manual, examples, ...

Quality coverage
Unit, integration and stress tests

Cloud Balancing example

Domain model

Computer

public class Computer {

  private int cpuPower;
  private int memory;
  private int networkBandwidth;

  private int cost;

  // getters
}

Process is a planning entity

@PlanningEntity
public class Process {

  private int requiredCpuPower;
  private int requiredMemory;
  private int requiredNetworkBandwidth;

  // getters

  ...
}

Process has a planning variable

@PlanningEntity
public class Process {
  ...

  private Computer computer;

  @PlanningVariable(valueRangeProviderRefs = {"computerRange"})
  public Computer getComputer() {
    return computer;
  }
  public void setComputer(Computer computer) {
    this.computer = computer;
  }

}

Solution CloudBalance

@PlanningSolution
public class CloudBalance implements Solution<HardSoftScore> {

  private List<Computer> computerList;
  private List<Process> processList;

  @ValueRangeProvider(id = "computerRange")
  public List<Computer> getComputerList() {
    return computerList;
  }

  @PlanningEntityCollectionProperty
  public List<Process> getProcessList() {
    return processList;
  }

  ...
}

Solution CloudBalance: score

public class CloudBalance implements Solution<HardSoftScore> {
  ...

  private HardSoftScore score;

  public HardSoftScore getScore() {
    return score;
  }
  public void setScore(HardSoftScore score) {
    this.score = score;
  }

}

Cloud Balancing example

Score constraints

            Given 2 solutions

            which one is better?

Score calculation

Easy Java

Incremental Java

Drools

Easy Java score calculation

Easy to implement

Bridge an existing system

Slow

public class CloudBalancingEasyScoreCalculator
    implements EasyScoreCalculator<CloudBalance> {

  public Score calculateScore(CloudBalance cb) {
    ...
    return HardSoftScore.valueOf(hardScore, softScore);
  }

}

Incremental Java score calculation

Fast

Solution changes ⇒ recalculate score delta only

Hard to implement

Much boilerplate code

Drools score calculation

Incremental

No boilerplate code

Constraints in Drools Rule Language (DRL)

Declarative (like SQL, regular expression)

Integration opportunities

Drools Workbench

Decision tables

Solution CloudBalance: getProblemFacts()

public class CloudBalance implements Solution<HardSoftScore> {

  private List<Computer> computerList;
  private List<Process> processList;
  ...

  // Used in Drools score rules (DRL)
  public Collection<Object> getProblemFacts() {
    List<Object> facts = new ArrayList<Object>();
    facts.addAll(computerList);
    return facts;
  }

  ...
}

DRL soft constraint: computer cost

rule "computerCost"
  when
    // there is a computer
    $s : Computer($c : cost)
    // there is a processes on that computer
    exists Process(computer == $s)
  then
    // lower soft score by the maintenance cost
    scoreHolder.addSoftConstraintMatch(kcontext, - $c);
end

DRL hard constraint: CPU power

rule "requiredCpuPowerTotal"
  when
    // there is a computer
    $s : Computer($cpu : cpuPower)
    // with too little cpu for its processes
    $total : Number(intValue > $cpu) from accumulate(
      Process(computer == $s, $requiredCpu : requiredCpuPower),
      sum($requiredCpu)
    )
  then
    // lower hard score by the excessive CPU usage
    scoreHolder.addHardConstraintMatch(kcontext,
        $cpu - $total.intValue());
end

Score calculation must be flexible

Optimal solution for almost your business problem is useless

                Model supports:

Reusing existing classes

Rich, OO class hierarchies (including polymorphism)

                Constraints supports:

Any constraint (no linear or quadratic restrictions!)

Reusing existing code

                Scoring supports:

Positive/negative mix

Score weights

Unlimited score levels

Cloud Balancing example

Solving it

Solver configuration by XML

<solver>
  <solutionClass>...CloudBalance</solutionClass>
  <entityClass>...Process</entityClass>

  <scoreDirectorFactory>
    <scoreDefinitionType>HARD_AND_SOFT</scoreDefinitionType>
    <scoreDrl>...ScoreRules.drl</scoreDrl>
  </scoreDirectorFactory>

  <!-- optimization algorithms -->
</solver>

Solving

SolverFactory factory = SolverFactory.createFromXmlResource(
    "...SolverConfig.xml");
Solver solver = factory.buildSolver();

solver.solve(cloudBalance);
cloudBalance = (CloudBalance) solver.getBestSolution();

Cloud Balancing example

Optimization algorithms

Brute Force config

<solver>
  ...

  <exhaustiveSearch>
    <exhaustiveSearchType>BRUTE_FORCE</exhaustiveSearchType>
  </exhaustiveSearch>
</solver>

Brute Force scalability

Plan 1200 processes with Brute Force?

First Fit config

<solver>
  ...

  <constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
  </constructionHeuristic>
</solver>

First Fit scalability

First Fit results

All hard constraints satisfied: maintenance cost shown

First Fit Decreasing config

<solver>
  ...

  <constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
  </constructionHeuristic>
</solver>

DifficultyComparator

public class ProcessDifficultyComparator
    implements Comparator<Process> {
  public int compare(Process a, Process b) {
    // Compare on requiredCpuPower * requiredMemory
    //     * requiredNetworkBandwidth
  }
}

@PlanningEntity(difficultyComparatorClass
    = ProcessDifficultyComparator.class)
public class Process  {
  ...
}

First Fit Decreasing scalability

First Fit Decreasing results

Construction Heuristics + Local Search

<solver>
  ...

  <constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
  </constructionHeuristic>
  <localSearch>
    ...
  <localSearch>
</solver>

Hill Climbing config

<localSearch>
  <forager>
    <!-- Untweaked standard value -->
    <acceptedCountLimit>1000</acceptedCountLimit>
  </forager>
</localSearch>

Tabu Search config

<localSearch>
  <acceptor>
    <!-- Typical standard value -->
    <entityTabuSize>7</entityTabuSize>
  </acceptor>
  <forager>
    <!-- Typical value -->
    <acceptedCountLimit>1000</acceptedCountLimit>
  </forager>
</localSearch>

Simulated Annealing config

<localSearch>
  <acceptor>
    <!-- Tweaked value -->
    <simulatedAnnealingStartingTemperature>
        0hard/400soft
    </simulatedAnnealingStartingTemperature>
  </acceptor>
  <forager>
    <!-- Typical value -->
    <acceptedCountLimit>4</acceptedCountLimit>
  </forager>
</localSearch>

Late Acceptance config

<localSearch>
  <acceptor>
    <!-- Typical standard value -->
    <lateAcceptanceSize>400</lateAcceptanceSize>
  </acceptor>
  <forager>
    <!-- Typical value -->
    <acceptedCountLimit>4</acceptedCountLimit>
  </forager>
</localSearch>

Local Search results

Cost ($) reduction

Optimization algorithms

                Exhaustive Search

Brute Force

Branch And Bound

                Construction Heuristics

First Fit (Decreasing)

Weakest/Strongest Fit (Decreasing)

Cheapest Insertion

                Metaheuristics (Local Search, ...)

Hill Climbing

Tabu Search

Strategic Oscillation Tabu Search

Simulated Annealing

Late Acceptance

Step Counting Hill Climbing

Benchmark results

Demo

Gain by using OptaPlanner

                Use case
                Gain type
                Avg
                Min
                Max

                Cloud Balancing
                Maintenance cost 1
                -18%
                -16%
                -21%

                Machine Reassignment
                Unbalanced load 2
                -63%
                -25%
                -97%

                Vehicle Routing
(Belgium datasets)
                Distance 1
                -20%
                -7%
                -27%

                Nurse rostering
                Unhappiness 1
                -34%
                -20%
                -83%

                Course scheduling
                Unhappiness 1
                -66%
                -26%
                -100%

            OptaPlanner in a 5 minute run

            1 Compared to traditional algorithms with domain knowledge.

            2 Compared to initial assignments.

Repeated planning:
continuous/real-time

            Continuous planning demo

Nurse rostering demo

Summary

OptaPlanner solves planning and scheduling problems

Adding constraints: easy and scalable

Switching/combining optimization algorithms: easy

Build from source

https://github.com/droolsjbpm/optaplanner

$ git clone git@github.com:droolsjbpm/optaplanner.git
...
$ cd optaplanner
$ mvn clean install -DskipTests
...
$ cd optaplanner-examples
$ mvn exec:java
...

Q & A

OptaPlanner homepage

http://www.optaplanner.org

Reference manual

http://www.optaplanner.org/learn/documentation.html

Download/fork this presentation

http://www.optaplanner.org/learn/slides.html

What did you think of this presentation?

Twitter: @GeoffreyDeSmet

Google+: +GeoffreyDeSmet

            Introduction to

            heuristics and metaheuristics

            for

            business resource optimization

                by Geoffrey De Smet

                OptaPlanner lead

N Queens demo

demo

Simplified problem

N Queens

Place n queens on a n sizes chessboard

No 2 queens can attach each other

Bad

Good

Imperfect example

Not NP-complete (shortcuts exist)

Score function is too simple (too black and white)

What solution is better?

Need for objective scoring

Better score ⇔ better solution

Highest score ⇔ optimal solution

N Queens

Hard constraints:

-1 for every pair of conflicting queens

Soft constraints:

None

Score = -2

Conflicts: A-B, B-D

Score = 0

No conflicts

How do we find the best solution?

Need for optimization algorithms

Best solution in available time

Brute Force scalability

                8 queens = 15.7 seconds

                9 queens = 2.5 minutes (times 10)

                10 queens = 0.83 hours (times 20)

How many combinations for 100 queens?

1 queen per column

100 queens ⇒ 100 variables

100 rows ⇒ 100 values per variable

Source: NASA (wikipedia)

                    > humans?

                    7 000 000 000

How many combinations for 100 queens?

1 queen per column

100 queens ⇒ 100 variables

100 rows ⇒ 100 values per variable

Source: NASA and ESA (wikipedia)

                    > minimum atoms

                    in the observable universe?

                    1080

How many combinations for 100 queens?

1 queen per column

100 queens ⇒ 100 variables

100 rows ⇒ 100 values per variable

                100100 = 10200

                1 0000000000 0000000000 0000000000 0000000000 0000000000

                  0000000000 0000000000 0000000000 0000000000 0000000000

                  0000000000 0000000000 0000000000 0000000000 0000000000

                  0000000000 0000000000 0000000000 0000000000 0000000000

How many combinations for n queens?

1 queen per column

n queens ⇒ n variables

n rows ⇒ n values per variable

                nn

                |valueSet||variableSet|

How long?

Presume 109 scores/ms ⇒ 1020 scores/year

                    Queens
                    Combinations
                    Calculation time

                    100
                    100100 = 10200
                    10180 years

                    1000
                    10001000 = 103000
                    102980 years

                    10000
                    1000010000 = 1040000
                    1039980 years

Moore's law == a drop in the ocean

Exhaustive Search doesn't scale

Branches explode exponentially

Not enough CPU

Not enough memory

Move types

Change move

Swap move

...

All change moves

                            n
                            # moves
                            # solutions

                            4
                            16
                            256

                            8
                            64
                            16777216

                            64
                            4096
                            10116

                            n
                            n2
                            nn

Multiple moves

Multiple moves can reach any solution

Performance tricks

Reuse existing business code

public class Nurse {

  private Country country;

  public boolean isHoliday(Date date) {
    if (country == Country.BE) {
      // true if date is 1-JAN, easter monday, 21-JUL, ...
    } else if (country == Country.FR) {
      // true if date is 1-JAN, easter monday, 14-JUL, ...
    } else if (...) {
      ...
    }
    ...
  }

}

Assumption: An optimal VRP route uses only 1 vehicle.

Assumption: An optimal VRP route uses only 1 vehicle. (false)

Assumption: An optimal VRP route has no crossing lines.

Assumption: An optimal VRP route has no crossing lines. (false)

Assumption: An optimal, feasible VRP route with n vehicles is still optimal for n+1 vehicles.

Assumption: An optimal, feasible VRP route with n vehicles is still optimal for n+1 vehicles. (false)

Assumption: An optimal VRP route has no crossing lines of the same color.

Assumption: An optimal VRP route has no crossing lines of the same color. (false)

Assumption: We can focus on time windows before focusing on capacity (or vice versa).

Assumption: We can focus on time windows before focusing on capacity (or vice versa). (false)

Assumption: Humans optimize VRP optimally.

Assumption: Humans optimize VRP optimally. (false)

Can a manager reasonable judge if this is optimal?

Who's in control?

The user is in control

Course scheduling demo

Teacher, Course, Room

class Teacher {
            ...
            }

class Course {
            Teacher teacher;
            ...
            }

class Period {
            ...
            }

class Room {
            ...
            }

Lecture

@PlanningEntity
            class Lecture {
            Course course;
            int lectureIndexInCourse;

            @PlanningVariable(...) Period period;
            @PlanningVariable(...) Room room;
            ...
            }

Add a constraint

With Java

class UnavailablePeriodPenalty {
            Course course;
            Period period;
            ...
            }

public HardSoftScore calculateScore(Schedule schedule);
            int hardScore = 0;
            for (UnavailablePeriodPenalty penalty : schedule.getPenaltyList()) {
            for (Lecture lecture : schedule.getLectureList()) {
            if (penalty.getCourse() == lecture.getCourse()
            && penalty.getPeriod() == lecture.getPeriod()) {
            hardScore--;
            }
            }
            }
            ...
            return HardSoftScore.valueOf(hardScore, softScore);
            }

With Drools rule engine

class UnavailablePeriodPenalty {
            Course course;
            Period period;
            ...
            }

rule "unavailablePeriodPenalty"
            when
            // When a course is unavailable for a certain period ...
            UnavailablePeriodPenalty($c : course, $p : period)
            // ... and a lecture of that course is scheduled in that period ...
            Lecture(course == $c, period == $p)
            then
            // ... then we lose 1 hard score point
            scoreHolder.addHardConstraintMatch(kcontext, -1);
            end

Q & A

OptaPlanner homepage

http://www.optaplanner.org

Reference manual

http://www.optaplanner.org/learn/documentation.html

Download/fork this presentation

http://www.optaplanner.org/learn/slides.html

What did you think of this presentation?

Twitter: @GeoffreyDeSmet

Google+: +GeoffreyDeSmet


text:
#import "UIViewController.h"

#import "PUAvalancheReviewCollectionViewLayoutDelegate-Protocol.h"
#import "PUPhotosSharingGridCellDelegate-Protocol.h"
#import "PUPhotosSharingTransitionViewController-Protocol.h"
#import "PUReviewScrubberDataSource-Protocol.h"
#import "PUReviewScrubberDelegate-Protocol.h"
#import "UICollectionViewDataSource-Protocol.h"
#import "UICollectionViewDelegate-Protocol.h"
#import "UIGestureRecognizerDelegate-Protocol.h"

@class NSIndexPath, NSMutableSet, PLAvalanche, PLManagedAsset, PUAvalancheReporter, PUAvalancheReviewCollectionViewLayout, PUAvalancheReviewControllerSpec, PUImageManager, PUPhotoBrowserController, PUPhotosSharingTransitionContext, PUReviewInstructionalView, PUReviewScrubber, UIBarButtonItem, UICollectionView, UICollectionViewLayout, UITapGestureRecognizer;

@interface PUAvalancheReviewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource, PUReviewScrubberDataSource, PUReviewScrubberDelegate, PUAvalancheReviewCollectionViewLayoutDelegate, UIGestureRecognizerDelegate, PUPhotosSharingGridCellDelegate, PUPhotosSharingTransitionViewController>
{
    _Bool __updatingContentOffsetFromScrubbing;
    _Bool __completingReviewMode;
    id <PUAvalancheReviewControllerDelegate> _delegate;
    id <PLAssetContainerList> _avalancheContainerList;
    PUAvalancheReviewControllerSpec *__spec;
    UICollectionView *__collectionView;
    PUAvalancheReviewCollectionViewLayout *__collectionViewLayout;
    PUReviewInstructionalView *__instructionalView;
    UIBarButtonItem *__doneBarButtonItem;
    UIBarButtonItem *__cancelBarButtonItem;
    UITapGestureRecognizer *__tapGestureRecognizer;
    NSIndexPath *__inFlightReferenceIndexPath;
    NSMutableSet *__preheatedAssets;
    PLAvalanche *__avalancheBeingReviewed;
    PLManagedAsset *__initialAsset;
    id <PLAssetContainer> __currentAssetContainer;
    PUPhotoBrowserController *__presentingPhotoBrowserController;
    UIBarButtonItem *__reportBarButtonItem;
    PUAvalancheReporter *__avalancheReporter;
    PUImageManager *__imageManager;
    UICollectionViewLayout *__transitionLayout;
    PUPhotosSharingTransitionContext *_photosSharingTransitionContext;
}

+ (id)filteringContext;
@property(retain, nonatomic) PUPhotosSharingTransitionContext *photosSharingTransitionContext; // @synthesize photosSharingTransitionContext=_photosSharingTransitionContext;
@property(retain, nonatomic, setter=_setTransitionLayout:) UICollectionViewLayout *_transitionLayout; // @synthesize _transitionLayout=__transitionLayout;
@property(readonly, nonatomic) PUImageManager *_imageManager; // @synthesize _imageManager=__imageManager;
@property(readonly, nonatomic) PUAvalancheReporter *_avalancheReporter; // @synthesize _avalancheReporter=__avalancheReporter;
@property(readonly, nonatomic) UIBarButtonItem *_reportBarButtonItem; // @synthesize _reportBarButtonItem=__reportBarButtonItem;
@property(readonly, nonatomic) PUPhotoBrowserController *_presentingPhotoBrowserController; // @synthesize _presentingPhotoBrowserController=__presentingPhotoBrowserController;
@property(readonly, nonatomic) id <PLAssetContainer> _currentAssetContainer; // @synthesize _currentAssetContainer=__currentAssetContainer;
@property(readonly, nonatomic) PLManagedAsset *_initialAsset; // @synthesize _initialAsset=__initialAsset;
@property(readonly, nonatomic) PLAvalanche *_avalancheBeingReviewed; // @synthesize _avalancheBeingReviewed=__avalancheBeingReviewed;
@property(nonatomic) _Bool _completingReviewMode; // @synthesize _completingReviewMode=__completingReviewMode;
@property(readonly, nonatomic) _Bool _updatingContentOffsetFromScrubbing; // @synthesize _updatingContentOffsetFromScrubbing=__updatingContentOffsetFromScrubbing;
@property(retain, nonatomic, setter=_setPreheatedAssets:) NSMutableSet *_preheatedAssets; // @synthesize _preheatedAssets=__preheatedAssets;
@property(readonly, nonatomic) NSIndexPath *_inFlightReferenceIndexPath; // @synthesize _inFlightReferenceIndexPath=__inFlightReferenceIndexPath;
@property(readonly, nonatomic) UITapGestureRecognizer *_tapGestureRecognizer; // @synthesize _tapGestureRecognizer=__tapGestureRecognizer;
@property(readonly, nonatomic) UIBarButtonItem *_cancelBarButtonItem; // @synthesize _cancelBarButtonItem=__cancelBarButtonItem;
@property(readonly, nonatomic) UIBarButtonItem *_doneBarButtonItem; // @synthesize _doneBarButtonItem=__doneBarButtonItem;
@property(readonly, nonatomic) PUReviewInstructionalView *_instructionalView; // @synthesize _instructionalView=__instructionalView;
@property(readonly, nonatomic) PUAvalancheReviewCollectionViewLayout *_collectionViewLayout; // @synthesize _collectionViewLayout=__collectionViewLayout;
@property(readonly, nonatomic) UICollectionView *_collectionView; // @synthesize _collectionView=__collectionView;
@property(readonly, nonatomic) PUAvalancheReviewControllerSpec *_spec; // @synthesize _spec=__spec;
@property(readonly, nonatomic) id <PLAssetContainerList> avalancheContainerList; // @synthesize avalancheContainerList=_avalancheContainerList;
@property(nonatomic) id <PUAvalancheReviewControllerDelegate> delegate; // @synthesize delegate=_delegate;
- (void).cxx_destruct;
- (id)photosSharingGridCellViewForZooming:(id)arg1;
- (id)photosSharingGridCellBadgeForZooming:(id)arg1 layoutAnchor:(unsigned long long *)arg2;
- (void)photosSharingGridCellDidEndZooming:(id)arg1;
- (_Bool)photosSharingGridCellShouldBeginZooming:(id)arg1;
- (struct CGRect)embeddedActivityViewFrameWhenShowing:(_Bool)arg1;
- (id)embeddedActivityView;
- (void)setPhotosSharingTransitionLayout:(id)arg1 animated:(_Bool)arg2;
- (id)transitionCollectionView;
- (_Bool)gestureRecognizer:(id)arg1 shouldRecognizeSimultaneouslyWithGestureRecognizer:(id)arg2;
- (unsigned long long)numberOfPhotosInReviewScrubber:(id)arg1;
- (void)reviewScrubberDidSelectItemAtIndexPath:(id)arg1;
- (void)reviewScrubberDidScrub:(id)arg1;
- (void)reviewScrubber:(id)arg1 willDisplayCell:(id)arg2 atIndexPath:(id)arg3;
- (struct CGRect)layout:(id)arg1 collectionView:(id)arg2 selectionBadgeFrameForItemFrame:(struct CGRect)arg3 atIndexPath:(id)arg4;
- (struct CGSize)layout:(id)arg1 collectionView:(id)arg2 sizeForItemAtIndexPath:(id)arg3;
- (id)collectionView:(id)arg1 viewForSupplementaryElementOfKind:(id)arg2 atIndexPath:(id)arg3;
- (id)collectionView:(id)arg1 cellForItemAtIndexPath:(id)arg2;
- (long long)collectionView:(id)arg1 numberOfItemsInSection:(long long)arg2;
- (long long)numberOfSectionsInCollectionView:(id)arg1;
- (_Bool)collectionView:(id)arg1 shouldSelectItemAtIndexPath:(id)arg2;
- (void)scrollViewWillEndDragging:(id)arg1 withVelocity:(struct CGPoint)arg2 targetContentOffset:(inout struct CGPoint *)arg3;
- (void)scrollViewDidEndDecelerating:(id)arg1;
- (void)scrollViewDidEndDragging:(id)arg1 willDecelerate:(_Bool)arg2;
- (void)scrollViewDidScroll:(id)arg1;
- (void)scrollViewWillBeginDragging:(id)arg1;
- (void)_updatePreheatedAssets;
- (void)assetContainerDidChange:(id)arg1;
- (void)_reportButtonAction:(id)arg1;
- (void)_cancelReviewModeAction:(id)arg1;
- (void)_cancelReviewMode;
- (void)_finishReviewModeAction:(id)arg1;
- (void)_crossfadeToAssetAndDismiss:(id)arg1;
- (void)_dismissReviewController;
- (id)_actionViewRootView;
- (void)_reallyToggleCurrentPickStatusAtIndexPath:(id)arg1;
- (void)_toggleCurrentPickStatusAtIndexPath:(id)arg1;
- (void)_promoteFavoriteAssetsWithReviewCompletionHandler:(id)arg1;
- (void)_reloadAvalancheDataWithAsset:(id)arg1;
- (void)_updateReviewScrubberFromContentOffset;
- (int)reviewScrubberImageFormat;
@property(readonly, nonatomic) PUReviewScrubber *_reviewScrubber;
- (void)_updateCollectionViewLayoutInsets;
- (id)_selectionViewAtIndexPath:(id)arg1 forCollectionView:(id)arg2;
- (id)_indexPathInCollectionView:(id)arg1 closestToPoint:(struct CGPoint)arg2 excludingIndexPath:(id)arg3;
- (double)_horizontalOffsetInCollectionView:(id)arg1 forCenteringOnItemAtIndexPath:(id)arg2;
- (id)_indexPathOfCenterVisibleItemInCollectionView:(id)arg1;
- (void)_pageToIndexPath:(id)arg1 animated:(_Bool)arg2;
- (struct CGSize)_sizeForItemAtIndexPath:(id)arg1 interfaceOrientation:(long long)arg2;
- (id)_assetAtIndexPath:(id)arg1;
- (id)_currentAsset;
- (void)_handleTapInMainCollectionView:(id)arg1;
- (void)_handleTapAtIndexPath:(id)arg1;
- (struct CGRect)selectionBadgeFrameForItemFrame:(struct CGRect)arg1 atIndexPath:(id)arg2;
- (void)_updateCell:(id)arg1 forItemAtIndexPath:(id)arg2;
- (void)_getFirstValidIndexPath:(id *)arg1 lastValidIndexPath:(id *)arg2;
- (void)_getMainCollectionViewFrame:(struct CGRect *)arg1 collectionViewLayoutInsets:(struct UIEdgeInsets *)arg2 orientation:(long long)arg3;
- (void)_updateMainViewAnimated:(_Bool)arg1;
- (void)_updateBarItemsAnimated:(_Bool)arg1;
- (void)_updateNavigationItemTitle;
- (void)_updateEnabledNavigationBarItems;
- (_Bool)shouldAutorotateToInterfaceOrientation:(long long)arg1;
- (unsigned long long)supportedInterfaceOrientations;
- (_Bool)shouldAutorotate;
- (_Bool)automaticallyAdjustsScrollViewInsets;
- (void)didRotateFromInterfaceOrientation:(long long)arg1;
- (void)willAnimateRotationToInterfaceOrientation:(long long)arg1 duration:(double)arg2;
- (void)willRotateToInterfaceOrientation:(long long)arg1 duration:(double)arg2;
- (_Bool)pu_wantsNavigationBarVisible;
- (_Bool)pu_wantsStatusBarVisible;
- (_Bool)pu_wantsTabBarVisible;
- (_Bool)pu_wantsToolbarVisible;
- (void)viewWillLayoutSubviews;
- (void)viewWillAppear:(_Bool)arg1;
- (void)dealloc;
- (void)viewDidLoad;
- (id)initWithSpec:(id)arg1 startingAtAsset:(id)arg2 inAvalanche:(id)arg3 currentAssetContainer:(id)arg4 fromPhotoBrowserController:(id)arg5;

@end

redpajama_set_name: RedPajamaGithub


text:
using System;

using OpenMetaverse;
using OpenMetaverse.Rendering;

namespace AvatarPreview
{
    /// <summary>
    /// Subclass of LindenMesh that adds vertex, index, and texture coordinate
    /// arrays suitable for pushing direct to OpenGL
    /// </summary>
    public class GLMesh : LindenMesh
    {
        /// <summary>
        /// Subclass of LODMesh that adds an index array suitable for pushing
        /// direct to OpenGL
        /// </summary>
        new public class LODMesh : LindenMesh.LODMesh
        {
            public ushort[] Indices;

            public override void LoadMesh(string filename)
            {
                base.LoadMesh(filename);

                // Generate the index array
                Indices = new ushort[_numFaces * 3];
                int current = 0;
                for (int i = 0; i < _numFaces; i++)
                {
                    Indices[current++] = (ushort)_faces[i].Indices[0];
                    Indices[current++] = (ushort)_faces[i].Indices[1];
                    Indices[current++] = (ushort)_faces[i].Indices[2];
                }
            }
        }

        /// <summary>
        ///
        /// </summary>
        public struct GLData
        {
            public float[] Vertices;
            public ushort[] Indices;
            public float[] TexCoords;
            public Vector3 Center;
        }

        public GLData RenderData;

        public GLMesh(string name)
            : base(name)
        {
        }

        public override void LoadMesh(string filename)
        {
            base.LoadMesh(filename);

            float minX, minY, minZ;
            minX = minY = minZ = Single.MaxValue;
            float maxX, maxY, maxZ;
            maxX = maxY = maxZ = Single.MinValue;

            // Generate the vertex array
            RenderData.Vertices = new float[NumVertices * 3];
            int current = 0;
            for (int i = 0; i < NumVertices; i++)
            {
                RenderData.Vertices[current++] = Vertices[i].Coord.X;
                RenderData.Vertices[current++] = Vertices[i].Coord.Y;
                RenderData.Vertices[current++] = Vertices[i].Coord.Z;

                if (Vertices[i].Coord.X < minX)
                    minX = Vertices[i].Coord.X;
                else if (Vertices[i].Coord.X > maxX)
                    maxX = Vertices[i].Coord.X;

                if (Vertices[i].Coord.Y < minY)
                    minY = Vertices[i].Coord.Y;
                else if (Vertices[i].Coord.Y > maxY)
                    maxY = Vertices[i].Coord.Y;

                if (Vertices[i].Coord.Z < minZ)
                    minZ = Vertices[i].Coord.Z;
                else if (Vertices[i].Coord.Z > maxZ)
                    maxZ = Vertices[i].Coord.Z;
            }

            // Calculate the center-point from the bounding box edges
            RenderData.Center = new Vector3((minX + maxX) / 2, (minY + maxY) / 2, (minZ + maxZ) / 2);

            // Generate the index array
            RenderData.Indices = new ushort[NumFaces * 3];
            current = 0;
            for (int i = 0; i < NumFaces; i++)
            {
                RenderData.Indices[current++] = (ushort)Faces[i].Indices[0];
                RenderData.Indices[current++] = (ushort)Faces[i].Indices[1];
                RenderData.Indices[current++] = (ushort)Faces[i].Indices[2];
            }

            // Generate the texcoord array
            RenderData.TexCoords = new float[NumVertices * 2];
            current = 0;
            for (int i = 0; i < NumVertices; i++)
            {
                RenderData.TexCoords[current++] = Vertices[i].TexCoord.X;
                RenderData.TexCoords[current++] = Vertices[i].TexCoord.Y;
            }
        }

        public override void LoadLODMesh(int level, string filename)
        {
            LODMesh lod = new LODMesh();
            lod.LoadMesh(filename);
            LodMeshes[level] = lod;
        }
    }
}


text:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "jingle/notifier/communicator/login_settings.h"

#include <cstddef>

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h"

namespace notifier {

namespace {

const char kAuthMechanism[] = "auth_mechanism";

class LoginSettingsTest : public ::testing::Test {
 protected:
  LoginSettingsTest() {
    servers_.push_back(
        ServerInformation(
            net::HostPortPair("default.com", 100),
            DOES_NOT_SUPPORT_SSLTCP));
  }

  ServerList servers_;
};

TEST_F(LoginSettingsTest, Basic) {
  const LoginSettings login_settings(buzz::XmppClientSettings(),
                                     NULL,
                                     servers_,
                                     false /* try_ssltcp_first */,
                                     kAuthMechanism);
  EXPECT_EQ(base::Time(), login_settings.GetRedirectExpirationForTest());
  const ServerList& servers = login_settings.GetServers();
  ASSERT_EQ(servers_.size(), servers.size());
  for (size_t i = 0; i < servers.size(); ++i) {
    EXPECT_TRUE(servers[i].Equals(servers_[i]));
  }
}

TEST_F(LoginSettingsTest, Redirect) {
  LoginSettings login_settings(buzz::XmppClientSettings(),
                               NULL,
                               servers_,
                               false /* try_ssltcp_first */,
                               kAuthMechanism);
  const ServerInformation redirect_server(
      net::HostPortPair("redirect.com", 200),
      SUPPORTS_SSLTCP);
  login_settings.SetRedirectServer(redirect_server);

  {
    const ServerList& servers =
        login_settings.GetServersForTimeForTest(
            login_settings.GetRedirectExpirationForTest() -
            base::TimeDelta::FromMilliseconds(1));
    ASSERT_EQ(servers_.size(), 1u);
    EXPECT_TRUE(servers[0].Equals(redirect_server));
  }

  {
    const ServerList& servers =
        login_settings.GetServersForTimeForTest(
            login_settings.GetRedirectExpirationForTest());
    ASSERT_EQ(servers_.size(), servers.size());
    for (size_t i = 0; i < servers.size(); ++i) {
      EXPECT_TRUE(servers[i].Equals(servers_[i]));
    }
  }
}

}  // namespace

}  // namespace notifier


text:
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

public class NetTCPServer
{
    public int _maxConnections = 5000;
    public int _sendTimeout = 3;
    public int _revTimeout = 3;

    Socket _listener;

    int _port = 0;

    private NetworkManager _netMgr = null;

    public NetTCPServer()
    {
        _netMgr = NetworkManager.Instance;
    }

    public bool CreateTcpServer(string ip, int listenPort)
    {
        _port = listenPort;
        _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        foreach (IPAddress address in Dns.GetHostEntry(ip).AddressList)
        {
            try
            {
                IPAddress hostIP = address;
                IPEndPoint ipe = new IPEndPoint(address, _port);

                _listener.Bind(ipe);
                _listener.Listen(_maxConnections);
                _listener.BeginAccept(new System.AsyncCallback(ListenTcpClient), _listener);

                break;

            }
            catch (System.Exception)
            {
                return false;
            }
        }

        return true;
    }

    void ListenTcpClient(System.IAsyncResult ar)
    {
        // bit stream
        NetBitStream stream = new NetBitStream();
        try
        {
            // 取得服务器端的Socket
            // Socket listener = (Socket)ar.AsyncState;

            // 取得客户端的socket
            Socket client = _listener.EndAccept(ar);
            stream._socket = client;

            // 设置 timeout时间
            client.SendTimeout = _sendTimeout;
            client.ReceiveTimeout = _revTimeout;

            // 接收从服务器返回的头信息
            client.BeginReceive(stream.BYTES, 0, NetBitStream.header_length, SocketFlags.None, new System.AsyncCallback(ReceiveHeader), stream);

            // 发送消息 建立一个新的连接
            PushPacket((ushort)MessageIdentifiers.ID.NEW_INCOMING_CONNECTION, "", client);

        }
        catch (System.Exception)
        {
            //出现错误
        }

        // 继续接受其它连接
        _listener.BeginAccept(new System.AsyncCallback(ListenTcpClient), _listener);
    }

    void ReceiveHeader(System.IAsyncResult ar)
    {
        NetBitStream stream = (NetBitStream)ar.AsyncState;

        try
        {
            int read = stream._socket.EndReceive(ar);

            // 服务器断开连接
            if (read < 1)
            {
                // 发送消息 失去一个连接
                PushPacket((ushort)MessageIdentifiers.ID.CONNECTION_LOST, "", stream._socket);
                return;
            }

            // 获得消息体长度
            stream.DecodeHeader();

            // 下一个读取
            stream._socket.BeginReceive(stream.BYTES, NetBitStream.header_length, stream.BodyLength, SocketFlags.None, new System.AsyncCallback(ReceiveBody), stream);
        }
        catch (System.Exception e)
        {
            PushPacket((ushort)MessageIdentifiers.ID.CONNECTION_LOST, e.Message, stream._socket);
        }
    }

    void ReceiveBody(System.IAsyncResult ar)
    {
        NetBitStream stream = (NetBitStream)ar.AsyncState;

        try
        {
            int read = stream._socket.EndReceive(ar);

            // 用户已下线
            if (read < 1)
            {
                PushPacket((ushort)MessageIdentifiers.ID.CONNECTION_LOST, "", stream._socket);
                return;
            }

            // 将收到的消息传入队列
            PushPacket2(stream);

            // 下一个读取
            stream._socket.BeginReceive(stream.BYTES, 0, NetBitStream.header_length, SocketFlags.None, new System.AsyncCallback(ReceiveHeader), stream);

        }
        catch (System.Exception e)
        {
            PushPacket((ushort)MessageIdentifiers.ID.CONNECTION_LOST, e.Message, stream._socket);
        }
    }

    public void Send(NetBitStream bts, Socket peer)
    {

        NetworkStream ns;
        lock (peer)
        {
            ns = new NetworkStream(peer);
        }

        if (ns.CanWrite)
        {
            try
            {
                ns.BeginWrite(bts.BYTES, 0, bts.Length, new System.AsyncCallback(SendCallback), ns);
            }
            catch (System.Exception)
            {
                PushPacket((ushort)MessageIdentifiers.ID.CONNECTION_LOST, "", peer);
            }
        }

    }

    // 发送消息回调
    private void SendCallback(System.IAsyncResult ar)
    {

        NetworkStream ns = (NetworkStream)ar.AsyncState;
        try
        {
            ns.EndWrite(ar);
            ns.Flush();
            ns.Close();
        }
        catch (System.Exception)
        {
            //错误
        }

    }

    // 向Network Manager的队列传递内部消息
    void PushPacket(ushort msgid, string exception, Socket peer)
    {

        NetPacket packet = new NetPacket();
        packet.SetIDOnly(msgid);
        packet._error = exception;
        packet._peer = peer;

        _netMgr.AddPacket(packet);
    }

    // 向Network Manager的队列传递数据
    void PushPacket2(NetBitStream stream)
    {

        NetPacket packet = new NetPacket();
        stream.BYTES.CopyTo(packet._bytes, 0);
        packet._peer = stream._socket;

        _netMgr.AddPacket(packet);
    }
}


text:
import os
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
from django.conf import settings
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator, MaxValueValidator
from fly_project import constants

# This code is triggered whenever a new user has been created and saved to the database
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

# http://stackoverflow.com/questions/14838128/django-rest-framework-token-authentication

class BannedDomain(models.Model):
    class Meta:
        app_label = 'api'
        ordering = ('name',)
        db_table = 'fly_banned_domains'

    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=63, db_index=True, unique=True)
    banned_on = models.DateField(auto_now_add=True, null=True)
    reason = models.CharField(max_length=127, blank=True, null=True)

    def __str__(self):
        return str(self.name)

class BannedIP(models.Model):
    class Meta:
        app_label = 'api'
        ordering = ('address',)
        db_table = 'fly_banned_ips'

    id = models.AutoField(primary_key=True)
    address = models.GenericIPAddressField(db_index=True, unique=True)
    banned_on = models.DateField(auto_now_add=True, null=True)
    reason = models.CharField(max_length=127, blank=True, null=True)

    def __str__(self):
        return str(self.address)

class BannedWord(models.Model):
    class Meta:
        app_label = 'api'
        ordering = ('text',)
        db_table = 'fly_banned_words'

    id = models.AutoField(primary_key=True)
    text = models.CharField(max_length=63, db_index=True, unique=True)
    banned_on = models.DateField(auto_now_add=True, null=True)
    reason = models.CharField(max_length=127, blank=True, null=True)

    def __str__(self):
        return str(self.text)

class ImageUpload(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_image_uploads'

    upload_id = models.AutoField(primary_key=True)
    upload_date = models.DateField(auto_now=True, null=True)
    image = models.ImageField(upload_to='upload', null=True, blank=True)
    user = models.ForeignKey(User, null=True, blank=True,)

    def delete(self, *args, **kwargs):
        """
            Overrided delete functionality to include deleting the local file
            that we have stored on the system. Currently the deletion funciton
            is missing this functionality as it's our responsibility to handle
            the local files.
        """
        if self.image:
            if os.path.isfile(self.image.path):
                os.remove(self.image.path)
        super(ImageUpload, self).delete(*args, **kwargs) # Call the "real" delete() method

    def __str__(self):
        return str(self.upload_id)

class ResourceLink(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_resource_links'

    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=127,)
    url = models.URLField()
    type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(3)],
        choices=constants.RESOURCE_TYPE_OPTIONS,
        default=1,
        db_index=True,
    )

    def __str__(self):
        return str(self.url)

class Goal(models.Model):
    class Meta:
        abstract = True

    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, db_index=True,)

    # Variable to be used to save the initial date this goal was created on.
    created = models.DateTimeField(auto_now_add=True, db_index=True,)

    # Variable controls whether the User has set the Goal and will wait
    # 30 days before this Goal will unlock.
    is_locked = models.BooleanField(default=False)

    # Variable allows the client to find out the goal type
    # through an ajax request
    goal_type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(3)],
        blank=True,
        default=0,
        db_index=True,
    )

    # Variable controls when this particular goal can be closed. Closure
    # involves modifying 'is_closed' and 'earned_xp' values.
    unlocks = models.DateTimeField(null=True, blank=True)

    # Variable controls whether this particular goal was finished and thus
    # cannot be modified after it was closed.
    is_closed = models.BooleanField(default=False, db_index=True,)

    # When 'is_closed=True' variable was set, this variable controls whether
    # the User has actually finished this goal with success or not.
    was_accomplished = models.BooleanField(default=False, db_index=True)

    # When 'is_closed=True' variable was set, this variable controls what
    # amount of experience points where earned for accomplishing it.
    earned_xp = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(9999)],
        default=0,
    )

    def __str__(self):
        return str(self.id)

class SavingsGoalManager(models.Manager):
    def get_latest(self, user_id):
        try:
            return SavingsGoal.objects.filter(user_id=user_id).latest('created')
        except SavingsGoal.DoesNotExist:
            return None

class SavingsGoal(Goal):
    class Meta:
        app_label = 'api'
        db_table = 'fly_savings_goals'

    objects = SavingsGoalManager()
    amount = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0.00,
    )
    times = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(99)],
        default=0,
    )
    period = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(2)],
        choices=constants.INTERVAL_OPTIONS,
        default=1,
    )

class OrderedSavingsGoal(SavingsGoal):
    class Meta:
        ordering = ('-created',)
        proxy = True

class CreditGoalManager(models.Manager):
    def get_latest(self, user_id):
        try:
            return CreditGoal.objects.filter(user_id=user_id).latest('created')
        except CreditGoal.DoesNotExist:
            return None

class CreditGoal(Goal):
    class Meta:
        app_label = 'api'
        db_table = 'fly_credit_goals'

    objects = CreditGoalManager()
    points = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(850)],
        default=0,
    )
    times = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(99)],
        default=0,
    )
    period = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(2)],
        choices=constants.INTERVAL_OPTIONS,
        default=1,
    )

class OrderedCreditGoal(CreditGoal):
    class Meta:
        ordering = ('-created',)
        proxy = True

class FinalGoalManager(models.Manager):
    def get_latest(self, user_id):
        try:
            return FinalGoal.objects.filter(user_id=user_id,).latest('created')
        except FinalGoal.DoesNotExist:
            return None

class FinalGoal(Goal):
    class Meta:
        app_label = 'api'
        db_table = 'fly_final_goals'

    objects = FinalGoalManager()
    amount = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0.00,
    )
    for_want = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(6)],
        choices=constants.FOR_WANT_OPTIONS,
        default=1,
    )
    for_other_want = models.CharField(max_length=63, default='', null=True, blank=True)

class OrderedFinalGoal(FinalGoal):
    class Meta:
        ordering = ('-created',)
        proxy = True

class Badge(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_badges'

    id = models.AutoField(primary_key=True, db_index=True)
    created = models.DateTimeField(auto_now_add=True)
    type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(4)],
        choices=constants.BADGE_TYPE_OPTIONS,
        default=1,
    )
    icon = models.CharField(max_length=31, null=True, blank=True)
    colour = models.CharField(max_length=31, null=True, blank=True)
    level = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(9999)],
        default=1,
    )
    title = models.CharField(max_length=63, null=True, blank=True)
    description = models.CharField(max_length=511, null=True, blank=True)
    has_xp_requirement = models.BooleanField(default=True, blank=True,)
    required_xp = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(9999)],
    )

    def __str__(self):
        return str(self.id)

class XPLevelManager(models.Manager):
    def get_or_create_for_level_one(self):
        """
            Function will lookup
        """
        try:
            return XPLevel.objects.get(num=1)
        except XPLevel.DoesNotExist:
            return self.create(
                num=1,
                min_xp=0,
                max_xp=25,
            )

class XPLevel(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_xp_levels'

    objects = XPLevelManager()
    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=31, null=True, blank=True)
    num = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(9999)],
        choices=constants.DURATION_IN_MINUTES_OPTIONS,
        default=1,
    )
    min_xp = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(9999)],
        default=0,
    )
    max_xp = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(9999)],
        default=25,
    )

    def __str__(self):
        return str(self.id)

class CourseManager(models.Manager):
    def get_by_id_or_none(self, id):
        try:
            return Course.objects.get(id=id)
        except Course.DoesNotExist:
            return None

class Course(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_courses'

    objects = CourseManager()
    id = models.AutoField(primary_key=True, db_index=True)
    type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(3)],
        choices=constants.GOAL_TYPE_OPTIONS,
        default=1,
        db_index=True,
    )
    image = models.CharField(max_length=63, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True,db_index=True,)
    title = models.CharField(max_length=63, null=True, blank=True)
    summary = models.CharField(max_length=255, null=True, blank=True)
    description = models.CharField(max_length=511, null=True, blank=True)
    video_url = models.URLField(null=True, blank=True)
    duration = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(5), MaxValueValidator(60)],
        choices=constants.DURATION_IN_MINUTES_OPTIONS,
        default=5,
    )
    awarded_xp = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(9999)],
        default=1,
    )
    has_prerequisites = models.BooleanField(default=False,db_index=True,)
    prerequisites = models.ManyToManyField("self", blank=True,)

    def __str__(self):
        return str(self.id)

class OrderedCourse(Course):
    class Meta:
        ordering = ('created',)
        proxy = True

class Quiz(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_quizzes'

    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    course = models.ForeignKey(Course, db_index=True,)
    title = models.CharField(max_length=63, null=True, blank=True)
    description = models.CharField(max_length=511, null=True, blank=True)

    def __str__(self):
        return str(self.id)

class Question(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_questions'

    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    quiz = models.ForeignKey(Quiz, db_index=True,)
    num = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(9999)],
        default=1,
    )
    text = models.CharField(max_length=511, null=True, blank=True)
    type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(3)],
        choices=constants.QUESTION_TYPE_OPTIONS,
        default=1,
        db_index=True,
    )
    a = models.CharField(max_length=255, null=True, blank=True,)
    a_is_correct = models.BooleanField(default=False)
    b = models.CharField(max_length=255, null=True, blank=True,)
    b_is_correct = models.BooleanField(default=False)
    c = models.CharField(max_length=255, null=True, blank=True)
    c_is_correct = models.BooleanField(default=False)
    d = models.CharField(max_length=255, null=True, blank=True)
    d_is_correct = models.BooleanField(default=False)
    e = models.CharField(max_length=255, null=True, blank=True)
    e_is_correct = models.BooleanField(default=False)
    f = models.CharField(max_length=255, null=True, blank=True)
    f_is_correct = models.BooleanField(default=False)

    def __str__(self):
        return str(self.id)

class OrderedQuestion(Question):
    class Meta:
        ordering = ('num',)
        proxy = True

class EnrolledCourse(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_enrolled_courses'

    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, db_index=True,)
    course = models.ForeignKey(Course)
    finished = models.DateTimeField(null=True, blank=True,)
    is_finished = models.BooleanField(default=False)
    final_mark = models.FloatField(
        validators=[MinValueValidator(0), MaxValueValidator(100),],
        default=0,
    )

    def __str__(self):
        return str(self.id)

class QuizSubmission(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_quiz_submissions'

    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    course = models.ForeignKey(Course,)
    user = models.ForeignKey(User, db_index=True,)
    quiz = models.ForeignKey(Quiz, db_index=True,)
    finished = models.DateTimeField(null=True, blank=True,)
    is_finished = models.BooleanField(default=False)
    final_mark = models.FloatField(
        validators=[MinValueValidator(0), MaxValueValidator(100),],
        default=0,
    )

    def __str__(self):
        return str(self.id)

class QuestionSubmission(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_question_submissions'

    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, db_index=True,)
    question = models.ForeignKey(Question, db_index=True,)
    quiz = models.ForeignKey(Quiz)
    type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(3)],
        choices=constants.QUESTION_TYPE_OPTIONS,
        default=1,
        db_index=True,
    )
    a = models.BooleanField(default=False)
    b = models.BooleanField(default=False)
    c = models.BooleanField(default=False)
    d = models.BooleanField(default=False)
    e = models.BooleanField(default=False)
    f = models.BooleanField(default=False)
    mark = models.FloatField(
        validators=[MinValueValidator(0), MaxValueValidator(100),],
        default=0,
    )

    def __str__(self):
        return str(self.id)

class Me(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_mes'

    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, db_index=True,)
    avatar = models.ImageField(upload_to='upload', null=True, blank=True)
    xp = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(99999)],
        default=0,
    )
    xp_percent = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        default=0,
    )
    xplevel = models.ForeignKey(XPLevel)
    badges = models.ManyToManyField(Badge, blank=True, related_name='fly_user_badges',)
    courses = models.ManyToManyField(EnrolledCourse, blank=True, related_name='fly_user_enrolled_courses',)
    wants_newsletter = models.BooleanField(default=False)
    wants_goal_notify = models.BooleanField(default=False)
    wants_course_notify = models.BooleanField(default=False)
    wants_resource_notify = models.BooleanField(default=False)

    def __str__(self):
        return str(self.id)

class Notification(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_notifications'
    id = models.AutoField(primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(3)],
        choices=constants.NOTIFICATION_TYPE_OPTIONS,
        default=1,
        db_index=True,
    )
    title = models.CharField(max_length=511, null=True, blank=True)
    description = models.CharField(max_length=511, null=True, blank=True)
    user = models.ForeignKey(User, db_index=True,)
    xplevel = models.ForeignKey(XPLevel, null=True, blank=True,)
    badge = models.ForeignKey(Badge, null=True, blank=True,)

    def __str__(self):
        return str(self.id)

class Share(models.Model):
    class Meta:
        app_label = 'api'
        db_table = 'fly_shares'

    id = models.AutoField(primary_key=True, db_index=True)
    created = models.DateTimeField(auto_now_add=True)
    type = models.PositiveSmallIntegerField(
        validators=[MinValueValidator(1), MaxValueValidator(3)],
        choices=constants.SHARE_TYPE_OPTIONS,
        default=1,
    )
    user = models.ForeignKey(User, db_index=True,)
    xplevel = models.ForeignKey(XPLevel, null=True, blank=True,)
    badge = models.ForeignKey(Badge, null=True, blank=True,)
    custom_title = models.CharField(max_length=511, null=True, blank=True)
    custom_description = models.CharField(max_length=511, null=True, blank=True)
    custom_url = models.URLField(null=True, blank=True)
    notification_id = models.PositiveIntegerField(blank=True)

    def __str__(self):
        return str(self.id)


text:
CFX_CSSExtTextBuf::CFX_CSSExtTextBuf(WideStringView str) : m_Buffer(str) {}

CFX_CSSExtTextBuf::~CFX_CSSExtTextBuf() = default;